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

Volley取数后用Bundle传值到Fragment触发空指针异常,如何解决?

解决Fragment间Bundle传值的空指针问题

嘿,我看你遇到了Attempt to invoke virtual method 'java.lang.String android.os.BaseBundle.getString(...)' on a null object reference这个错误,本质就是你在ChooseTab这个Fragment里调用getArguments()时拿到了null,导致调用getString()触发了空指针。我来帮你拆解问题并给出修复方案:

为什么会出现这个错误?

主要有两个核心原因:

  • 你可能在某些场景下创建ChooseTab实例时,没有给它设置Arguments(比如直接new ChooseTab()但忘了调用setArguments());
  • 最关键的是,Volley的网络请求是异步的,你可能在count还没从接口拿到值的时候,就急着执行Fragment跳转传值的逻辑了,甚至可能因为时机不对导致Bundle根本没传递成功。

具体的修复步骤

1. 修正异步请求的传值时机

你的getCount()方法是异步请求,count的值要等接口返回后才会被赋值。现在你是在点击事件里直接跳转传值,这时候count可能还没拿到,甚至会因为请求延迟导致Bundle传递逻辑出问题。我们把跳转逻辑移到Volley的onResponse回调里,确保拿到count后再传值:

修改getCount()方法,把跳转逻辑放在请求成功后:

private void getCount() {
 String url="http://192.168.1.106:9500/api/restqueue/";
 String json_req = "json_req";
 JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
 @Override
 public void onResponse(JSONObject response) {
 try {
 JSONObject object=new JSONObject(response.toString());
 count=object.getString("name");
 // 接口请求成功,拿到count后再跳转传值
 navigateToChooseTab();
 } catch (JSONException e) {
 e.printStackTrace();
 }
 }
 }, new Response.ErrorListener() {
 @Override
 public void onErrorResponse(VolleyError error) {
 // 这里可以加个错误提示,比如Toast告诉用户请求失败了
 Toast.makeText(getActivity(), "请求失败,请重试", Toast.LENGTH_SHORT).show();
 }
 }) {
 @Override
 public Map<String, String> getHeaders() throws AuthFailureError {
 Map<String, String> headers = new HashMap<>();
 String credentials = name+":"+pass;
 String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
 headers.put("Content-type", "application/json");
 headers.put("Authorization", auth);
 return headers;
 }
 };
 AppController.getInstance().addToRequestQueue(req, json_req);
}

// 单独封装跳转逻辑,代码更清晰
private void navigateToChooseTab() {
 fm = getFragmentManager();
 String tag = "";
 tx = fm.beginTransaction();
 Bundle bundle = new Bundle();
 bundle.putString("totcount", count);
 ChooseTab choose = new ChooseTab();
 choose.setArguments(bundle);
 tx.replace(R.id.frame, choose, tag);
 tx.addToBackStack(tag);
 tx.commit();
}

然后修改点击事件,只触发网络请求:

name.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 // 点击后先发起网络请求,等拿到数据再跳转
 getCount();
 }
});

2. 在ChooseTab里加个空值判断

为了防止极端情况(比如请求失败后跳转,或者其他地方创建ChooseTab没传Bundle),在获取Bundle时先判断是否为null:

Bundle bundle = this.getArguments();
if (bundle != null) {
 count = bundle.getString("totcount", "empty");
} else {
 // 处理没有传值的情况,比如给个默认值或者提示用户
 count = "empty";
 Toast.makeText(getActivity(), "未获取到数据", Toast.LENGTH_SHORT).show();
}

3. 检查所有创建ChooseTab的地方

确保你所有创建ChooseTab实例的代码,都调用了setArguments()传递Bundle,不要有直接new ChooseTab()就添加到事务的情况,否则肯定会出现空指针。

额外小建议

  • 不要在Fragment的onCreateView()以外的生命周期方法里随便用getArguments(),除非你确定它已经被正确设置;
  • 系统会自动保存和恢复Fragment的arguments,所以只要你是通过setArguments()设置的,Fragment重建后也能拿到值,不用额外处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:50:40