1

根据 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 和子事件侦听器有关。我缺乏相当多的知识,我认为这就是为什么我无法弄清楚。

提前谢谢,弗拉德

4

3 回答 3

4

事实核查

事实是,onCreate()先调用后调用onStart()。但是因为您正在调用 firebase 来获取您的数据集,onStart()所以您不会等待此操作完成,这意味着您的列表onStart仍然没有填充。记住什么时候onCreate被调用,无论在那里执行什么代码,它都不会onStart因为被调用而暂停。同样,在执行它自己的代码之前,onStart不要等待里面的所有代码onCreate完成。

你的问题

onStart从 firebase eventlisteners inside 获取数据集后,您似乎想在里面做点什么onCreate。一世

一个建议可能吗?

您可以使用LiveData让您的代码内部onStart知道 firebase 事件侦听器已完成,并已准备好您需要在onStart.

你问什么是实时数据?

LiveData 是一个可观察的数据持有者类。与常规的 observable 不同,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.");
});

    }

于 2019-11-17T10:17:28.373 回答
3

在您的活动中 onCreate() 在 onStart() 之前调用,但在您的 onCreate() 方法中您只添加 childEventListener,而onChildAdded事件仅在调用 onStart() 之后发生,这就是您在日志中看到的内容。

于 2019-11-17T10:11:52.187 回答
2

您开始在活动调用后(在您的情况下)触发的回调中填充您的loadedGigs列表。onChildAddedonStart()

根据文档,ChildEventListener发生更改时将触发适当的方法”,这意味着它将在未来某个时刻以异步方式发生,因此您不应期望您的数据存在于活动的onStart().

还有一件事。您Log.w("onCreate",...)与活动的生命周期无关onCreate(Bundle savedInstanceState),此类日志输出消息可能会造成混淆。

于 2019-11-17T10:39:36.127 回答