В приложении 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, "------------------");
}
}
}
}
Комментариев нет:
Отправить комментарий