Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Task & Document API

Task & Document API

Tasks are the plumbing of Android apps: you use them every day when developing. But the Task API in Android is one of the most difficult API to apprehend. The behaviour fragmentation between the Android versions does not help us either: taskAffinity, launchMode, flags, etc. In addition to the Task API, Android 5.0 introduced the Document Task API. This new feature is a big upheaval on how we manage tasks as Android developers and users.

In this presentation, we will have an in depth look at these APIs. We will see how to use them in typical use cases.

Video available here: https://www.youtube.com/watch?v=NTWmxp8dzBs

Mathieu Calba

November 10, 2015
Tweet

More Decks by Mathieu Calba

Other Decks in Programming

Transcript

  1. Task & Document API
    Droidcon Paris 2015

    View Slide

  2. @Mathieu_Calba
    +MathieuCalba

    View Slide

  3. @Mathieu_Calba
    +MathieuCalba

    View Slide

  4. What is a Task?

    View Slide

  5. What is a Task?
    An Activity represents a screen

    View Slide

  6. What is a Task?
    An application is often composed of many activities

    View Slide

  7. What is a Task?
    An application is often composed of many activities

    View Slide

  8. What is a Task?
    An application is often composed of
    A task is an ordered queue
    of activities called “back stack”

    View Slide

  9. What is a Task?
    Tasks are presented
    in the overview screen

    View Slide

  10. What is a Task?
    • Since 1.0: icon and name
    • Screenshot added in 4.3
    • Icon and name customisation added in 5.0
    Overview screen

    View Slide

  11. What is a Task?
    Overview screen

    View Slide

  12. How does it work?

    View Slide

  13. How does it work?
    2 main ways:
    • Attributes on the tag in the AndroidManifest.xml
    • Flags on the Intent
    Task API

    View Slide

  14. How does it work?
    android:allowTaskReparenting
    android:alwaysRetainTaskState
    android:autoRemoveFromRecents
    android:clearTaskOnLaunch
    android:documentLaunchMode
    android:excludeFromRecents
    android:finishOnTaskLaunch
    Task API
    android:launchMode
    android:maxRecents
    android:noHistory
    android:relinquishTaskIdentity
    android:stateNotNeeded
    android:taskAffinity

    View Slide

  15. How does it work?
    Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
    Intent.FLAG_ACTIVITY_CLEAR_TASK
    Intent.FLAG_ACTIVITY_CLEAR_TOP
    Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
    Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
    Intent.FLAG_ACTIVITY_MULTIPLE_TASK
    Intent.FLAG_ACTIVITY_NEW_DOCUMENT
    Intent.FLAG_ACTIVITY_NEW_TASK
    Task API
    Intent.FLAG_ACTIVITY_NO_ANIMATION
    Intent.FLAG_ACTIVITY_NO_HISTORY
    Intent.FLAG_ACTIVITY_NO_USER_ACTION
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
    Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
    Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
    Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS
    Intent.FLAG_ACTIVITY_SINGLE_TOP
    Intent.FLAG_ACTIVITY_TASK_ON_HOME
    Intent.FLAG_ACTIVITY_HELL

    View Slide

  16. Have fun with flags!

    View Slide

  17. Standard behaviour

    View Slide

  18. Standard behaviour
    Action: android.intent.action.MAIN
    Category: android.intent.category.LAUNCHER
    Flags:
    • Intent.FLAG_ACTIVITY_NEW_TASK
    • Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
    Start from launcher

    View Slide

  19. Standard behaviour
    Start from launcher
    Action: android.intent.action.MAIN
    Category: android.intent.category.LAUNCHER
    Flags:
    • Intent.FLAG_ACTIVITY_NEW_TASK
    • Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

    View Slide

  20. Action: android.intent.action.MAIN
    Category: android.intent.category.LAUNCHER
    Flags:
    • Intent.FLAG_ACTIVITY_NEW_TASK
    • Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
    Standard behaviour
    Start from launcher
    My awesome app

    View Slide

  21. My awesome app
    Standard behaviour
    Start from launcher
    Action: android.intent.action.MAIN
    Category: android.intent.category.LAUNCHER
    Flags:
    • Intent.FLAG_ACTIVITY_NEW_TASK
    • Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

    View Slide

  22. My awesome app
    Standard behaviour
    Start from launcher
    Action: android.intent.action.MAIN
    Category: android.intent.category.LAUNCHER
    Flags:
    • Intent.FLAG_ACTIVITY_NEW_TASK
    • Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

    View Slide

  23. Intent.FLAG_ACTIVITY_NEW_TASK
    Start the activity in a new Task depending on the task’s affinity
    Standard behaviour
    Start from launcher

    View Slide

  24. android:taskAffinity
    Used to determine in which task this activity will be launched when started
    with Intent.FLAG_ACTIVITY_NEW_TASK
    Application’s package name by default
    Standard behaviour
    Start from launcher

    View Slide

  25. Action: null
    Category: null
    Flags: null
    My awesome app
    Standard behaviour
    Start from within the app
    My awesome screen

    View Slide

  26. My awesome app
    My awesome screen
    Standard behaviour
    Start from within the app
    Action: null
    Category: null
    Flags: null

    View Slide

  27. Standard behaviour
    Start from overview
    My awesome app
    My awesome screen
    Action: null
    Category: null
    Flags: null

    View Slide

  28. My awesome app
    My awesome screen
    Standard behaviour
    Start from overview
    Action: null
    Category: null
    Flags: null

    View Slide

  29. Standard behaviour
    Start from overview
    My awesome app
    My awesome screen
    Action: null
    Category: null
    Flags: null

    View Slide

  30. Standard behaviour
    Start from overview
    My awesome app
    My awesome screen
    Action: null
    Category: null
    Flags: null

    View Slide

  31. My awesome app
    Same Intent that launched this activity
    Action: android.intent.action.MAIN
    Category: android.intent.category.LAUNCHER
    Flags:
    Intent.FLAG_ACTIVITY_NEW_TASK
    Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
    Standard behaviour
    Restart from back
    My awesome app
    My awesome screen

    View Slide

  32. My awesome app
    Same Intent that launched this activity
    Action: android.intent.action.MAIN
    Category: android.intent.category.LAUNCHER
    Flags:
    Intent.FLAG_ACTIVITY_NEW_TASK
    Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
    Standard behaviour
    Restart from back
    My awesome app
    My awesome screen

    View Slide

  33. But there is more to it

    View Slide

  34. But there is more to it
    USE ANOTHER APP TO DO A JOB
    MANY ENTRY POINTS INTO OUR APP
    MULTITASKING INSIDE AN APP

    View Slide

  35. But there is more to it
    USE ANOTHER APP TO DO A JOB
    MANY ENTRY POINTS INTO OUR APP
    MULTITASKING INSIDE AN APP

    View Slide

  36. But there is more to it
    USE ANOTHER APP TO DO A JOB
    MANY ENTRY POINTS INTO OUR APP
    MULTITASKING INSIDE AN APP

    View Slide

  37. Using other applications
    startActivity(new Intent().setAction(Intent.ACTION_VIEW)
    .setData(Uri.parse("http://captaintrain.com"));

    What behaviour does occur? New task or not?
    Opening an Url

    View Slide

  38. Using other applications
    Opening an Url
    It depends on the opened application!
    startActivity(new Intent().setAction(Intent.ACTION_VIEW)
    .setData(Uri.parse("http://captaintrain.com"));

    What behaviour does occur? New task or not?

    View Slide

  39. Using other applications
    • With the old Android browser: new task
    • With Firefox: new task
    • With Chrome: same task
    Opening an Url

    View Slide

  40. Using other applications
    Same task
    Action: android.intent.action.VIEW
    Category: null
    Flags:
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
    Opening an Url

    View Slide

  41. Using other applications
    Opening an Url
    New task
    Action: android.intent.action.VIEW
    Category: null
    Flags:
    Intent.FLAG_ACTIVITY_NEW_TASK
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP

    View Slide

  42. Using other applications
    Opening an Url
    New task
    Action: android.intent.action.VIEW
    Category: null
    Flags:
    Intent.FLAG_ACTIVITY_NEW_TASK
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
    WHY DID IT APPEAR?

    View Slide

  43. Using other applications
    In the old Android browser’s manifest:
    !
    android:label="@string/app_name"

    android:launchMode="singleTask"

    android:name=".MainActivity"

    android:theme="@style/AppTheme.NoActionBar">
    Opening an Url

    View Slide

  44. Using other applications
    In the old Android browser’s manifest:
    !
    android:label="@string/app_name"

    android:launchMode="singleTask"

    android:name=".MainActivity"

    android:theme="@style/AppTheme.NoActionBar">
    Opening an Url

    View Slide

  45. android:launchMode
    Determines how an activity is launched

    View Slide

  46. android:launchMode
    • New instance of the activity all the time
    • Can be anywhere in the stack
    • Which task is determined by the presence of FLAG_ACTIVITY_NEW_TASK and
    the android:taskAffinity attribute
    android:launchMode=“standard”

    View Slide

  47. android:launchMode
    • New instance of the activity most of the time
    • Can be anywhere in the stack
    • Which task is determined by the presence of FLAG_ACTIVITY_NEW_TASK and
    the android:taskAffinity attribute
    • If the targeted task already has this activity at the top of it with this
    android:launchMode, instead of creating a new instance, it just send a new
    Intent to this instance, which will receive it in the onNewIntent() method
    android:launchMode=“singleTop”

    View Slide

  48. android:launchMode
    • Only one instance of the activity
    • Always the root activity of the task
    • Other activities can be in its task (only standard and singleTop activities)
    android:launchMode=“singleTask”

    View Slide

  49. android:launchMode
    • Only one instance of the activity
    • Always the root activity of the task
    • Alone in its task
    • Every startActivity() behave just like if the Intent has the
    FLAG_ACTIVITY_NEW_TASK flag
    android:launchMode=“singleInstance”

    View Slide

  50. android:launchMode
    android:launchMode behaviour can be overridden by the FLAG_ACTIVITY_* in
    the intent

    View Slide

  51. Using other applications
    What is the correct behaviour?
    This way (app -> browser), it’s better to have them in the same task, because
    the browser is a utility
    Nothing can be done to prevent a new task to be launched here
    Opening an Url

    View Slide

  52. Using other applications
    Taking a picture
    final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    startActivityForResult(intent, REQUEST_CODE_IMAGE_CAPTURE);

    View Slide

  53. Using other applications
    Taking a picture
    Only works when activity started in the same task
    Otherwise, an Activity.RESULT_CANCELED is received directly
    final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    startActivityForResult(intent, REQUEST_CODE_IMAGE_CAPTURE);

    View Slide

  54. Using other applications
    Sharing via email
    But it launch in the same task, which is not the expected behaviour on 5.0+
    final Intent target = new Intent()

    .setAction(Intent.ACTION_SENDTO)

    .setData(Uri.fromParts(“mailto", "[email protected]", null))

    .putExtra(Intent.EXTRA_TEXT, "Hello Droidcon!");

    startActivity(Intent.createChooser(target, "My chooser"));

    View Slide

  55. Using other applications
    Sharing via email
    Action: android.intent.action.SENDTO
    Category: null
    Data: mailto:[email protected]
    Flags:
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
    final Intent target = new Intent()

    .setAction(Intent.ACTION_SENDTO)

    .setData(Uri.fromParts(“mailto", "[email protected]", null))

    .putExtra(Intent.EXTRA_TEXT, "Hello Droidcon!");

    startActivity(Intent.createChooser(target, "My chooser"));

    View Slide

  56. Using other applications
    Sharing via email
    Action: android.intent.action.SENDTO
    Category: null
    Data: mailto:[email protected]
    Flags:
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
    final Intent target = new Intent()

    .setAction(Intent.ACTION_SENDTO)

    .setData(Uri.fromParts(“mailto", "[email protected]", null))

    .putExtra(Intent.EXTRA_TEXT, "Hello Droidcon!");

    startActivity(Intent.createChooser(target, "My chooser"));

    View Slide

  57. Using other applications
    Intent.FLAG_ACTIVITY_NEW_TASK?
    No, because we don’t want to be launched in the targeted application’s task
    Sharing via email

    View Slide

  58. Using other applications
    Intent.FLAG_ACTIVITY_NEW_DOCUMENT (5.0+)
    • Start a new task dedicated to this job
    • New mail and original application are accessible via the overview screen
    • Restarting the original task from overview will not bring the mail activity
    Sharing via email

    View Slide

  59. Using other applications
    Compatibility: Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
    • Start a the job in the same task
    • Restarting the original task from overview will not bring the mail activity as
    it will be finished
    Sharing via email

    View Slide

  60. Using other applications
    final Intent target = new Intent()

    .setAction(Intent.ACTION_SENDTO)

    .setData(Uri.fromParts(“mailto", "[email protected]", null))

    .putExtra(Intent.EXTRA_TEXT, "Hello Droidcon!");

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

    target.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);

    } else {

    target.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

    }

    startActivity(Intent.createChooser(target, "My chooser"));
    Sharing via email

    View Slide

  61. Using other applications
    Sharing via email
    final Intent target = new Intent()

    .setAction(Intent.ACTION_SENDTO)

    .setData(Uri.fromParts(“mailto", "[email protected]", null))

    .putExtra(Intent.EXTRA_TEXT, "Hello Droidcon!");

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

    target.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);

    } else {

    target.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

    }

    startActivity(Intent.createChooser(target, "My chooser"));

    View Slide

  62. Multiple entry points
    Internally:
    • From the notification
    • From a widget
    • From a wear app
    Externally:
    • Multiple icons in the launcher
    • Responding to a public Intent (URL, sharing, etc)

    View Slide

  63. Multiple entry points
    Internally

    View Slide

  64. Multiple entry points
    Internally
    final PendingIntent pendingIntent = TaskStackBuilder.create(this)

    .addNextIntentWithParentStack(DetailsActivity.
    newFocusOnBarcodeIntent(this, id))
    .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    Action: null
    Category: null
    Flags:
    Intent.FLAG_ACTIVITY_NEW_TASK
    Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT

    View Slide

  65. Multiple entry points
    Allow us to create a stack of activities
    Internally
    final PendingIntent pendingIntent = TaskStackBuilder.create(this)

    .addNextIntentWithParentStack(DetailsActivity.
    newFocusOnBarcodeIntent(this, id))
    .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

    View Slide

  66. Multiple entry points
    TaskStackBuilder.create(this)

    .addParentStack(ParentActivity.class)

    .addNextIntent(detailIntent)

    .startActivities();
    Internally
    Add the parent’s stack as defined by android:parentActivityName in
    AndroidManifest.xml

    View Slide

  67. Multiple entry points
    Add the targeted activity’s Intent
    Internally
    TaskStackBuilder.create(this)

    .addParentStack(ParentActivity.class)

    .addNextIntent(detailIntent)

    .startActivities();

    View Slide

  68. Multiple entry points
    Internally
    Do both at the same time
    TaskStackBuilder.create(this)

    .addNextIntentWithParentTask(detailIntent)

    .startActivities();

    View Slide

  69. Multiple entry points
    Internally
    Start the stack
    TaskStackBuilder.create(this)

    .addNextIntentWithParentTask(detailIntent)

    .startActivities();

    View Slide

  70. Multiple entry points
    Internally
    Create a pending Intent to be launched
    TaskStackBuilder.create(this)

    .addNextIntentWithParentTask(detailIntent)

    .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

    View Slide

  71. Multiple entry points
    Multiple icons in the app drawer
    Use cases very uncommon: app with multiple specific jobs
    Multiple activities declared with intent-filter:
    !




    Become interesting with non-standard android:launchMode
    Externally

    View Slide

  72. Multiple entry points
    Intercepting Urls:
    !













    Externally

    View Slide

  73. Multiple entry points
    From the old Android browser:
    Action: android.intent.action.VIEW
    Category: android.intent.category.BROWSABLE
    Data: https://www.captaintrain.com/search
    Flags:
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
    Externally
    S
    AM
    E TASK

    View Slide

  74. Multiple entry points
    From the email app:
    Action: android.intent.action.VIEW
    Category: android.intent.category.BROWSABLE
    Data: https://www.captaintrain.com/search
    Flags:
    Intent.FLAG_ACTIVITY_NEW_TASK
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
    Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
    Intent.FLAG_ACTIVITY_NEW_DOCUMENT
    Intent.FLAG_ACTIVITY_NO_ANIMATION
    Externally
    N
    EW
    TASK

    View Slide

  75. Multiple entry points
    From the email app:
    Action: android.intent.action.VIEW
    Category: android.intent.category.BROWSABLE
    Data: https://www.captaintrain.com/search
    Flags:
    Intent.FLAG_ACTIVITY_NEW_TASK
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
    Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
    Intent.FLAG_ACTIVITY_NEW_DOCUMENT
    Intent.FLAG_ACTIVITY_NO_ANIMATION
    Externally
    N
    EW
    TASK

    View Slide

  76. Multiple entry points
    From Chrome:
    Action: android.intent.action.VIEW
    Category: android.intent.category.BROWSABLE
    Data: https://www.captaintrain.com/search
    Flags:
    Intent.FLAG_ACTIVITY_NEW_TASK
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
    Externally
    N
    EW
    TASK

    View Slide

  77. Multiple entry points
    From Chrome:
    Action: android.intent.action.VIEW
    Category: android.intent.category.BROWSABLE
    Data: https://www.captaintrain.com/search
    Flags:
    Intent.FLAG_ACTIVITY_NEW_TASK
    Intent.FLAG_ACTIVITY_FORWARD_RESULT
    Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP
    Externally
    N
    EW
    TASK

    View Slide

  78. Multiple entry points
    What is the good behaviour?
    Externally

    View Slide

  79. Multiple entry points
    What is the good behaviour?
    Externally
    !
    New task!

    View Slide

  80. Multiple entry points
    2 solutions:
    • let the current behaviour and let some user have some bad experience
    • force the creation of a new task for better user experience at the expense
    of clean code
    Externally

    View Slide

  81. Multiple entry points
    2 solutions:
    • let the current behaviour and let some user have some bad experience
    • force the creation of a new task for better user experience at the expense
    of clean code
    Externally
    Here come android:launchMode=“singleTask” to the rescue!

    View Slide

  82. Multiple entry points
    Create a special activity that will catch all Urls you need to catch:
    !
    android:launchMode="singleTask"

    android:name=".UrlCatcherActivity"

    android:theme="@android:style/Theme.NoDisplay">












    And then it will redirect to the correct activity and finish itself
    Externally

    View Slide

  83. Multitasking inside an app
    Why?
    • multi-document opened at the same time
    • writing an email and looking at other emails as references
    • multi-tasking at the system level is quicker than at the app level

    View Slide

  84. Introducing Document API (5.0+)

    View Slide

  85. Introducing Document API (5.0+)
    Move from app-centric to document-centric system

    View Slide

  86. Introducing Document API (5.0+)
    An extension of the Tasks API
    Move from app-centric to document-centric system

    View Slide

  87. Multitasking inside an app
    Only one instance of this document, one task
    Same as setting FLAG_ACTIVITY_NEW_DOCUMENT alone on the Intent
    android:launchMode=“standard” mandatory
    Create new document
    android:label="NewDocument"

    android:documentLaunchMode="intoExisting"

    android:name=".NewDocumentActivity" />

    View Slide

  88. Multitasking inside an app
    Multiple instance of this document, multiple tasks
    Same as setting FLAG_ACTIVITY_NEW_DOCUMENT and
    FLAG_ACTIVITY_MULTIPLE_TASK on the Intent
    android:launchMode must be standard
    Create new document
    android:label="NewDocument"

    android:documentLaunchMode="always"

    android:name=".NewDocumentActivity" />

    View Slide

  89. Multitasking inside an app
    Create new document
    Default value of the attribute
    New task only if FLAG_ACTIVITY_NEW_TASK or specific android:launchMode
    android:label="NewDocument"

    android:documentLaunchMode="none"

    android:name=".NewDocumentActivity" />

    View Slide

  90. Multitasking inside an app
    Create new document
    Even with FLAG_ACTIVITY_NEW_DOCUMENT, no new document task
    android:label="NewDocument"

    android:documentLaunchMode="never"

    android:name=".NewDocumentActivity" />

    View Slide

  91. Multitasking inside an app
    Limiting the history
    Define the max number of recent documents for one activity
    Between 1 and 50, default to 16
    android:label="NewDocument"

    android:documentLaunchMode="always"

    android:maxRecents="50"

    android:name=".NewDocumentActivity" />

    View Slide

  92. Multitasking inside an app
    Starting in background

    View Slide

  93. Multitasking inside an app
    Starting in background
    Force the grouping of documents with the original activity
    Force the behaviour of the android:documentLaunchMode=“always”
    final ActivityOptions options = ActivityOptions.makeTaskLaunchBehind();

    final Intent intent = new Intent(this, NewDocumentActivity.class)

    .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);

    startActivity(intent, options.toBundle());

    View Slide

  94. Multitasking inside an app
    In ActivityManager:
    !
    public List getAppTasks()
    Managing documents

    View Slide

  95. Multitasking inside an app
    ActivityManager.AppTask
    Contains a lot of information on a task, you can:
    !
    public RecentTaskInfo getTaskInfo()
    !
    public void moveToFront()
    !
    public void finishAndRemoveTask()
    Managing documents

    View Slide

  96. Multitasking inside an app
    In a document activity:
    • finish() will terminate the activity but let the task remain in overview
    • finishAndRemoveTask() will terminate the activity and remove the task in
    overview
    Removing a document

    View Slide

  97. Multitasking inside an app
    Use FLAG_ACTIVITY_NEW_DOCUMENT when launching an external activity on
    5.0+
    On pre-5.0, use FLAG_ACTIVITY_CLEAR_TASK_WHEN_RESET to get roughly the
    same behaviour
    Compatibility

    View Slide

  98. Multitasking inside an app
    ActivityManager.TaskDescription
    Customising the overview entry of your activity:
    !
    setTaskDescription(new ActivityManager.TaskDescription(
    "New label”,
    bitmap,
    getColor(R.color.red)));
    Overview screen customisation (5.0+)

    View Slide

  99. Multitasking inside an app
    Overview screen customisation (5.0+)

    View Slide

  100. Multitasking inside an app
    Persistance behaviours (5.0+)
    Default value
    Persist the activity only if it’s the root of the task
    android:label="NewDocument"

    android:documentLaunchMode="always"

    android:persistableMode="persistRootOnly"

    android:name=".NewDocumentActivity" />

    View Slide

  101. Multitasking inside an app
    Persistance behaviours (5.0+)
    If the activity is the root of the task, the task is not persisted
    android:label="NewDocument"

    android:documentLaunchMode="always"

    android:persistableMode="persistNever"

    android:name=".NewDocumentActivity" />

    View Slide

  102. Multitasking inside an app
    Persistance behaviours (5.0+)
    The activity is persisted across reboot
    Uses a PersistableBundle in onCreate/onSavedInstanceState to restore/
    persist some data across reboot
    android:label="NewDocument"

    android:documentLaunchMode="always"

    android:persistableMode="persistAcrossReboots"

    android:name=".NewDocumentActivity" />

    View Slide

  103. Choose the behaviour you
    want wisely

    View Slide

  104. Choose the behaviour you
    want wisely
    New task only when there is
    a break in the app flow

    View Slide

  105. API is complicated,
    but powerful

    View Slide

  106. Credits
    !
    • Nexus 5 frame - Cyril Mottier
    • Fonts: Lato, Menlo

    View Slide