android - What Are the Differences Between FLAG_ACTIVITY_RESET_TASK_IF_NEEDED and FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP? -


i in process of (finally) writing chapter on tasks book, , encountering few lingering puzzles.

things serve home screen launchers seem use combination of flag_activity_new_task , flag_activity_reset_task_if_needed when launch requested launcher activity:

intent i=new intent(intent.action_main);  i.addcategory(intent.category_launcher); i.setflags(intent.flag_activity_new_task |             intent.flag_activity_reset_task_if_needed); i.setcomponent(name);  startactivity(i);   

the documentation flag_activity_reset_task_if_needed has:

if set, , activity either being started in new task or bringing top existing task, launched front door of task. result in application of affinities needed have task in proper state (either moving activities or it), or resetting task initial state if needed.

that's not clear.

in particular, seem same effects seen using combination of flag_activity_clear_top , flag_activity_single_top. quoting docs flag_activity_clear_top:

if set, , activity being launched running in current task, instead of launching new instance of activity, of other activities on top of closed , intent delivered (now on top) old activity new intent...

the running instance of [the desired activity] either receive new intent starting here in onnewintent() method, or finished , restarted new intent. if has declared launch mode "multiple" (the default) , have not set flag_activity_single_top in same intent, finished , re-created; other launch modes or if flag_activity_single_top set intent delivered current instance's onnewintent().

the flag_activity_clear_top documentation makes sense, @ least me.

so, flag_activity_reset_task_if_needed different combination of flag_activity_clear_top , flag_activity_single_top?


bonus points if can explain flag_activity_clear_task different either of other 2 options described above.

if set in intent passed context.startactivity(), flag cause existing task associated activity cleared before activity started. is, activity becomes new root of otherwise empty task, , old activities finished. can used in conjunction flag_activity_new_task.

one obvious difference between , flag_activity_clear_top | flag_activity_single_top flag_activity_clear_task needs flag_activity_new_task. but, other that, seem net effects same, , match flag_activity_reset_task_if_needed.

i had @ source code activitymanager. flag intent.flag_activity_reset_task_if_needed indeed magic intent.flag_activity_clear_top | intent.flag_activity_single_top not do: triggers task reparenting.

here's (albeit lame) example:

in app have root activity roota , have activity reparentablea:

<application         android:label="@string/app_name">     <activity android:name=".roota">         <intent-filter>             <action android:name="android.intent.action.main"/>             <category android:name="android.intent.category.launcher"/>         </intent-filter>     </activity>     <activity android:name=".reparentablea"             android:allowtaskreparenting="true"/> </application> 

app has package name "com.app.a" default taskaffinity of components "com.app.a".

in app b have root activity rootb:

<application         android:label="@string/app_name">     <activity android:name="rootb">         <intent-filter>             <action android:name="android.intent.action.main"/>             <category android:name="android.intent.category.launcher"/>         </intent-filter>     </activity> </application> 

app b has package name "com.app.b" default taskaffinity of components "com.app.b".

now launch app b home screen. starts new task , creates new instance of activity rootb root activity in task. activity rootb launches activity reparentablea in standard way, without special flags. instance of reparentablea created , put on top of rootb in current task.

press home.

now launch app home screen. starts new task , creates new instance of activity roota root activity in task. note: when android launches "launcher" intent, automatically sets flags intent.flag_activity_new_task , intent.flag_activity_reset_task_if_needed. because of this, launching roota triggers task reparenting. android looks see if there activities in other tasks have affinity new task (and reparentable). finds reparentablea (which has same task affinity roota) in app b task , moves new app task. when launching app not see roota, see reparentablea, moved top of new task.

if return app b, can see reparentablea gone task stack , task consists of 1 activity: rootb.


notes using intent.flag_activity_clear_top | intent.flag_activity_single_top

the important thing remember using these flags "reset task" it works if there instance of target activity @ root of task. if root activity ever finishes, cannot clear task starting root activity intent.flag_activity_clear_top | intent.flag_activity_single_top. android create new instance of target (root) activity , put on top of existing activities in task, not @ want.


difference between intent.flag_activity_clear_task , intent.flag_activity_clear_top | intent.flag_activity_single_top:

as noted above, using clear_top | single_top works if there instance of target activity in task. clear_task, however, removes activities task, regardless of whether or not there instance of target activity in task. also, using clear_task ensures target activity becomes root activity of task, without needing know activity root activity before cleared task.


difference between intent.flag_activity_clear_task , intent.flag_activity_reset_task_if_needed:

as indicated above, using clear_task always remove activities task , launch new instance of target activity. in contrast, reset_task_if_needed reset task in situations (the "if_needed" part). task "reset" if android either:

  • creating new task (in case "reset" functionality involves task reparenting explained above), or
  • if android bringing background task foreground (in case task cleared of activities launched intent.flag_activity_clear_when_task_reset , activities on top of activities). note: root activity never cleared in case.

important note: when testing, please note there difference in way android behaves when launching apps home screen (or list of available applications) , when selecting tasks recent task list.

in first case (launching app selecting list of available applications or shortcut on home screen), launcher intent intent.flag_activity_new_task | intent.flag_activity_reset_task_if_needed created. used regardless of whether or not app running. intent launched , activitymanager figures out do.

in second case (selecting task list of recent tasks), if task still exists, brought front. task "reset" not performed if task brought front using recent task list. isn't obvious me how managed , i've not had chance through source code figure out why is.


i hope answers questions. looking forward feedback , test results.


Comments

Popular posts from this blog

google chrome - Developer tools - How to inspect the elements which are added momentarily (by JQuery)? -

angularjs - Showing an empty as first option in select tag -

php - Cloud9 cloud IDE and CakePHP -