javaandroidoncreateonstart

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


Solution

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