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
相关产品推荐
相关产品推荐

