You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中调用setData()打印slope_db触发NullPointerException问题

问题分析

你遇到的NullPointerException核心原因是Volley网络请求的异步特性:

  • 在onCreate方法里,你先调用getData(lat, longi)发起网络请求,但这个请求不会阻塞主线程——代码会立刻跳去执行setData()。
  • 此时网络请求的onResponse回调还没触发,slope_db根本没被赋值,自然是null,执行Log.d("index",slope_db)就会抛出空指针异常。

另外,代码里还有个潜在的坑:判断jsonObj.get("slope")是否为null的写法不对,jsonObj.get("slope").equals(null)会在slope字段不存在时直接抛出异常,应该改用jsonObj.isNull("slope")来做判断。

解决方案

方案1:在网络请求回调中调用setData()

既然slope_db是在onResponse里才被赋值,那我们干脆等赋值完成后再调用setData(),确保它有值:

修改后的getData方法:

private void getData(String lat, String longi){
    String URL = "http://10.129.133.157/test.php?x="+longi+"&y="+lat;
    Log.d("URL",URL);
    StringRequest stringRequest = new StringRequest(com.android.volley.Request.Method.GET, URL, 
        new com.android.volley.Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    Log.d("JSON",response);
                    JSONObject jsonObj = new JSONObject(response);
                    // 修正空值判断逻辑
                    if(jsonObj.isNull("slope")){
                        slope_db = "1.0";
                    } else {
                        slope_db = jsonObj.getString("slope"); // 用getString更安全,避免类型转换异常
                    }
                    Log.d("slope",slope_db);
                    // 赋值完成后再调用setData
                    setData();
                } catch (Exception e) {
                    e.printStackTrace();
                    // 异常情况下也给slope_db设默认值,避免后续空指针
                    slope_db = "1.0";
                    setData();
                }
            }
        }, 
        new com.android.volley.Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d("TAG error","error occured"+error.toString());
                // 请求失败时同样设默认值并调用setData
                slope_db = "1.0";
                setData();
            }
        } 
    );
    stringRequest.setRetryPolicy(new DefaultRetryPolicy(100000000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(stringRequest);
}

然后在onCreate里去掉直接调用setData()的代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    lat = getIntent().getExtras().get("Latitude").toString();
    longi = getIntent().getExtras().get("Longitude").toString();
    getData(lat, longi);
    // 移除这里的setData()调用
}

方案2:用回调接口(更灵活的扩展方式)

如果后续需要在多个地方处理数据加载完成的逻辑,可以定义一个回调接口,解耦数据请求和UI逻辑:

// 定义回调接口
interface DataLoadListener {
    void onDataLoaded(String slope);
}

// 修改getData方法,接收回调参数
private void getData(String lat, String longi, DataLoadListener listener){
    String URL = "http://10.129.133.157/test.php?x="+longi+"&y="+lat;
    Log.d("URL",URL);
    StringRequest stringRequest = new StringRequest(com.android.volley.Request.Method.GET, URL, 
        new com.android.volley.Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    Log.d("JSON",response);
                    JSONObject jsonObj = new JSONObject(response);
                    String slope;
                    if(jsonObj.isNull("slope")){
                        slope = "1.0";
                    } else {
                        slope = jsonObj.getString("slope");
                    }
                    Log.d("slope",slope);
                    listener.onDataLoaded(slope);
                } catch (Exception e) {
                    e.printStackTrace();
                    listener.onDataLoaded("1.0");
                }
            }
        }, 
        new com.android.volley.Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d("TAG error","error occured"+error.toString());
                listener.onDataLoaded("1.0");
            }
        } 
    );
    stringRequest.setRetryPolicy(new DefaultRetryPolicy(100000000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(stringRequest);
}

然后在onCreate里调用:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    lat = getIntent().getExtras().get("Latitude").toString();
    longi = getIntent().getExtras().get("Longitude").toString();
    getData(lat, longi, new DataLoadListener() {
        @Override
        public void onDataLoaded(String slope) {
            slope_db = slope;
            setData();
        }
    });
}
额外优化建议
  • 不要直接写getIntent().getExtras().get("Latitude").toString(),如果get("Latitude")返回null会直接触发空指针,建议先做判断:
    Bundle extras = getIntent().getExtras();
    if(extras != null){
        lat = extras.getString("Latitude");
        longi = extras.getString("Longitude");
    }
    
  • 构建网络URL时,用Uri.Builder更安全,避免拼接字符串出错:
    String url = new Uri.Builder()
            .scheme("http")
            .authority("10.129.133.157")
            .path("test.php")
            .appendQueryParameter("x", longi)
            .appendQueryParameter("y", lat)
            .build()
            .toString();
    

内容的提问来源于stack exchange,提问作者sudhanshud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:46:57