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