安卓程序运行含RecyclerView的页面时模拟器发生崩溃
RecyclerView启动即崩溃修复
问题相关材料
- RecyclerView页面布局截图:

- RecyclerView列表项布局截图:

- Logcat报错信息截图:

原始ViewHolder实现代码
public class myPageViewHolder extends RecyclerView.ViewHolder { TextView rName, rDesc, rDuration, rIngredients, rSteps; public myPageViewHolder(View itemView) { super(itemView); rName = itemView.findViewById(R.id.rName); rDesc = itemView.findViewById(R.id.rDesc); rDuration = itemView.findViewById(R.id.rDuration); rIngredients = itemView.findViewById(R.id.rIngredients); rSteps = itemView.findViewById(R.id.rSteps); } }
原始Adapter实现代码
public class myPageAdapter extends RecyclerView.Adapter<myPageViewHolder> { ArrayList<Recipe> data; public myPageAdapter(ArrayList<Recipe> input) { data = input; } public myPageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View item = LayoutInflater.from(parent.getContext()).inflate(R.layout.mypagelayout, parent, false); return new myPageViewHolder(item); } public void onBindViewHolder(myPageViewHolder holder, int position) { Recipe r = data.get(position); holder.rName.setText(r.getName()); holder.rDesc.setText(r.getDescription()); holder.rDuration.setText(r.getDuration() + "mins"); holder.rIngredients.setText(r.getIngredients()[('\n')]); holder.rSteps.setText(r.getSteps()[('\n')]); } public int getItemCount() { return data.size(); } } // 粘贴错位的冗余代码 RecyclerView recyclerView = findViewById(R.id.recyclerView); myPageAdapter adapter = new myPageAdapter(recipeList); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setAdapter(adapter);
原始MainActivity实现代码
public class MainActivity extends AppCompatActivity { // 错误位置初始化列表数据 ArrayList<Recipe> recipeList = (ArrayList<Recipe>) getIntent().getSerializableExtra("rList"); Intent intent = getIntent(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView create = findViewById(R.id.createImage); create.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent gotoCreate = new Intent(MainActivity.this, createRecipe.class); startActivity(gotoCreate); } }); RecyclerView recyclerView = findViewById(R.id.recyclerView); myPageAdapter adapter = new myPageAdapter(recipeList); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setAdapter(adapter); } }
问题点逐一修复
- 删除错位冗余代码
Adapter类闭合大括号后的RecyclerView初始化代码是粘贴错误,直接删除即可,这段逻辑已经在MainActivity中实现,残留会直接触发编译错误。 - 修正Intent取值时机
禁止在Activity成员变量声明位置直接调用getIntent(),此时Activity未完成生命周期初始化,调用返回值为空,直接强转序列化列表会触发空指针崩溃。需要把取值逻辑移到onCreate方法内,同时加空值兜底,覆盖启动时未传参的边缘场景。 - 修正数组取值逻辑错误
onBindViewHolder中r.getIngredients()[('\n')]写法存在逻辑错误:'\n'是ASCII码为10的字符,作为数组索引会强制取数组第11个元素,只要数组长度不足就会触发数组越界崩溃。如果需要把数组元素用换行拼接为字符串,使用TextUtils.join("\n", 数组对象)实现即可。 - 确认列表项布局引用正确
检查onCreateViewHolder中inflate的R.layout.mypagelayout是否为单个列表项的布局文件,不要把放置RecyclerView的整个页面布局传进去,否则会因找不到对应ID的TextView触发空指针。
修正后可直接运行的代码
MainActivity部分
public class MainActivity extends AppCompatActivity { private ArrayList<Recipe> recipeList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 生命周期初始化完成后再取Intent参数 Intent intent = getIntent(); if (intent != null) { recipeList = (ArrayList<Recipe>) intent.getSerializableExtra("rList"); } // 空值兜底避免空指针 if (recipeList == null) { recipeList = new ArrayList<>(); } ImageView create = findViewById(R.id.createImage); create.setOnClickListener(view -> { Intent gotoCreate = new Intent(MainActivity.this, createRecipe.class); startActivity(gotoCreate); }); RecyclerView recyclerView = findViewById(R.id.recyclerView); myPageAdapter adapter = new myPageAdapter(recipeList); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setAdapter(adapter); } }
Adapter onBindViewHolder修正部分
@Override public void onBindViewHolder(myPageViewHolder holder, int position) { Recipe r = data.get(position); holder.rName.setText(r.getName()); holder.rDesc.setText(r.getDescription()); holder.rDuration.setText(r.getDuration() + "mins"); holder.rIngredients.setText(TextUtils.join("\n", r.getIngredients())); holder.rSteps.setText(TextUtils.join("\n", r.getSteps())); }
内容的提问来源于stack exchange,提问作者Kelven Lim
相关产品推荐
相关产品推荐

