Skip to content

Instantly share code, notes, and snippets.

@kaushikgopal
Last active February 2, 2022 07:28
Show Gist options
  • Star 80 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save kaushikgopal/5c1b029798b73c73193d to your computer and use it in GitHub Desktop.
Save kaushikgopal/5c1b029798b73c73193d to your computer and use it in GitHub Desktop.
Notes on opportune moments to do "stuff" in the Android Lifecycle
  • In general you want to try and put things in onStart and onStop for logical start and stops.

Activity

onCreate

  • Dagger inject self into graph
  • setContentView(R.layout.xxx)
  • Butterknife.bind(this)
  • RxJava CompositeSubscription.add (if NON UI related work being done)
  • realm = Realm.getDefaultInstance();

onStart

onResume

  • RxJava CompositeSubscription.add (if ui related work being done)

onPause

  • RxJava CompositeSubscription.clear (if ui related work being done)

onStop

  • EventBus unregister

onDestroy

  • Dagger "Activity" scoped graph destruction
  • RxJava CompositeSubscription.clear (if NON UI related work being done)
  • realm.close();

Fragment (DialogFragment etc.)

onAttach(Context) (prev.Activity)

  • Dagger inject self into graph
  • setCallbackOrListener(activity) - when you want to communicate back to the activity

Warning: lifecycle callpoint is subtly different now. onAttach(Context) is called later than onAttach(Activity) and so if you expected the injection to have happened before certain callbacks like onViewCreated this is not the case (e.g. API 19)

onCreateView

  • view = Inflate.inflation
  • ButterKnife.bind(this, view);
  • realm = Realm.getDefaultInstance();

onStart

  • EventBus register

onResume

  • RxJava CompositeSubscription.add (if ui related work being done)

onPause

  • RxJava CompositeSubscription.clear (if ui related work being done)

onStop

  • EventBus unregister

onDestroy

  • LeakCanary MyApp.getRefWatcher().watch(this);

onDestroyView

  • ButterKnife.unbind(this);
  • realm.close();

View

onFinishInflate

  • Butterknife.bind(this)

onAttachedToWindow

  • RxJava CompositeSubscription.add

onDetachedFromWindow

  • RxJava CompositeSubscription.clear

Application

  • LeakCanary Refwatcher = LeakCanary.install(this);
  • Dagger ObjectGraph.create

ViewHolder (for RecyclerViews, ListViews etc.)

ViewHolder (Constructor)

  • Butterknife.bind(this. itemView)
@kaushikgopal
Copy link
Author

This started as an experiment to put the new Dropbox Paper app through its paces. Unfortunately Dropbox exposes email addresses when collaborating with Paper, so it was probably not the best tool for the experiment. Decided to post it here instead. ¯_(ツ)_/¯. Feel free to throw in your suggestions

@konmik
Copy link

konmik commented Feb 17, 2016

Hi Kaushik,

I think it is better to start listening the event bus during the first onResume.

After onStart onRestoreInstanceState will be fired, so if you get an event during onStart and update your views the new view state will be erased by the previous state.

@kaushikgopal
Copy link
Author

@konmik very interesting. The counter to having it in onResume is the case where you have a dialog show up in front of the activity. onPause would be fired and the event bus would stop listening to future events in that activity.

question: how often though do you think we would get an important event fired between onStart and onRestoreInstanceState? The counter point i brought up is possibly more plausible?

I see your point too though. I guess we pick the lesser of two evils :( ?

  • Lifecycles are a pain
  • Yet another point for RxJava > EventBus

Copy link

ghost commented Feb 17, 2016

I pretty much follow this and put all(most) of these in a base to make all activities and fragments behave well.

@jmarkovic
Copy link

Technicality aside, I'm genuinely interested in what capacity you use EventBus and for what? Since you do agree that RxJava > EventBus. I'd like not to go on a big tangent here, but would just like to say that I find EB useful only in stateless environments, such as very long running tasks which are rare in Android (like background services, EB is a cool way to notify the service about news, like POST in REST).

Additionally, I'd just add onAttach in Fragment for fragment callback listener.

Thoughts?

@kaushikgopal
Copy link
Author

jmarkovic: onAttach - good point! adding it in.

The only reason i'm using an EventBus is because it's present in legacy code. Refactoring it all to RxJava is just too time consuming and hard to justify. The hope is to eventually move away.

@ar-g
Copy link

ar-g commented Feb 18, 2016

Do you use CompositeSubscription.add()/clean() in start()/stop() methods for activity/fragment as well? I using resume()/pause(), the only issue is FragmentDialogs, usually just trying to avoid intersection with dialogs in this case.

@kaushikgopal
Copy link
Author

@ar-g : hmm... I hesitate to put it as a general rule in here.

If you're doing UI related stuff with your Subscriptions, then sure onResume <-> onPause may be wise. but if you're doing non-ui related work like network activity, saving to disk etc. other concurrency related activity which RxJava is great at, then even onCreate <-> onDestroy might be better.

Interesting, maybe UI related events should be classified separately.

@brescia123
Copy link

@kaushikgopal Maybe it could be better to move UI related RxJava subscriptions addition and clearing from onPause/onResume to onStart/onStop. What do you think?

@kaushikgopal
Copy link
Author

@brescia123 any specific reason you're suggesting that over onResume/onPause ?

@apkelly
Copy link

apkelly commented Oct 30, 2016

The example on the Square website suggests calling the ButterKnife.unbind(this); method in the onDestroyView of a Fragment, to mirror the creation in onCreateView.

@kaushikgopal
Copy link
Author

@apkelly: good catch! updated

@155martinmoreno
Copy link

@brescia123 any specific reason you're suggesting that over onResume/onPause ?

maybe multi-window?

@kaushikgopal
Copy link
Author

@155martinmoreno gotcha. though, i suppose then it dives in to a case by case basis. if you truly wanted the stream to be "live" in multiwindow, sure it makes sense to have it onStop/Start. but if you want it to halt, anytime the ui is inactive (despite multiwindow), might still make sense to have it onResume/Pause

@mr-thierry
Copy link

mr-thierry commented Apr 5, 2017

Just a quick note: for the UI Graph, the Dagger graph creation should occur BEFORE calling super.onCreate(). Otherwise some fragment will try to call the Activity graph before is it created. So it should be in the onCreate(), but before calling super.onCreate(). :)

@pepos
Copy link

pepos commented Nov 17, 2017

Very nice document, I only have a concern, I would not recommend the following or at least I would add a warning:

View

onAttachedToWindow

  • RxJava CompositeSubscription.add

onDetachedFromWindow

  • RxJava CompositeSubscription.unsubscribe

When the app is pushed to the background, the view won't be detached from the window. So you need to be careful not to do some UI update like open new activity in this callback, because it is not guarantee that the app is in the foreground.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment