Android跨Activity传递Parcelable对象报空指针异常如何解决
问题定位
你的空指针异常和「MainActivity跳转homePage未携带Bundle」没有关系,是代码存在3个核心错误:
- 传参、取参逻辑不匹配:
createPage中存入Bundle的是ParcelableArrayList类型,key为recipe,但homePage中却调用getParcelable("recipe")获取单个Recipe对象,类型不匹配导致取值为null - 页面栈逻辑错误:你在
createPage中通过startActivity启动新的homePage实例,会在返回栈顶层叠加新页面,原本从MainActivity进入的homePage实例、MainActivity实例根本不会收到你传的参数 - 变量作用域错误:
recipeList是定义在MainActivity中的成员变量,你在homePage中直接调用recipeList.add(r),homePage本身没有这个变量的实例,调用时必然触发空指针
另外你的Recipe类的Parcelable实现逻辑是正确的,不需要修改。
修复方案
你的需求是链式页面的数据回传,不要通过重新startActivity打乱返回栈,使用Android原生的页面结果回调机制实现即可:
1. 调整MainActivity跳转逻辑
使用带结果回调的方式启动homePage,接收最终回传的Recipe对象添加到自身列表:
public class MainActivity extends AppCompatActivity { private static final int REQ_CODE_HOME = 1000; private List<Recipe> recipeList = new ArrayList<>(); // 假设这是你的列表适配器 // private RecipeAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 跳转homePage的触发逻辑,比如按钮点击 findViewById(R.id.btn_enter_home).setOnClickListener(v -> { Intent intent = new Intent(MainActivity.this, homePage.class); startActivityForResult(intent, REQ_CODE_HOME); }); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQ_CODE_HOME && resultCode == RESULT_OK && data != null) { Recipe newRecipe = data.getParcelableExtra("new_recipe"); if (newRecipe != null) { recipeList.add(newRecipe); // 新数据添加后刷新列表 // adapter.notifyDataSetChanged(); } } } }
2. 调整homePage逻辑
同样用带结果回调的方式启动createPage,接收到createPage回传的Recipe后,继续回传给上一级的MainActivity:
public class homePage extends AppCompatActivity { private static final int REQ_CODE_CREATE = 1001; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); // 跳转createPage的触发逻辑 findViewById(R.id.btn_create).setOnClickListener(v -> { Intent intent = new Intent(homePage.this, createPage.class); startActivityForResult(intent, REQ_CODE_CREATE); }); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQ_CODE_CREATE && resultCode == RESULT_OK && data != null) { Recipe newRecipe = data.getParcelableExtra("new_recipe"); if (newRecipe != null) { // 将收到的新Recipe回传给MainActivity Intent returnIntent = new Intent(); returnIntent.putExtra("new_recipe", newRecipe); setResult(RESULT_OK, returnIntent); // 如果不需要留在homePage可以直接调用finish()返回MainActivity finish(); } } } }
3. 调整createPage逻辑
创建完Recipe对象后,不要启动新的homePage,直接将数据塞入返回Intent,关闭当前页面回到上一级的homePage即可:
public class createPage extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_create); // 提交新Recipe的触发逻辑 findViewById(R.id.btn_submit).setOnClickListener(v -> { // 收集页面输入参数构造Recipe对象 Recipe r = new Recipe(/* 传入你收集的参数 */); Intent returnIntent = new Intent(); returnIntent.putExtra("new_recipe", r); setResult(RESULT_OK, returnIntent); // 关闭当前创建页,自动返回homePage finish(); }); } }
如果你使用的是AndroidX新版API,可以将
startActivityForResult替换为Activity Result API,核心回传逻辑不变。
内容的提问来源于stack exchange,提问作者Kelven Lim
相关产品推荐
相关产品推荐

