点击按钮后App崩溃(FATAL EXCEPTION: main)原因及修复咨询
根据你描述的场景——之前按钮功能正常,添加向ArrayList写入信息的代码后点击按钮App崩溃,且是通过startActivityForResult启动目标Activity、在onActivityResult中获取信息再存入ArrayList——下面是最可能的崩溃原因和对应的修复方法:
1. ArrayList未初始化(最常见的空指针异常)
这是主线程崩溃(FATAL EXCEPTION: main)最常见的原因:你只声明了ArrayList变量,但没有实例化它,当调用mDataList.add(...)时就会触发NullPointerException。
修复方法:
在使用ArrayList之前完成初始化,比如在宿主Activity的onCreate()方法中初始化:
private ArrayList<String> mDataList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_activity_layout); // 初始化ArrayList,避免空指针 mDataList = new ArrayList<>(); }
2. onActivityResult中获取的返回数据为空
如果目标Activity没有正确设置返回结果,或者你在onActivityResult中直接操作空数据,都会导致空指针崩溃。比如:
- 目标Activity没调用
setResult(RESULT_OK, intent)就finish; - 在
onActivityResult中直接调用data.getStringExtra("key"),但data本身是null。
修复方法:
第一步,确保目标Activity正确返回数据:
// 目标Activity的按钮点击回调中 Button submitBtn = findViewById(R.id.btn_submit); submitBtn.setOnClickListener(v -> { String inputContent = "要返回的内容"; Intent resultIntent = new Intent(); resultIntent.putExtra("DATA_KEY", inputContent); // 必须设置RESULT_OK和携带数据的Intent setResult(RESULT_OK, resultIntent); finish(); });
第二步,在宿主Activity的onActivityResult中增加多层非空判断:
// 定义常量请求码,避免硬编码出错 private static final int REQUEST_ADD_DATA = 1001; @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); // 先匹配请求码、结果码,再判断数据不为空 if (requestCode == REQUEST_ADD_DATA && resultCode == RESULT_OK && data != null) { String receivedData = data.getStringExtra("DATA_KEY"); // 再判断拿到的数据有效,再存入ArrayList if (receivedData != null && !receivedData.isEmpty()) { mDataList.add(receivedData); // 后续启用ListView时,可调用adapter.notifyDataSetChanged()更新列表 } } }
3. 生命周期导致的ArrayList对象失效
如果宿主Activity因为系统内存不足被后台销毁重建,之前初始化的ArrayList会丢失,此时onActivityResult回调时,ArrayList可能处于未初始化状态,调用add()就会崩溃。
修复方法:
通过onSaveInstanceState和onRestoreInstanceState保存、恢复ArrayList数据:
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 保存ArrayList数据到Bundle outState.putStringArrayList("SAVED_DATA_LIST", mDataList); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // 恢复数据,若恢复后为空则重新初始化 mDataList = savedInstanceState.getStringArrayList("SAVED_DATA_LIST"); if (mDataList == null) { mDataList = new ArrayList<>(); } }
4. 请求码不匹配导致的逻辑错误
如果启动Activity时用的请求码和onActivityResult中判断的请求码不一致,可能会误执行代码逻辑,间接导致崩溃(比如操作了错误的数据源)。
修复方法:
定义常量请求码,确保启动和回调时使用同一个值:
// 常量请求码,统一管理 private static final int REQUEST_ADD_DATA = 1001; // 启动目标Activity时 Intent intent = new Intent(this, TargetActivity.class); startActivityForResult(intent, REQUEST_ADD_DATA); // onActivityResult中匹配该常量 if (requestCode == REQUEST_ADD_DATA) { // 处理逻辑 }
内容的提问来源于stack exchange,提问作者Kazj

