为什么 onStart() 方法 运行 在我的 android 项目中的 onCreate 之前?
why does onStart() method run before onCreate in my android project?
根据activity生命周期,onCreate()在应用程序创建时被调用一次,随后的onStart()方法可能在整个activity生命周期中被调用多次。然而,这不是发生在我身上的事情。
我的 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 和子事件监听器的使用有关。我缺乏相当多的知识,我认为这就是我无法弄清楚的原因。
提前致谢,
弗拉德
在你的activity onCreate() 是在 onStart() 之前调用的,但是在你的 onCreate() 方法中你只添加了 childEventListener,而事件 onChildAdded 只在调用 onStart() 之后发生,这就是您在日志中看到的内容。
事实核查
事实上,onCreate()
先被调用,然后是 onStart()
。但是因为你正在调用 firebase 来获取你的数据集,你的 onStart()
没有等待它完成,这意味着你在 onStart
中的列表仍然没有填充。请记住,当 onCreate
被调用时,无论在那里执行什么代码,它都不会暂停 onStart
被调用。同样,onStart
在执行它自己的代码之前不会等待 onCreate
中的所有代码完成。
你的问题
从 onCreate
中的 firebase 事件监听器获取数据集后,你似乎想在 onStart
中做一些事情。我
有什么建议吗?
你可以使用LiveData
让你的代码在onStart
里面知道firebase事件监听已经完成,并且已经准备好你需要在onStart
中使用的数据了。
你问的是什么实时数据?
LiveData is an observable data holder class. Unlike a regular
observable, LiveData is lifecycle-aware, meaning it respects the
lifecycle of other app components, such as activities, fragments, or
services. This awareness ensures LiveData only updates app component
observers that are in an active lifecycle state.
查看更多 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.");
});
}
您开始在 onChildAdded
回调中填充您的 loadedGigs
列表(在您的情况下)在 activity 的 onStart()
调用之后触发。
根据文档,ChildEventListener
的 "appropriate method will be triggered when changes occur" 这意味着它将在未来的某个时刻以异步方式发生,因此您不应期望您的数据存在于 activity的onStart()
.
还有一件事。您的 Log.w("onCreate",...)
与 activity 的生命周期 onCreate(Bundle savedInstanceState)
无关,这样的日志输出消息可能会造成混淆。
根据activity生命周期,onCreate()在应用程序创建时被调用一次,随后的onStart()方法可能在整个activity生命周期中被调用多次。然而,这不是发生在我身上的事情。
我的 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 和子事件监听器的使用有关。我缺乏相当多的知识,我认为这就是我无法弄清楚的原因。
提前致谢, 弗拉德
在你的activity onCreate() 是在 onStart() 之前调用的,但是在你的 onCreate() 方法中你只添加了 childEventListener,而事件 onChildAdded 只在调用 onStart() 之后发生,这就是您在日志中看到的内容。
事实核查
事实上,onCreate()
先被调用,然后是 onStart()
。但是因为你正在调用 firebase 来获取你的数据集,你的 onStart()
没有等待它完成,这意味着你在 onStart
中的列表仍然没有填充。请记住,当 onCreate
被调用时,无论在那里执行什么代码,它都不会暂停 onStart
被调用。同样,onStart
在执行它自己的代码之前不会等待 onCreate
中的所有代码完成。
你的问题
从 onCreate
中的 firebase 事件监听器获取数据集后,你似乎想在 onStart
中做一些事情。我
有什么建议吗?
你可以使用LiveData
让你的代码在onStart
里面知道firebase事件监听已经完成,并且已经准备好你需要在onStart
中使用的数据了。
你问的是什么实时数据?
LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.
查看更多 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.");
});
}
您开始在 onChildAdded
回调中填充您的 loadedGigs
列表(在您的情况下)在 activity 的 onStart()
调用之后触发。
根据文档,ChildEventListener
的 "appropriate method will be triggered when changes occur" 这意味着它将在未来的某个时刻以异步方式发生,因此您不应期望您的数据存在于 activity的onStart()
.
还有一件事。您的 Log.w("onCreate",...)
与 activity 的生命周期 onCreate(Bundle savedInstanceState)
无关,这样的日志输出消息可能会造成混淆。