Search code examples
androidandroid-intentactivity-lifecycle

Android- activity intents living through multiple onStart and onStop cycles


Any intent that gets passed either when an activity is created or as a param to onNewIntent(), lives as long as activity has not been destroyed. Well, even if the activity is launched from recent apps section after being destroyed but that's another issue.

My question is what should be the best practice in such cases to avoid duplicate processing due to old intent when activity is started/resumed from background or 'created' from recent apps section.

Say, am pulling getDataString() for example for analytics which should ideally be tracked only when the app has actually started via a deeplink. But it's very much available each time in the call-chain of onStart(), inside the old intent. What is recommended?

  1. intent be set to null in onStop()? //seems most logical to me. pitfalls?
  2. some local checks to ignore values?
  3. setting temporary field(s) in onStop() to identify if it's an old one?

Solution

  • After trying out various cases, here is what I found. Some of these opinions may have best suited my codebase but am guessing they are generically applicable.

    1. setting intent null is risky and can cause an NPE since we can't guarantee what all is intent being used for in the codebase, including being used indirectly by some internal api, e.g activity getReferrer
    2. local checks again is anyway a weak way to fix this.
    3. Similar to above but much cleaner. Stored a field in intent itself indicating if it has been 'consumed' [for any processing]. Function looks like:

      private void markIntentValuesTracked(final boolean status){
            if(getIntent() != null){
                getIntent().putExtra(LAUNCH_INTENT_VALUES_CONSUMED, status);
            }
        }
      

    method calls:

    onCreate():

    boolean isOldIntent = (getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0;
    markIntentValuesTracked(isOldIntent);
    

    onNewIntent(): markIntentValuesTracked(false);

    onStop(): markIntentValuesTracked(true)