简体   繁体   中英

why does onStart() method run before onCreate in my android project?

According to the activity lifecycle, onCreate() is called once when the app is created, followed by the onStart() method which may be called multiple times throughout the activity lifecycle. Yet that's not whats happening to me.

I have this code inside my onCreate method:

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) {

            }
        });

And then I have my onStart method:

@Override
    protected void onStart()
    {
        super.onStart();
        Log.w("onStart", "There are " + loadedGigs.size() + "Gigs loaded in the array.");


    }

And here are the logs:

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

I had other code but i deleted it all because I kept getting a null pointer exception and couldn't figure out why. Turns out I was trying to access the "loadedGigs" array list from inside the onStart method thinking it had already been populated from the onCreate method.

Any ideas on why this is happening? My best guess is it has something to do with my use of Firebase and the child event listener. I'm lacking quite a bit of knowledge and I think that's why I can't figure it out.

Thx in advance, Vlad

FACT CHECK

Fact of the matter is, onCreate() is called first then onStart() follows. But because you are making a firebase call to get your dataset, your onStart() is not waiting for this to complete, meaning your list inside onStart is still not populated. Remember when onCreate is called, whatever code is executed there, it does not pause onStart from being called. Likewise, onStart is not waiting for all the code inside onCreate to finish before exeuting it's own code.

YOUR PROBLEM

Seems you want to do something inside onStart after you get your dataset from firebase eventlisteners inside onCreate . I

A SUGGESTION MAYBE?

You can use LiveData to let your code inside onStart know that firebase event listeners are done, and have prepared the data you need to use in onStart .

WHAT IS LIVEDATA YOU ASK?

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.

See more here

HOW WILL IT LOOK LIKE:

 //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."); }); }

In your activity onCreate() is called before onStart(), but in your onCreate() method you only add the childEventListener, while the event onChildAdded only occurs after onStart() is called, and that's what you see in the logs.

You start populating your loadedGigs list in onChildAdded callback that is (in your case) fired AFTER activity's onStart() invocation.

According to the documentation, ChildEventListener 's "appropriate method will be triggered when changes occur" which means it will happen at some moment in the future in async fashion, so you shouldn't expect your data exists in activity's onStart() .

One more thing. Your Log.w("onCreate",...) is not about activity's lifecycle onCreate(Bundle savedInstanceState) , and such log output message may confuse.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM