Android get app tasks

The Tasks API

Starting with Google Play services version 9.0.0, you can use a Task API and a number of methods that return Task or its subclasses. Task is an API that represents asynchronous method calls, similar to PendingResult in previous versions of Google Play services.

Handling task results

To be notified when the task succeeds, attach an OnSuccessListener :

To be notified when the task fails, attach an OnFailureListener :

To handle success and failure in the same listener, attach an OnCompleteListener :

Threading

Listeners attached to a thread are run on the application main (UI) thread by default. When attaching a listener, you can also specify an Executor that is used to schedule listeners.

Activity-scoped listeners

If you are listening for task results in an Activity , you may want to add activity-scoped listeners to the task. These listeners are removed during the onStop method of your Activity so that your listeners are not called when the Activity is no longer visible.

Chaining

If you use multiple APIs that return Task , you can chain them together using a continuation. This helps avoid deeply nested callbacks and consolidates error handling for chains of tasks.

For example, the method doSomething returns a Task but requires an AuthResult , which we will get asynchronously from a task:

Using the Task.continueWithTask method, we can chain these two tasks:

Blocking

If your program is already executing in a background thread you can block a task to get the result synchronously and avoid callbacks:

You can also specify a timeout when blocking a task so that your application does not hang:

Interoperability

A Task aligns conceptually to several popular Android approaches to managing asynchronous code, and a Task can be straightforwardly converted to other primitives, including the ListenableFuture and Kotlin coroutines, which are recommended by AndroidX.

Here’s an example using a Task :

Kotlin Coroutine

Usage

Add the following dependency to your project and use the code below to convert from a Task .

Gradle (module-level build.gradle , usually app/build.gradle )
Snippet

Guava ListenableFuture

Add the following dependency to your project and use the code below to convert from a Task .

Gradle (module-level build.gradle , usually app/build.gradle )
Snippet

RxJava2 Observable

Add the following dependency, in addition to the relative async library of choice, to your project and use the code below to convert from a Task .

Gradle (module-level build.gradle , usually app/build.gradle )
Snippet

Next steps

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Источник

a) Task Affinity:

In general, what is affinity?

Like all of you have affinity for Android App Development,
Activities also have affinity towards default package, that is the reason all the Activities in one App falls under one task, by default.

Where can one define Task Affinity?

You define affinity per activity in your AndroidManifest.xml.
Affinity of an Activity is defined by following attribute within tag:

Читайте также:  Отключение wifi по времени android

This parameter accepts a String. By default, every activity has same affinity as your package attribute value of mainfest tag.

Affinity of a Task is defined by the affinity of its root Activity.

b) Launch modes:

It is used to instructs Android system on how to launch a particular activity.
Two ways to define launchMode for an Activity:

Defining launch modes in Manifest File:

1. “standard”:

This is the default mode. In case you don’t define any launchMode, the new activity is launched in standard mode.
Here, a new instance of the Activity will be created — everytime.

2. “singleTop”

This is just as same as “standard” mode, except for — Android will perform an extra check “whether this activity is already on the top of the Activity Stack.”
If YES, then it won’t create a new instance of the Activity but instead it will call the onNewIntent() of the same Activity.

Have a look at the Activity Stack for “standard” & “singleTop” launch modes. Consider the Activity Intent order as: A → B → B → B

3. “singleTask”

Here, the referred Activity will be launched in the new Task.
(PS: You can notice this in Recents window)

So, you just define “launchMode”: “singleTask” and it will all work magically, huh?

Your current activity has to have a “taskAffinity” value defined other than the default package name. Or else, even though you have tagged it as “singleTask” it will still open it in the same damn Task.
One last important point to note is:

You CAN still have other Activities coming on top of this Activity, even in the newly created Task.

4. “singleInstance”

Well, this is exactly same as “singleTask” with one teeny-tiny difference.
That is:

You CANNOT have other Activities coming on top of this Activity. This Activity is a lone warrior in the Tasks playground. 😎

General Note on using “singleTask” & “singleInstance”:

When you launch an activity with a launchMode defined in Manifest, the Android system looks for the taskAffinity first. Then in the main stack of Tasks (i.e. Recents screen), Android checks if there is a task already present with the root Activity having same taskAffinity as the one for intended Activity, if Yes , then the Activity is opened in that task, else a new task is created and with Intended Activity placed at its root .

