根据活动生命周期,创建应用程序时会先调用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和子事件侦听器有关。我缺少很多知识,我认为这就是为什么我无法弄清楚的原因。
提前,弗拉德
在您的活动中,onCreate()在onStart()之前被调用,但是在您的onCreate()方法中,您仅添加childEventListener,而事件onChildAdded仅在调用onStart()之后发生,这就是您所看到的在日志中。
事实检查
事实是,首先调用onCreate()
,然后调用onStart()
。但是,由于您正在进行Firebase调用以获取数据集,因此onStart()
不在等待此操作完成,这意味着onStart
内部的列表仍未填充。请记住,当调用onCreate
时,无论在此处执行什么代码,它都不会暂停onStart
的调用。同样,onStart
不会在执行自己的代码之前等待onCreate
中的所有代码完成。
您的问题
[似乎您想从onStart
内部的firebase事件侦听器获取数据集后,想要在onCreate
内部进行某些操作。我
可能有建议吗?
您可以使用LiveData
让您的onStart
内部的代码知道Firebase事件侦听器已完成,并且已经准备好需要在onStart
中使用的数据。
您问什么是LIVEDATA?
LiveData是可观察的数据持有者类。不像普通的可以观察到,LiveData具有生命周期意识,这意味着它尊重其他应用程序组件的生命周期,例如活动,片段或服务。这种意识确保LiveData仅更新应用程序组件处于活动生命周期状态的观察者。
查看更多here
它看起来如何:
//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.");
});
}
您开始在loadedGigs
回调中填充onChildAdded
列表,该列表(在您的情况下)在活动的onStart()
调用后触发。
根据文档,ChildEventListener
的"appropriate method will be triggered when changes occur"表示它将在未来的某个时候以异步方式发生,因此您不应该期望数据存在于活动的onStart()
中。
还有一件事。您的Log.w("onCreate",...)
与活动的生命周期onCreate(Bundle savedInstanceState)
无关,并且此类日志输出消息可能会造成混淆。