Android Studio中RecyclerView引发App启动崩溃问题求助
Android RecyclerView 初始化崩溃问题修复
崩溃根源
从日志可明确,崩溃是空指针异常:在displayData方法调用itemName.add()时,itemName未初始化,属于null对象。此外还存在ViewHolder视图绑定错误、RecyclerView初始化顺序问题。
崩溃日志
java.lang.RuntimeException: 无法启动活动 ComponentInfo{com.example.test/com.example.test.activities.MainActivity}: java.lang.NullPointerException: 尝试在null对象引用上调用虚拟方法 'boolean java.util.ArrayList.add(java.lang.Object)' at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: java.lang.NullPointerException: 尝试在null对象引用上调用虚拟方法 'boolean java.util.ArrayList.add(java.lang.Object)' at com.example.test.activities.MainActivity.displayData(MainActivity.java:73) at com.example.test.activities.MainActivity.onCreate(MainActivity.java:42) at android.app.Activity.performCreate(Activity.java:8000) at android.app.Activity.performCreate(Activity.java:7984) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
界面截图(注释崩溃代码后加载的UI)

代码修复方案
1. MainActivity.java 修复
问题点:
- 未初始化
itemName、itemQnt集合 - RecyclerView初始化顺序错误(先设Adapter再加载数据)
- 未关闭Cursor导致资源泄漏
- 从增删页面返回后未刷新数据
修复后代码:
public class MainActivity extends AppCompatActivity { ItemDatabase db; ArrayList<String> itemName, itemQnt; ItemViewAdapter itemViewAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化集合,解决空指针 itemName = new ArrayList<>(); itemQnt = new ArrayList<>(); // 初始化数据库 db = new ItemDatabase(this); // 绑定按钮 Button addItem = findViewById(R.id.addItemBtn); Button deleteItem = findViewById(R.id.deleteItemBtn); // 初始化RecyclerView RecyclerView recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); // 先加载数据再初始化Adapter displayData(); itemViewAdapter = new ItemViewAdapter(this, itemName, itemQnt); recyclerView.setAdapter(itemViewAdapter); // 跳转添加页面 addItem.setOnClickListener(v -> { startActivity(new Intent(getApplicationContext(), AddItemActivity.class)); }); // 跳转删除页面 deleteItem.setOnClickListener(v -> { startActivity(new Intent(getApplicationContext(), DeleteItemActivity.class)); }); } private void displayData() { // 清空旧数据,避免重复加载 itemName.clear(); itemQnt.clear(); Cursor cursor = db.getData(); if (cursor.getCount() == 0) { Toast.makeText(MainActivity.this, "暂无数据", Toast.LENGTH_SHORT).show(); cursor.close(); return; } while (cursor.moveToNext()) { itemName.add(cursor.getString(0)); itemQnt.add(cursor.getString(1)); } cursor.close(); // 关闭Cursor释放资源 } // 从增删页面返回时刷新数据 @Override protected void onResume() { super.onResume(); displayData(); if (itemViewAdapter != null) { itemViewAdapter.notifyDataSetChanged(); } } }
2. ItemViewHolder.java 修复
问题点:用nameView.findViewById()而非itemView.findViewById(),导致视图绑定失败
修复后代码:
public class ItemViewHolder extends RecyclerView.ViewHolder{ TextView nameView; TextView qntView; public ItemViewHolder(@NonNull View itemView) { super(itemView); // 通过itemView查找子控件 nameView = itemView.findViewById(R.id.nameInput); qntView = itemView.findViewById(R.id.qntInput); } }
3. ItemViewAdapter.java 优化
问题点:未处理集合为null的情况,可能导致getItemCount()崩溃
修复后代码:
public class ItemViewAdapter extends RecyclerView.Adapter<ItemViewHolder> { Context context; ArrayList<String> name, quantity; public ItemViewAdapter(Context context, ArrayList<String> name, ArrayList<String> quantity) { this.context = context; // 空集合兜底处理 this.name = name != null ? name : new ArrayList<>(); this.quantity = quantity != null ? quantity : new ArrayList<>(); } @NonNull @Override public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = LayoutInflater.from(context).inflate(R.layout.activity_item_inventory, parent, false); return new ItemViewHolder(v); } @Override public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { holder.nameView.setText(name.get(position)); holder.qntView.setText(quantity.get(position)); } @Override public int getItemCount() { return name.size(); } }
4. 布局文件说明
activity_main.xml和activity_item_inventory.xml布局逻辑正常,RecyclerView位置(标题下方、按钮上方)符合需求,无需修改。
内容的提问来源于stack exchange,提问作者Austin Palmer
相关产品推荐
相关产品推荐

