Android应用:ActivityA获取Firebase数据后传递至其他Activity的问题
Hey there! Let's work through this problem step by step. You want to fetch all Firebase data once in your launch Activity (ActivityA) and share it with the other three Activities, but ran into issues using GreenRobot EventBus. Here's how to get this working smoothly, plus some alternative approaches if EventBus still doesn't click:
First, make sure you've got the correct dependency added to your app-level build.gradle (for GreenRobot's EventBus, not the AndroidX variant):
implementation 'org.greenrobot:eventbus:3.3.1'
Next, create a simple data class to hold all your Firebase data—this is the "event" you'll pass around. It should contain separate datasets for each Activity:
// Kotlin example data class FirebaseWeekDataEvent( val activityAData: List<WeekData>, val activityBData: List<WeekData>, val activityCData: List<WeekData>, val activityDData: List<WeekData> ) // Java example public class FirebaseWeekDataEvent { private List<WeekData> activityAData; private List<WeekData> activityBData; private List<WeekData> activityCData; private List<WeekData> activityDData; public FirebaseWeekDataEvent(List<WeekData> aData, List<WeekData> bData, List<WeekData> cData, List<WeekData> dData) { this.activityAData = aData; this.activityBData = bData; this.activityCData = cData; this.activityDData = dData; } // Add getters for each dataset public List<WeekData> getActivityBData() { return activityBData; } }
Once you've retrieved all your Firebase data in ActivityA, package it into your event class and send it via EventBus. Do this only after all data is fully loaded (don't post partial data!):
// In ActivityA's Firebase success callback FirebaseFirestore.getInstance() .collection("weekly_data") .get() .addOnSuccessListener { snapshot -> // Parse data into separate lists for each Activity val aData = snapshot.toObjects(WeekData::class.java).filter { it.targetActivity == "A" } val bData = snapshot.toObjects(WeekData::class.java).filter { it.targetActivity == "B" } val cData = snapshot.toObjects(WeekData::class.java).filter { it.targetActivity == "C" } val dData = snapshot.toObjects(WeekData::class.java).filter { it.targetActivity == "D" } // Post the event to all subscribed components EventBus.getDefault().post(FirebaseWeekDataEvent(aData, bData, cData, dData)) }
For other Activities (like ActivityB) to receive the data, you need to register/unregister with EventBus at the right lifecycle points, and define a subscription method:
class ActivityB : AppCompatActivity() { private var weekData: List<WeekData>? = null override fun onStart() { super.onStart() // Register with EventBus when the Activity becomes visible EventBus.getDefault().register(this) } override fun onStop() { super.onStop() // Unregister when the Activity goes to background to avoid memory leaks EventBus.getDefault().unregister(this) } // Subscription method—must use @Subscribe annotation @Subscribe(threadMode = ThreadMode.MAIN) fun onWeekDataReceived(event: FirebaseWeekDataEvent) { // Grab the data specific to ActivityB weekData = event.activityBData // Pass this data to your Fragments (e.g., update your ViewPager adapter) (viewPager.adapter as WeekFragmentPagerAdapter).updateWeekData(weekData) } }
If you're still not receiving events, check these common pitfalls:
- Missing
@Subscribeannotation: Your subscription method must have this, and it should be public (Java) or have default visibility (Kotlin). - Incorrect lifecycle registration: Use
onStart()/onStop()instead ofonCreate()/onDestroy()—if your Activity is in the background when the event posts, it won't receive it otherwise. - Need to receive events after they're posted? Use a sticky event. In ActivityA, post with
EventBus.getDefault().postSticky(yourEvent), and in the target Activity, addsticky = trueto your annotation:@Subscribe(threadMode = ThreadMode.MAIN, sticky = true) fun onWeekDataReceived(event: FirebaseWeekDataEvent) { // Handle data // Optional: Remove the sticky event if you don't need it anymore EventBus.getDefault().removeStickyEvent(event) }
If EventBus feels overly complex for your use case, a simple singleton cache works great for one-time data fetching:
object FirebaseDataCache { private var allWeekData: FirebaseWeekDataEvent? = null fun setAllData(data: FirebaseWeekDataEvent) { allWeekData = data } fun getActivityBData(): List<WeekData>? { return allWeekData?.activityBData } } // In ActivityA's Firebase callback val event = FirebaseWeekDataEvent(aData, bData, cData, dData) FirebaseDataCache.setAllData(event) // In ActivityB's onCreate() or onStart() FirebaseDataCache.getActivityBData()?.let { data -> // Pass to Fragments }
This approach avoids lifecycle headaches and is super straightforward for static, one-time loaded data.
Just remember to handle cases where data might not be loaded yet (e.g., show a loading spinner in other Activities until the cache is populated).
内容的提问来源于stack exchange,提问作者Samual