Defining launch modes using Intent Flags:

1. “FLAG_ACTIVITY_NEW_TASK”:

Now, putting it straight — this is just as same behaviour as
launchMode — singleTask.
Here, you do the same thing programmatically while creating your Intent for new Activity. Your code will look something like this:

Notes:

a) If you haven’t defined taskAffinity value different from the default one, setting this flag will have no effect. (Just like you did when using launchMode — singleTask)

b) The default behaviour of back press on newly created activity in a new task is — GO TO HOMESCREEN. If you want to go back to the Activity in your main task, that started this new Activity, then you have to define it in Manifest of your app. See the following snippet:

2. “FLAG_ACTIVITY_SINGLE_TOP”:

Again, this is same as launchMode — singleTop. You have to set the Intent Flag as follows:

Now, if the Activity to be launched is on the Top of the Activity stack, then instead of creating a new Activity, it will call onNewIntent() of the already open Activity. A sample snippet is as follows:

Читайте также:  Лефт 4 деад для андроид

3. “FLAG_ACTIVITY_CLEAR_TOP”:

There are two scenarios of use here:
a) All Activities in the same Task:
As expected, this flag will clear all the Activities on the top of Intended Activity in the stack and bring it to Foreground.

b) Activities spread across different tasks:
If this flag is set along with FLAG_ACTIVITY_NEW_TASK then the system will bring the required Task that contains the intended Activity to Foreground, and clear all the Activities on the top of that Activity.

That will be a wrap on Android Tasks from my side.

Источник

Tasks и Back Stack в Android

Итак. Каждое Android приложение, как минимум, состоит из фундаментальных объектов системы — Activity. Activity — это отдельный экран который имеет свою отдельную логику и UI. Количество Activity в приложении бывает разное, от одного до много. При переходах между различными Activity пользователь всегда может вернуться на предыдущую, закрытую Activity при нажатии кнопки back на устройстве. Подобная логика реализована с помощью стека (Activity Stack). Его организация «last in, first out» — т.е. последний вошел, первый вышел. При открытии новой Activity она становится вершиной, а предыдущая уходит в режим stop. Стек не может перемешиваться, он имеет возможность добавления на вершину новой Activity и удаление верхней текущей. Одна и та же Activity может находиться в стеке, сколько угодно раз.
Task — это набор Activity. Каждый таск содержит свой стек. В стандартной ситуации, каждое приложение имеет свой таск и свой стек. При сворачивании приложения, таск уходит в background, но не умирает. Он хранит весь свой стек и при очередном открытии приложения через менеджер или через launcher, существующий таск восстановится и продолжит свою работу.

Ниже покажу картинку, как работает стек.

Если продолжать нажимать кнопку back, то стек будет удалять Activity до того, пока не останется главная корневая. Если же на ней пользователь нажмет back, приложение закроется и таск умрет. Кстати, я говорил о том, что когда мы сворачиваем наше приложение и запускам например новое, то наш таск просто уходит в background и будет ждать момента, пока мы его вызовем. На самом деле есть одно «но». Если мы будем иметь много задач в background или же просто сильно нагружать свое устройство, не мала вероятность того, что таск умрет из за нехватки системных ресурсов. Это не война конечно, но то что мы потеряем все наши текущие данные и наш стек очистится — это точно. Кстати для избежания потери данных в таком случаи, вам стоит почитать про SavingActivityState.

Маленький итог

Управление тасками

Существует два пути для изменения стандартной организации тасков. Мы можем устанавливать специальные атрибуты в манифесте для каждой Activity. Также мы можем устанавливать специальные флаги для Intent, который запускает новую Activity с помощью startActivity(). Заметьте, что иногда атрибуты в манифесте и флаги в Intent могут противоречить друг другу. В этом случаи флаги Intent будут более приоритетны.

Атрибут launchMode

