Задача и процесс Android, SingleTask и SingleInstance

Я прочитал страницу Google Android Developer, но концепция задачи (http://developer.android.com/guide/components/tasks-and-back-stack.html) меня действительно смущают.

После того, как я дочитал до SingleTask и SingleInstance, я еще больше запутался.

Я хотел бы задать вопрос, используя примеры, надеюсь, что у меня будет лучшее понимание этого вопроса:

Допустим, у меня есть 2 приложения A и B, A имеет действия x, y, z; B имеет 1, 2, 3 активности:

Предположим, что их режим запуска является стандартным (без использования флага намерения). И x - это основное действие приложения A; 1 – основное действие приложения Б.

1) Запустите приложение А, затем x-> y -> 1, нажмите кнопку домой, снова запустите приложение A, мы увидим активность y или 1?

2) Запустите приложение A, затем x -> 1 -> y -> 2 -> z -> 3, нажмите кнопку «Домой», запустите приложение A, оно будет содержать все действия (x -> 1 -> y -> 2 -> z -> 3), или он содержит только x -> y -> z? Как насчет того, чтобы запустить приложение B сейчас? Какие действия будут содержаться в приложении Б?

Теперь предположим, что действия 1, 2 и 3 являются однозадачными; x,y,z остаются стандартными:

3) Запустите приложение A, затем x -> y -> 1 -> 2, нажмите кнопку «Домой», запустите приложение A, оно будет содержать только x -> y или оно содержит x -> y -> 1 -> 2? Как насчет того, чтобы запустить приложение B сейчас? приложение B будет содержать только 1 или 1 -> 2?

4) Запустите приложение B, затем 1 -> 2 -> 3 -> 1, будут ли уничтожены 2 и 3?

5) Запустите приложение B, затем 1 -> 2 -> 3, нажмите кнопку «Домой», запустите приложение A сейчас, затем x -> y -> 2, затем нажмите кнопку «Назад», чтобы удалить 2. Запустите приложение B сейчас, какие действия оно содержит? Только 1 -> 3 или 1 -> 2 -> 3?

Спасибо, кто ответит и поможет!


person Sam YC    schedule 04.09.2013    source источник


Ответы (1)


Предположим, что их режим запуска является стандартным (без использования флага намерения). И x - это основное действие приложения A; 1 — основная активность приложения B.

1) Запустите приложение А, затем x-> y -> 1, нажмите кнопку домой, снова запустите приложение A, мы увидим активность y или 1?

Вы увидите активность 1. У вас есть одна задача, содержащая x->y->1 с действием 1 в верхней части стека действий в этой задаче. Когда вы нажимаете ДОМОЙ, эта задача перемещается на задний план. Когда вы снова запускаете приложение, Android находит стек задач и просто возвращает его (неповрежденным) на передний план, показывая вам верхнюю активность в стеке (в данном случае 1).

2) Запустите приложение A, затем x -> 1 -> y -> 2 -> z -> 3, нажмите кнопку «Домой», запустите приложение A, оно будет содержать все действия (x -> 1 -> y -> 2 -> z -> 3), или он содержит только x -> y -> z?

Как и выше, у вас есть одна задача. Когда вы нажимаете HOME, задача содержит x->1->y->2->z->3 и перемещается на задний план. Когда вы снова запустите приложение A, задача будет перенесена (без изменений), и вы увидите активность 3 сверху.

Как насчет того, чтобы запустить приложение B сейчас? Какие действия будут содержаться в приложении B?

Ну вопрос как таковой некорректен. Что вы действительно хотите знать, так это "Какие действия будут содержаться в этой задаче?", но вот ответ:

Если вы запустите приложение B с экрана HOME, вы начнете новую задачу. Эта задача будет содержать одно действие, а именно 1. Эта задача не имеет ничего общего с другой задачей (которая все еще находится в фоновом режиме). Тот факт, что фоновая задача содержит действия из двух разных приложений, не имеет значения.

Теперь предположим, что действия 1, 2, 3 являются SingleTask; x,y,z по-прежнему Стандарт:

3) Запустите приложение A, затем x -> y -> 1 -> 2, нажмите кнопку «Домой», запустите приложение A, оно будет содержать только x -> y или оно содержит x -> y -> 1 -> 2?

В момент, когда действие y запускает действие 1, будет создана новая задача. Таким образом, у вас будет одна задача, содержащая действие x->y, и вторая задача, содержащая 1. Когда действие 1 запускает действие 2, то, что происходит, зависит не только от launchMode действий. Даже если действие 2 объявлено launchMode="singleTask", если taskAffinity действия 2 совпадает с taskAffinity действия 1 (что по умолчанию так и есть, если они принадлежат одному и тому же приложению), то действие 2 будет создано в той же задаче. как действие 1 (т. е. оно будет вести себя так, как если бы действие 2 имело launchMode="standard"). Однако если активность 1 и активность 2 имеют разные taskAffinity, то активность 2 будет запущена как корневая активность в новой задаче. Теперь у вас будет 3 задачи, например: Task1 содержит x->y, Task2 содержит 1 и Task3 содержит 2.

Как насчет того, чтобы запустить приложение B сейчас? приложение B будет содержать только 1 или 1 -> 2?

