В приложении AP0003 так и осталось четыре активности A, B, C и D. Но их функционал и внешний вид несколько поменялся. Активность C имеет launcMode=”singleTask”. Активность D – launchMode="singleTop". Кроме того в Активности D была добавлена кнопка запуска Акитвности В в приложении AP0004.
В приложении AP0004 добавилась еще одна Активность Е со свойством launchMode="singleInstance".
Кроме того, я дописал код, который корректирует работу счетчика Активностей в задаче при убивании Активности D в приложении AP0003. Ну и еще много чего дописал.
Теперь к практике. Начнем с того момента где остановились в прошлый раз. Запускаем приложение AP0004.
Стрелочками отмечено то, на что следует обратить внимание. Теперь смотрим логи.
Теперь в скобках, как я и говорил, выводится номер задачи к которой принадлежит Активность.
Нажмем кнопку Info
Видим, что в задаче 9 сейчас одна Активность А. Тут все просто.
Жмем кнопку Start D AP0003
Теперь видим, что в задаче 9 две Активности: A и D. Активность А принадлежит приложению
AP0004, а Активность D – приложению AP0003. НО ОНИ В ОДНОЙ ЗАДАЧЕ 9.
Посмотрим логи.
Активность D была запущена в задаче 9 но в процессе приложения AP0003 с ID=1763. А у Активности А из которой она была запущена процесс ID=1813.
Жмем кнопку Info и смотрим логи.
И логов еще раз, подробнее, видно, что сейчас в нашей задаче 9 есть две Активности A и D. Активность D сейчас у нас на вершине стека. В прочем тут пока все как в прошлой практике.
Теперь введем какой-нибудь текст в Активности D, чтобы видеть будет ли он сохранен.
И жмем кнопку запустить Активность B AP0004.
Смотрим логи
Видим что Активность В была запущена в процессе приложения AP0004 с ID=1813. Жмем кнопку Info
И так, сейчас в нашей задаче 9 есть три Активности A-D-B. Активность D принадлежит приложению AP0003, а Активности A и B – приложению AP0004. Активность B сейчас на вершине стека. Так же стоит отметить что нажатие кнопки Info отрабатывается в процессе текущей Активности, что собственно логично. И еще запоминаем что процесс Активности D имеет значение 1763. Сейчас мы его будем убивать.
Жмем кнопку HOME и запускаем снова приложение ProcessView. Находим процесс 1763 приложения AP0003.
И убиваем его
Возвращаемся к нашему приложению AP0004
Теперь жмем кнопку ОБРАТНО, должна открыться Активность D, процесс которой мы убили.
Счетчик теперь работает правильно, благодаря изменениям в коде, которые я таки сподобился написать. Кроме того текст введенный нами тоже сохранился не смотря на то, что процесс Активности D был убит. Это говорит о том что объект Bundle, в котором сохраняются данные, привязан к задаче, а не процессу.
Теперь посмотрим логи
В начале данного скрина первые четыре строки мы видим отработку нажатия кнопки HOME и возврата к приложению. Затем в пятой строке логов нажатие кнопки ОБРАТНО. И происходи СОЗДАНИЕ Активности D. То есть срабатывает метод onCreate() вместо метода onRestart(), так как мы убили процесс Активности D. И создается Активность D уже в новом процессе с номером 1857, а старый был 1763, о чем нам собственно и докладывает наш код.
Но этот код работает только в том случае, если Активность D, запускается из другого приложения. Если же мы просто запустим приложение AP0003 и дойдем до Активности D, а затем убьем процесс приложения AP0003, то вместе с ним убьется и задача, а в месте с ней и объект Bundle.
Привету код Активности D приложения AP0003
package com.example.ap0003; import java.util.List; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; public class ActivityD extends Activity { final String TAG = "States"; TextView tvTextLife; List<ActivityManager.RunningTaskInfo> list; ActivityManager am; Integer TotalActCount; Boolean FirstStart; Boolean NextAct; static final String SaveMyPID = "MY_OLD_PID"; static final String SaveMyNextClick = "MY_NEXT_CLICK"; Integer SavedPID; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_d); setTitle(getResources().getString(R.string.app_name) + " | " + getLocalClassName() + " | TaskID: " + getTaskId()); Log.d(TAG, "ActivityD: onCreate("+getTaskId()+")"); // активность запущена впервые FirstStart = true; // кнопка запуска следующей Активности не нажималась NextAct = false; // определяем есть ли сохранненные данные if (savedInstanceState != null) { // Restore value of members from saved state Log.d(TAG, "ActivityD: onCreate("+getTaskId()+") NOT NULL: "); // сравниваем сохраненный и текущий PID SavedPID = savedInstanceState.getInt(SaveMyPID); if (SavedPID != android.os.Process.myPid()) { Log.d(TAG, "!!! Pocess AP0003 was killed !!!!"); Log.d(TAG, "Old PID: " + SavedPID); Log.d(TAG, "NEW PID: " + android.os.Process.myPid()); //коррекция счетчика если процесс приложения был убит FirstStart = false; //коррекция счетчика на запуск другой Активности if (savedInstanceState.getInt(SaveMyNextClick)==1){ NextAct=true; Log.d(TAG, "!!! NextAct=true !!!"); } } } else { // Probably initialize members with default values for a new // instance Log.d(TAG, "ActivityD: onCreate("+getTaskId()+") NULL"); } } @Override protected void onStart() { super.onStart(); Log.d(TAG, "ActivityD: onStart("+getTaskId()+")"); } @Override protected void onResume() { super.onResume(); Log.d(TAG, "ActivityD: onResume("+getTaskId()+")"); // получаем список 10 последних задач am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); list = am.getRunningTasks(10); // перебираем список задач и выбираем свою по TaskID for (RunningTaskInfo task : list) { if (task.id == getTaskId()) { // находим поле для вывода информации о количестве запущенных // Активностей tvTextLife = (TextView) findViewById(R.id.textActCountD); TotalActCount = task.numActivities; // коррекция счетчика для кнопки ДОМОЙ и ОБРАТНО if (NextAct == true & FirstStart == false) TotalActCount = TotalActCount - 1; // выводим количество Активностей в задаче tvTextLife.setText("Activites in task " + TotalActCount); // коррекция счетчика для кнопки ДОМОЙ NextAct = false; } } } @Override protected void onPause() { super.onPause(); // флаг что активность уже была запущена FirstStart = false; // находим текстовое поле по его идентификатору tvTextLife = (TextView) findViewById(R.id.textStateActD); // присваиваем значение атрибуту Text для выбранного TextView tvTextLife.setText("Этот экземпляр ActivityD уже был запущен!"); Log.d(TAG, "ActivityD: onPause("+getTaskId()+")"); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "ActivityD: onStop("+getTaskId()+")"); } @Override protected void onRestart() { super.onRestart(); Log.d(TAG, "ActivityD: onRestart("+getTaskId()+")"); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "ActivityD: onDestroy("+getTaskId()+")"); } @Override protected void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); // сохраняем значение PID savedInstanceState.putInt(SaveMyPID, android.os.Process.myPid()); Log.d(TAG, "ActivityD: onSave("+getTaskId()+") PID:" + android.os.Process.myPid()); //сохраняем нажатие запуска другой Активности if (NextAct==true){ savedInstanceState.putInt(SaveMyNextClick, 1); Log.d(TAG, "ActivityD: onSave("+getTaskId()+") NextAct=true"); } } public void onClickStartA(View v) { Intent intent = new Intent(ActivityD.this, ActivityA.class); startActivity(intent); // кнопка запуска следующей Активности была нажата NextAct = true; } public void onClickStartD(View v) { startActivity(new Intent(this, ActivityD.class)); } public void onClickStartB0004(View v) { startActivity(new Intent("AP0004_ActB")); NextAct = true; } public void onInfoClick(View v) { final String TAG = "States"; // получаем список 10 последних задач list = am.getRunningTasks(10); // перебираем список задач и выбираем свои по имени пакетов // com.example.ap000 for (RunningTaskInfo task : list) { if (task.baseActivity.flattenToShortString().startsWith( "com.example.ap000")) { // находим поле для вывода информации о количестве запущенных // Активностей Log.d(TAG, "------------------"); Log.d(TAG, "TaskID: " + task.id); Log.d(TAG, "Num: " + task.numActivities); Log.d(TAG, "Base: " + task.baseActivity.flattenToShortString()); Log.d(TAG, "Top: " + task.topActivity.flattenToShortString()); Log.d(TAG, "Thread ID: " + android.os.Process.myTid()); Log.d(TAG, "Process ID: " + android.os.Process.myPid()); Log.d(TAG, "------------------"); } } } }
Комментариев нет:
Отправить комментарий