如何通过.putExtra()或其他方式传递Firebase DatabaseReference至另一个Activity?
如何在Android Activity之间传递Firebase DatabaseReference?
直接传递DatabaseReference实例是行不通的——因为这个类既没有实现Parcelable也没有实现Serializable接口,不符合Android组件间传递对象的要求。不过有两种简单可靠的方法可以实现你的需求,下面详细说明:
方法一:传递构建引用的参数/完整路径(推荐)
这是最符合Android设计规范的方案,核心思路是传递构建引用所需的原始数据,在第二个Activity中重新构建DatabaseReference。
实现步骤:
在第一个Activity(MoreQP)中传递参数
你可以选择传递构建路径的所有独立参数,或者直接传递mDatabase的完整路径字符串:选项A:传递独立参数(更灵活,方便后续修改路径结构)
// 在resultCard的点击事件里 Intent showresulPage = new Intent(MoreQP.this, ShowQuestion.class); // 把构建引用需要的所有参数都传入Intent showresulPage.putExtra("SELECTED_SUBJECT", selectedSubject); showresulPage.putExtra("SY", sy); showresulPage.putExtra("SS", ss); showresulPage.putExtra("SE", se); showresulPage.putExtra("WHICH_SEMESTER", whichSemester); // 设置flags和启动Activity showresulPage.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); MoreQP.this.startActivity(showresulPage); finish();选项B:传递完整路径字符串(更简洁)
// 在showResult()方法中构建完mDatabase后,获取完整路径 String dbReferencePath = mDatabase.toString(); // 在Intent中传入路径 Intent showresulPage = new Intent(MoreQP.this, ShowQuestion.class); showresulPage.putExtra("DB_REFERENCE_PATH", dbReferencePath); // 设置flags和启动Activity showresulPage.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); MoreQP.this.startActivity(showresulPage); finish();在第二个Activity(ShowQuestion)中接收并构建引用
对应上面的两个选项:选项A的接收代码:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_question); // 获取Intent中的参数 String selectedSubject = getIntent().getStringExtra("SELECTED_SUBJECT"); String sy = getIntent().getStringExtra("SY"); String ss = getIntent().getStringExtra("SS"); String se = getIntent().getStringExtra("SE"); String whichSemester = getIntent().getStringExtra("WHICH_SEMESTER"); // 重新构建DatabaseReference DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference() .child("Department").child("CSE").child("Year").child(sy) .child(ss).child(se).child(whichSemester).child(selectedSubject); }选项B的接收代码:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_question); // 获取完整路径 String dbPath = getIntent().getStringExtra("DB_REFERENCE_PATH"); // 直接通过路径构建引用 DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReferenceFromUrl(dbPath); }
方法二:使用单例类持有引用
如果你不想传递多个参数,可以创建一个单例类来全局持有DatabaseReference实例,不过要注意内存泄漏的风险(比如Activity销毁后单例仍持有引用)。
实现步骤:
创建单例辅助类
public class FirebaseReferenceHolder { private static FirebaseReferenceHolder instance; private DatabaseReference currentReference; // 私有构造方法,防止实例化 private FirebaseReferenceHolder() {} // 获取单例实例 public static synchronized FirebaseReferenceHolder getInstance() { if (instance == null) { instance = new FirebaseReferenceHolder(); } return instance; } // 设置当前引用 public void setCurrentReference(DatabaseReference reference) { this.currentReference = reference; } // 获取当前引用 public DatabaseReference getCurrentReference() { return currentReference; } }在第一个Activity中设置引用
public void showResult(){ resultDisplay.setText(selectedSubject+"\n"+sy+" "+ss+" "+se); resultCard.setVisibility(resultCard.VISIBLE); // 构建引用 mDatabase = FirebaseDatabase.getInstance().getReference().child("Department").child("CSE").child("Year").child(sy).child(ss).child(se).child(whichSemester).child(selectedSubject); // 存入单例 FirebaseReferenceHolder.getInstance().setCurrentReference(mDatabase); }在第二个Activity中获取引用
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_question); // 从单例中获取引用 DatabaseReference mDatabase = FirebaseReferenceHolder.getInstance().getCurrentReference(); }
注意事项
- 你原来代码中的
showresulPage.putExtra(mDatabase);是错误的,putExtra需要键值对形式,而且DatabaseReference不能直接传递,一定要替换成上面的方法。 - 优先选择方法一,因为它更符合Android组件的生命周期设计,避免单例带来的内存泄漏风险。
内容的提问来源于stack exchange,提问作者Anirban
相关产品推荐
相关产品推荐