Для каждой Activity в манифесте можно указать атрибут launchMode. Он имеет несколько значений:

  • standard — (по умолчанию) при запуске Activity создается новый экземпляр в стеке. Activity может размещаться в стеке несколько раз
  • singleTop — Activity может распологаться в стеке несколько раз. Новая запись в стеке создается только в том случаи, если данная Activity не расположена в вершине стека. Если она на данный момент является вершиной, то у нее сработает onNewIntent() метод, но она не будет пересоздана
  • singleTask — создает новый таск и устанавливает Activity корнeвой для него, но только в случаи, если экземпляра данной Activity нет ни в одном другом таске. Если Activity уже расположена в каком либо таске, то откроется именно тот экземпляр и вызовется метод onNewIntent(). Она в свое время становится главной, и все верхние экземпляры удаляются, если они есть. Только один экземпляр такой Activity может существовать
  • singleInstance — тоже что и singleTask, но для данной Activity всегда будет создаваться отдельный таск и она будет в ней корневой. Данный флаг указывает, что Activity будет одним и единственным членом своего таска
Читайте также:  Наушники беспроводные apple earpods для андроид

На самом деле не важно, в каком таске открыта новая Activity. При нажатии кнопки back мы все равно вернемся на предыдущий таск и предыдущие Activity. Единственный момент, который нужно учитывать — это параметр singleTask. Если при открытии такой Activity мы достанем ее из другого background таска, то мы полностью переключаемся на него и на его стек. на картинке ниже это продемонстрировано.

Флаги

Как и говорил, мы можем устанавливать специальный флаги для Intent, который запускает новую Activity. Флаги более приоритетны, чем launchMode. Существует несколько флагов:

  • FLAG_ACTIVITY_NEW_TASK — запускает Activity в новом таске. Если уже существует таск с экземпляром данной Activity, то этот таск становится активным, и срабатываем метод onNewIntent().
    Флаг аналогичен параметру singleTop описанному выше
  • FLAG_ACTIVITY_SINGLE_TOP — если Activity запускает сама себя, т.е. она находится в вершине стека, то вместо создания нового экземпляра в стеке вызывается метод onNewIntent().
    Флаг аналогичен параметру singleTop описанному выше
  • FLAG_ACTIVITY_CLEAR_TOP — если экземпляр данной Activity уже существует в стеке данного таска, то все Activity, находящиеся поверх нее разрушаются и этот экземпляр становится вершиной стека. Также вызовется onNewIntent()

Affinity

Стандартно все Activity нашего приложения работают в одном таске. По желанию мы можем изменять такое поведение и указывать, чтобы в одном приложении Activity работали в разных тасках, или Activity разных приложений работали в одном. Для этого мы можем в манифесте для каждой Activity указывать название таска параметром taskAffinity. Это строковое значение, которое не должно совпадать с названием package, т.к. стандартный таск приложения называется именно как наш пакет. В общем случаи данный параметр указывает, что Activity будет гарантированно открываться в своём отдельном таске. Данный параметр актуален, если мы указываем флаг FLAG_ACTIVITY_NEW_TASK или устанавливаем для Activity атрибут allowTaskReparenting=«true». Этот атрибут указывает, что Activity может перемещаться между тасками, который её запустил и таском, который указан в taskAffinity, если один из них становится активным.

Чистка стека

Если таск долгое время находится в background, то система сама чистит его стек, оставляя только корневую Activity. Данное поведение обусловлено тем, что пользователь может забыть, что он делал в приложении до этого и скорее всего зашел в него снова уже с другой целью. Данная логика также может быть изменена с помощью нескольких атрибутов в манифесте.

  • alwaysRetainTaskState — если флаг установлен в true для корневой Activity, то стек не будет чиститься и полностью восстановится даже после длительного времени
  • clearTaskOnLaunch — если установить флаг в true для корневой Activity, то стек будет чиститься моментально, как только пользователь покинет таск. Полная противоположность alwaysRetainTaskState
  • finishOnTaskLaunch — работает аналогично clearTaskOnLaunch, но может устанавливаться на любую Activity и удалять из стека именно её

Это всё для данного топика. Статья не импровизированная, а по сути является вольным переводом официальной документации. Рекомендую собрать легкий пример и поэксперементировать с флагами и атрибутами. Некоторые моменты, лично для меня были, неожиданно интересными. любые ошибки и недоработки учту в лс. Спасибо.

Источник

Оцените статью