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

ListView通过Intent传递数据遇空指针与参数异常问题

解决ListView数据传递到Activity的空指针与查询异常问题

我来帮你一步步拆解并修复遇到的这些问题:


1. 先搞定 IllegalArgumentException: n <= 0: 0 错误

这个错误是因为从Firestore查询回来的placesList是空的(placeCount = 0),你直接调用randomGenerator.nextInt(placeCount)就触发了异常。我们需要先判断查询结果是否为空,再执行后续逻辑:

修改主Activity中onComplete里的代码:

if (task.isSuccessful()) {
    List<Places> placesList = new ArrayList<>();
    for (DocumentSnapshot document : task.getResult()) {
        Places place = document.toObject(Places.class);
        placesList.add(place);
    }

    // 新增:先判断查询结果是否为空
    if (placesList.isEmpty()) {
        Toast.makeText(ListViewPlaces.this, "没有找到符合条件的地点", Toast.LENGTH_SHORT).show();
        return;
    }

    int placeCount = placesList.size();
    Random randomGenerator = new Random();
    // 注意:不要重新定义局部变量randomPlaceList,直接用类的成员变量
    randomPlaceList.clear();
    for (int i = 1; i <= 3; i++) {
        randomPlaceList.add(placesList.get(randomGenerator.nextInt(placeCount)));
    }

    // 同样不要重新定义mListView,用成员变量即可
    mAdapter = new PlaceAdapter(randomPlaceList, ListViewPlaces.this);
    mListView.setAdapter(mAdapter);
}

2. 修复 NullPointerException: ArrayList.get(int) 错误

这个坑有两个原因:

  • 你在onComplete里重新定义了局部变量randomPlaceList,覆盖了类的成员变量,导致后续点击时拿不到数据
  • Firestore查询是异步的——你在onCreate里直接设置了点击事件,但此时mAdapter可能还没初始化(查询还没完成)

修复步骤:

  1. 删掉onComplete里的ArrayList<Places> randomPlaceList = new ArrayList<>();,直接使用类成员变量randomPlaceList
  2. 把点击事件移到onComplete内部(确保适配器已经初始化完成),同时增加空值判断:

修改后的点击事件代码:

// 把点击事件移到onComplete里,确保mAdapter已经初始化
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // 双重保险:先判断适配器和选中项是否不为空
        if (mAdapter == null) return;
        Places places = mAdapter.getItem(position);
        if (places == null) return;

        Intent intent = new Intent(ListViewPlaces.this, Card_activity.class);
        intent.putExtra("name", places.getName());
        startActivity(intent);
    }
});

另外,你的PlaceAdapter里有个小拼写错误:converView应该是convertView,建议修正避免后续混淆。


3. 修复第二个Activity的空指针问题

你的Card_activity里有两个明显错误:

  • getStringExtras是复数,返回的是Bundle对象,应该用getStringExtra("name")(单数)来获取单个字符串
  • 代码末尾少了分号,且没有判断name是否为null,会触发空指针

修改后的Card_activity代码:

public class Card_activity extends AppCompatActivity implements View.OnClickListener{
    TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.massive_places);
        mTextView = findViewById(R.id.head_name);

        // 修正:用getStringExtra,并增加空值判断
        String name = getIntent().getStringExtra("name");
        if (name != null) {
            mTextView.setText(name);
        } else {
            mTextView.setText("暂无名称");
        }
    }

    // 别忘了实现onClick方法,否则会编译报错
    @Override
    public void onClick(View v) {
        // 根据你的需求添加点击逻辑
    }
}

额外优化建议

  • 不要用getBaseContext()或getApplicationContext()初始化适配器,直接用当前Activity上下文(比如ListViewPlaces.this),避免上下文泄漏
  • 你的PlaceAdapter不需要自己保存dataSet,ArrayAdapter已经维护了数据源,直接用getItem(position)就能拿到数据,减少冗余
  • 给Firestore查询添加失败回调,方便排查问题:
query.get().addOnCompleteListener(...)
          .addOnFailureListener(new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                  Log.e("Firestore", "查询失败", e);
                  Toast.makeText(ListViewPlaces.this, "查询失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
              }
          });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:46:34