Как и выше, это зависит от taskAffinity. Если taskAffinity действия 1 и 2 совпадают, запуск приложения B с экрана HOME выведет задачу, содержащую 1->2, на передний план. Если taskAffinity действий отличается, запуск приложения B с экрана HOME выведет задачу, содержащую действие 1, на передний план.

4) Запустите приложение B, затем 1 -> 2 -> 3 -> 1, будут ли уничтожены 2 и 3?

2 и 3 не будут уничтожены. Предполагая, что 1, 2 и 3 все имеют launchMode="singleTask", тогда это (опять же) зависит от настроек taskAffinity. Предполагая, что все действия имеют одинаковый taskAffinity, тогда у вас будет одна задача, содержащая 1->2->3->1 (у вас будет 2 экземпляра действия 1), потому что taskAffinity превосходит launchMode.

Если у всех действий разные taskAffinity, то после 1->2->3 у вас будет 3 отдельных задания, каждое из которых содержит одно действие. Затем, когда действие 3 запускает действие 1, задача, содержащая действие 1, просто выводится на передний план, а не создается новый экземпляр действия 1.

5) Запустите приложение B, затем 1 -> 2 -> 3, нажмите кнопку «Домой», запустите приложение A сейчас, затем x -> y -> 2, затем нажмите кнопку «Назад», чтобы удалить 2. Запустите приложение B сейчас, какие действия оно содержит? Только 1 -> 3 или 1 -> 2 -> 3?

Опять же, это зависит от taskAffinity. Если все действия приложения B имеют одинаковые taskAffinity, то после 1->2->3 у вас будет одна задача. Пользователь нажимает кнопку HOME, эта задача переходит в фоновый режим. Теперь пользователь запускает приложение A, создавая новую задачу. После x->y вторая задача содержит эти 2 действия. Теперь действие y запускает действие 2. Поскольку это действие имеет launchMode="singleTask" и taskAffinity отличается от других действий в задаче (все они имеют taskAffinity приложения A), Android создаст новую задачу с действием 2 в качестве корня. Android не может использовать существующую задачу, содержащую 1->2->3, поскольку эта задача не содержит активности 2 в качестве корня. Когда пользователь нажимает НАЗАД в 2, это завершает действие 2, которое завершает третью задачу, возвращая пользователя ко второй задаче, содержащей x->y с действием y сверху. Теперь, нажав ДОМОЙ и запустив приложение B, существующая первая задача, содержащая 1->2->3, будет переведена на передний план.

Однако, если все действия приложения B имеют разные taskAffinity, то после 1->2->3 у вас будет 3 отдельных задачи, каждая из которых содержит одно действие. Пользователь нажимает ДОМОЙ и запускает приложение А, создавая новую задачу (теперь у вас есть 4 задачи). После x->y четвертая задача содержит эти 2 действия. Теперь действие y запускает действие 2. Android просто выводит задачу, содержащую активность 2, на передний план. Пользователь нажимает кнопку НАЗАД, это завершает действие 2 и задачу, в которой оно было (поскольку эта задача теперь пуста), возвращая пользователя к предыдущей задаче, которая содержит x->y из приложения A. Запуск приложения B с экрана HOME просто выведите задачу, содержащую действие 1, на передний план. Теперь у вас есть 3 задачи: Задача1 содержит действие 1 и находится на переднем плане, Задача2 содержит действие 3 и находится в фоновом режиме, Задача3 содержит действие x->y и находится в фоновом режиме.

ПРИМЕЧАНИЯ

Я понимаю, что это сложно. Мой ответ исходит из моей головы, я не пытался на самом деле реализовать все эти комбинации и проверки (однако я реализовал многие из этих случаев в прошлом, и я знаю, как это действительно работает). Причина в том, что большая часть того, что вы описали, не будет выполняться в реальном мире, поэтому примеры носят только теоретический, а не практический характер. В реальной жизни вам вряд ли понадобится использовать режимы запуска singleTask или singleInstance, если только вы не создаете собственную замену HOME-экрану или вам не нужно тщательно контролировать поведение вашего приложения, когда оно запускается другими приложениями. . В большинстве случаев у вас никогда не будет более одного действия с режимом запуска singleTask или singleInstance.

Если вы используете singleInstance или singleTask, вам нужно знать, как работает taskAffinity, а также убедиться, что у вас есть другой значок приложения (и, возможно, также метка приложения) для каждого действия, объявленного как «singleTask» или «singleInstance». . В противном случае пользователь не сможет вернуться к нужной задаче из-за того, как они отображаются в списке недавних задач.

person David Wasser    schedule 04.09.2013
comment
Это абсолютно отличный ответ! Очень подробно и закончено! Я впервые слышу о том, что taskAffinity играет такую ​​важную роль с singleTask и singleInstance. Большое спасибо за то, что поделились опытом! - person Sam YC; 05.09.2013
comment
Если я запускаю действие B из A (как из того же приложения, так и с привязкой к задачам по умолчанию) с намерением, имеющим флаг ACTIVITY_NEW_TASK, оно запустит действие B в той же задаче, что и A, или в другой задаче? - person pratim; 28.08.2014
comment
Ответ для 4 неверный, 2 и 3 будут уничтожены (я проверял этот вопрос в эмуляторе). - person floating cat; 14.03.2018