根据活动生命周期,在创建应用程序时调用onCreate((一次,然后调用onStart((方法,该方法可能在整个活动生命周期中调用多次。然而,这并不是发生在我身上的事情。
我的onCreate方法中有以下代码:
mRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
Gig thisGig = dataSnapshot.getValue(Gig.class);
loadedGigs.add(thisGig);
Log.w("onCreate", "There are " + loadedGigs.size() + "Gigs loaded in the array.");
arrayAdapter.notifyDataSetChanged();
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
然后我有了我的onStart方法:
@Override
protected void onStart()
{
super.onStart();
Log.w("onStart", "There are " + loadedGigs.size() + "Gigs loaded in the array.");
}
下面是日志:
V/FA: onActivityCreated
W/onStart: There are 0Gigs loaded in the array.
V/FA: Activity resumed, time: 2460468116
D/FA: Logging event (FE): screen_view(_vs), Bundle[{ga_event_origin(_o)=auto, ga_previous_class(_pc)=search_gigs_activity, ga_previous_id(_pi)=-5229767692724064313, ga_screen_class(_sc)=search_gigs_results_activity, ga_screen_id(_si)=-5229767692724064312}]
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
W/onCreate: There are 1Gigs loaded in the array.
W/onCreate: There are 2Gigs loaded in the array.
W/onCreate: There are 3Gigs loaded in the array.
V/FA: Inactivity, disconnecting from the service
我还有其他代码,但我删除了所有代码,因为我一直得到一个空指针异常,不知道为什么。事实证明,我试图从onStart方法内部访问"loadedGigs"数组列表,以为它已经从onCreate方法填充了。
你知道为什么会这样吗?我的最佳猜测是,这与我使用Firebase和子事件侦听器有关。我缺乏相当多的知识,我想这就是我搞不清楚的原因。
Thx,Vlad
事实核查
事实是,首先调用onCreate()
,然后调用onStart()
。但是,因为您正在进行firebase调用以获取数据集,所以onStart()
不会等待完成,这意味着onStart
中的列表仍然没有填充。记住,当调用onCreate
时,无论在那里执行什么代码,都不会暂停调用onStart
。同样,onStart
在执行自己的代码之前,并不是等待onCreate
中的所有代码都完成。
您的问题
在从onCreate
中的firebase事件监听器获得数据集后,似乎您想在onStart
中做些什么。I
建议可能吗
您可以使用LiveData
让onStart
内的代码知道firebase事件侦听器已经完成,并准备好了在onStart
中需要使用的数据。
您询问的LIVEDATA是什么
LiveData是一个可观察的数据持有者类。不像普通人可观察,LiveData具有生命周期意识,这意味着它尊重其他应用程序组件的生命周期,如活动、片段或服务。这种意识确保LiveData只更新应用程序组件处于活动生命周期状态的观察者。
点击此处查看更多
会是什么样子:
//just add dependency into the app/build.gradle .
def lifecycle_version = "1.1.1"
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
// Create an instance of LiveData to hold your firebase dataset eg List of Gig object
private MutableLiveData<List<Gig>> myGigLiveData;
.......
//initialize inside onCreate()
myGigLiveData = new MutableLiveData<>();
.......
mRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
Gig thisGig = dataSnapshot.getValue(Gig.class);
loadedGigs.add(thisGig);
Log.w("onCreate", "There are " + loadedGigs.size() + "Gigs loaded in the array.");
arrayAdapter.notifyDataSetChanged();
//set the dataset value to livedata
myGigLiveData.setValue(loadedGigs);
}
...............
//observe the livedata in onStart like so:
@Override
protected void onStart()
{
super.onStart();
myGigLiveData.observe(this, gigsList ->{
Log.w("onStart", "There are " + gigsList.size() + "Gigs loaded in the array.");
});
}
在您的活动中,onCreate((在onStart((之前被调用,但在onCreate(。
您开始在onChildAdded
回调中填充loadedGigs
列表,该回调(在您的情况下(触发了AFTER活动的onStart()
调用。
根据文档,ChildEventListener
的"当发生更改时,将触发适当的方法",这意味着它将在未来的某个时刻以异步方式发生,因此您不应该期望您的数据存在于活动的onStart()
中。
还有一件事。您的Log.w("onCreate",...)
与活动的生命周期onCreate(Bundle savedInstanceState)
无关,这样的日志输出消息可能会混淆。