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

如何跨Activity访问MainActivity的ArrayList存储Recipe对象

跨Activity回传Recipe对象写入集合的正确实现

Android中两个Activity由系统独立管理生命周期,绝对不要直接在createRecipe页面持有MainActivity的引用访问内部集合,这种写法会触发内存泄漏、空指针崩溃等问题。正确逻辑是:createRecipe仅负责收集用户输入生成Recipe实例,通过页面结果回调把实例传回MainActivity,由MainActivity自行完成集合添加操作。

实现步骤

  • 第一步:让Recipe实体类支持序列化,满足Intent跨页面传递自定义对象的要求
import java.io.Serializable;

public class Recipe implements Serializable {
    // 按自身业务定义类属性,示例如下
    private String recipeName;
    private int duration;
    private String ingredients;
    private String description;
    private String steps;

    // 补全构造方法、getter/setter
    public Recipe(String recipeName, int duration, String ingredients, String description, String steps) {
        this.recipeName = recipeName;
        this.duration = duration;
        this.ingredients = ingredients;
        this.description = description;
        this.steps = steps;
    }

    // 自行补全get/set方法
}

如果追求更高的跨页传输性能,可以实现Parcelable接口,用Android Studio的Parcelable生成插件可以一键生成实现代码,后续传值逻辑和Serializable一致,仅取数据时把getSerializableExtra换成getParcelableExtra即可。

  • 第二步:在MainActivity中注册页面结果回调,替换原有的跳转逻辑
    首先在MainActivity的成员位置定义结果启动器,同时记得提前初始化recipeList:
// MainActivity成员变量
ArrayList<Recipe> recipeList;
// 注册创建菜谱页的结果回调
private final ActivityResultLauncher<Intent> createRecipeLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        result -> {
            if (result.getResultCode() == RESULT_OK && result.getData() != null) {
                // 取出回传的新菜谱对象
                Recipe newRecipe = (Recipe) result.getData().getSerializableExtra("new_recipe");
                // 直接写入当前页面的集合即可
                recipeList.add(newRecipe);
                // 如果页面绑定了列表适配器,记得通知刷新
                // recipeAdapter.notifyDataSetChanged();
            }
        }
);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // 必须先初始化集合,避免空指针
    recipeList = new ArrayList<>();

    // 原来跳转到createRecipe的代码替换成下面的写法
    findViewById(R.id.to_create_recipe_btn).setOnClickListener(v -> {
        Intent intent = new Intent(MainActivity.this, createRecipe.class);
        createRecipeLauncher.launch(intent);
    });
}
  • 第三步:修改createRecipe页的提交逻辑,完成对象创建后回传再关闭页面
    找到代码中标注// How should I save it的位置,替换成如下逻辑:
// 拿到创建好的Recipe实例(确保你的CreateRecipe方法有返回值,返回生成的Recipe对象)
Recipe newRecipe = CreateRecipe(etRecipeName, etDuration, etIngredient, etDesc, etSteps);
Toast.makeText(createRecipe.this, "Recipe Created", Toast.LENGTH_SHORT).show();
// 封装回传数据
Intent resultIntent = new Intent();
resultIntent.putExtra("new_recipe", newRecipe);
setResult(RESULT_OK, resultIntent);
// 关闭当前页回到MainActivity
finish();

禁止写法提醒

不要把recipeList改成public static公共静态变量让createRecipe直接操作:

  • 静态变量的生命周期和应用进程绑定,会持有Activity引用造成内存泄漏
  • 应用在后台内存不足时,静态变量会被系统回收,切回前台会直接触发空指针崩溃
  • 代码耦合度极高,后续维护非常容易出问题

内容的提问来源于stack exchange,提问作者Kelven Lim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 08:27:20