Android on task completed

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:

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)

Читайте также:  Альтернатива aida64 для андроид

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:

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.

Источник

Полный список

— немного теории по Task
— фиксируем Activity в состоянии Paused

В этом уроке узнаем, куда помещается Activity, пока его не видно. И откуда оно достается при нажатии кнопки назад. В хелпе об этом написано достаточно понятно. Я сделаю краткий перевод основной части этого хелпа и использую их схемы.

Мы уже знаем, что приложение может содержать несколько Activity. И что Activity умеет вызывать Activity из других приложений с помощью Intent и Intent Filter. Если вы хотите отправить письмо из вашего приложения, вы вызываете Activity почтовой программы и передаете ей данные. Письмо уходит и вы возвращаетесь в ваше приложение. Создается ощущение, что все это происходило в рамках одного приложения. Такая «бесшовность» достигается за счет того, что оба Activity (ваше и почтовое) были в одном Task.

Прежде, чем продолжу объяснять, хочу сразу привести аналогию, чтобы тему легче было понять. В скобках я буду давать понятия-аналоги из Android.

Механизм организации Activity в Android очень схож по реализации с навигацией в браузере. Вы находитесь в одной вкладке(Task) и открываете страницы (Activity) переходя по ссылкам (Intent). В любой момент можете вернуться на предыдущую страницу, нажав кнопку Назад. Но кнопка Вперед отсутствует, т.к. страница, на которой была нажата кнопка Назад, стирается из памяти. И надо снова нажимать ссылку, если хотим попасть на нее. Если вам надо открыть что-то новое, вы создаете новую вкладку и теперь уже в ней открываете страницы, переходите по ссылкам, возвращаетесь назад. В итоге у вас есть несколько вкладок. Большинство из них на заднем фоне, а одна (активная, с которой сейчас работаете) – на переднем.

В итоге список аналогий браузера и Android таков:

Теперь вам будет более понятен текст про Task.

Task – группа из нескольких Activity, с помощью которых пользователь выполняет определенную операцию. Обычно стартовая позиция для создания Task – это экран Домой (Home).

Находясь в Home вы вызываете какое-либо приложение из списка приложений или через ярлык. Создается Task. И Activity приложения (которое отмечено как MAIN в манифест-файле) помещается в этот Task как корневое. Task выходит на передний фон. Если же при вызове приложения, система обнаружила, что в фоне уже существует Task, соответствующий этому приложению, то она выведет его на передний план и создавать ничего не будет.

Читайте также:  Nfs для андроид не работает

Когда Activity_A вызывает Activity_B, то Activity_B помещается на верх (в топ) Task и получает фокус. Activity_A остается в Task, но находится в состоянии Stopped (его не видно и оно не в фокусе). Далее, если пользователь жмет Back находясь в Activity_B, то Activity_B удаляется из Task и уничтожается. А Activity_A оказывается теперь на верху Task и получает фокус.

В каком порядке открывались (добавлялись в Task) Activity, в таком порядке они и содержатся в Task. Они никак специально не сортируются и не упорядочиваются внутри. Набор Activity в Task еще называют back stack. Я буду называть его просто — стэк.

Схема (с офиц.сайта) демонстрирует пример:

В верхней части то, что видит пользователь. В нижней – содержимое Task. Видно, как при вызове новых Activity они добавляются в верх стэка. А если нажата кнопка Назад, то верхнее Activity из стэка удаляется и отображается предыдущее Activity.

Допустим у нас есть Task с несколькими Activity. Он на переднем фоне, мы с ним работаем сейчас.

— если мы нажмем кнопку Home, то ничего не будет удалено, все Activity сохранятся в этом Task-е, а сам Task просто уйдет на задний фон и его всегда можно будет вызвать оттуда, снова вызвав приложение, Activity которого является корневым для Task-а. Либо можно удерживать кнопку Home и мы увидим как раз список Task-ов, которые расположены на заднем фоне.

— если же в активном Task-е несколько раз нажимать кнопку Назад, то в итоге в стэке не останется Activity, пустой Task будет удален и пользователь увидит экран Home.

Там еще как всегда куча нюансов и сложностей, но мы пока остановимся на этом и в дебри не полезем. Этих знаний вполне хватит, чтобы ответить на вопросы предыдущего урока: почему на шаге 2 MainActivity исчезло с экрана, но осталось висеть в памяти и не было уничтожено? Ведь на шаге 3 было уничтожено ActivityTwo после того, как оно пропало с экрана. А на шаге 4 было в итоге уничтожено и MainActivity. Почему шаг 2 стал исключением?

Теперь вы знаете, почему. Потому, что на шаге 2 MainActivity осталось в стэке, а ActivityTwo вставилось на верх стэка и получило фокус. Ну а на шаге 3 и 4 были удалены Activity из верха стэка, в Task не осталось Activity, и мы увидели экран Home.

Если бы мы на шаге 3 нажали не Back, а Home, то Task с обоими Activity ушел бы задний фон и ничего не было бы уничтожено.

Paused

Теперь давайте откроем проект с прошлого урока P0241_TwoActivityState. Мы хотели поймать состояние Paused для Activity. Это состояние означает, что Activity не в фокусе, но оно видно, пусть и частично. Мы можем этого добиться, если присвоим диалоговый стиль для ActivityTwo. Оно отобразится как всплывающее окно и под ним будет частично видно MainActivity – оно и будет в статусе Paused. Давайте реализуем.

Для этого открываем AndroidManifest.xml, вкладка Application, находим там ActivityTwo и справа в поле Theme пишем такой текст: @android:style/Theme.Dialog

Все сохраняем и запускаем приложение.

MainActivity: onCreate()
MainActivity: onStart()
MainActivity: onResume()

MainActivity: onPause()
ActivityTwo: onCreate()
ActivityTwo: onStart()
ActivityTwo: onResume()

Видим, что не был вызван метод onStop для MainActivity, а значит приложение не было переведено в состояние Stopped и находится в режиме Paused.

ActivityTwo: onPause()
MainActivity: onResume()
ActivityTwo: onStop()
ActivityTwo: onDestroy()

MainActivity восстановилось одним лишь вызовом onResume, а onStart не понадобился, т.к. оно было в состоянии Paused, а не Stopped.

Мы четко увидели разницу между этим примером и им же на прошлом уроке. И MainActivity у нас был в состоянии Paused.

Далее можно нажать Back, а можно Home — вы уже знаете, что произойдет в обоих случаях. По логам можно убедиться в этом.

Читайте также:  Что бы шел андроид сан андреас

Чтобы вернуть ActivityTwo нормальный режим отображения, зайдите снова в манифест и удалите строку из поля Theme.

Кстати, у вас уже вполне достаточно знаний, чтобы создать приложение с кучей Activity, прописать вызовы и поиграться, посмотреть логи. Тем самым закрепите темы LifeCycle и Task.

На следующем уроке:

— вызываем Activity используя неявный вызов и Intent Filter

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

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.

Источник

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