Как имитировать Android, убивающий мой процесс

Android убьет процесс, если он находится в фоновом режиме, и ОС решит, что ему нужны ресурсы (ОЗУ, ЦП и т.д.). Мне нужно смоделировать это поведение во время тестирования, чтобы я мог убедиться, что приложение работает правильно. Я хочу, чтобы иметь возможность сделать это автоматическим способом, чтобы я мог проверить, работает ли приложение правильно, когда это происходит, а это значит, что мне придется тестировать это в каждом действии и т.д.

Я знаю, как убить мой процесс. Это не проблема. Проблема в том, что когда я убиваю свой процесс (используя DDMS, adb shell kill, Process.killProcess() и т.д.), Android не перезапускает его так же, как если бы Android-ОС убила его сама.

Если ОС Android убьет этот процесс (из-за требований к ресурсам), когда пользователь вернется в приложение Android, он воссоздает процесс, а затем воссоздает верхнюю активность в стеке действий (вызов onCreate()).

С другой стороны, если I убивает процесс, Android предполагает, что активность в верхней части стека действий была плохой,, поэтому он автоматически воссоздает процесс а затем удаляет верхнюю активность из стека активности и воссоздает активность, которая была под верхней активностью (вызов onCreate() `). Это не то поведение, которое я хочу. Я хочу, чтобы такое же поведение, как когда Android убивает процесс.

Просто для объяснения наглядно, если мой стек активности выглядит так:

    ActivityA -> ActivityB -> ActivityC -> ActivityD

Если Android убивает процесс, и пользователь возвращается к приложению, Android воссоздает процесс и создает ActivityD.

Если я убью этот процесс, Android воссоздает процесс и создаст ActivityC.

Ответ 1

Лучший способ проверить это для меня - сделать это:

  • Откройте ActivityD в вашем приложении
  • Нажмите кнопку "Домой"
  • Нажмите Terminate Application в окне Logcat в Android Studio (это приведет к остановке процесса приложения, убедитесь, что вы выбрали свое устройство и процесс в раскрывающихся списках Logcat вверху)
  • Вернитесь в приложение, нажав и удерживая Home, или открыв приложения (зависит от устройства)
  • Приложение запустится в воссозданном ActivityD (ActivityA, ActivityB, ActivityC мертвы и будут воссозданы, когда вы вернетесь к ним)

На некоторых устройствах вы также можете вернуться к приложению (ActivityD) с помощью Приложения → Значок запуска, но на других устройствах вместо этого будет запускаться ActivityA.

Вот что говорят об этом Android-документы:

Обычно система очищает задачу (удаляет все действия из стека выше корневого действия) в определенных ситуациях, когда пользователь повторно выбирает эту задачу на главном экране. Как правило, это делается, если пользователь не посещал задание в течение определенного времени, например 30 минут.

Ответ 2

Кажется, это работает для меня:

adb shell am kill <package_name>

Это отличается от adb shell kill, упомянутого OP.

Обратите внимание, что справка для команды am kill говорит:

am kill: Kill all processes associated with <PACKAGE>.  Only kills.
  processes that are safe to kill -- that is, will not impact the user
  experience.

Таким образом, он не будет убивать процесс, если он находится на переднем плане. Это похоже на работу OP, если я уйду от своего приложения, а затем запустите adb shell am kill <package_name>, он убьет приложение (я подтвердил это с помощью ps на устройстве). Затем, если я вернусь к приложению, я вернусь к той активности, в которой я был ранее - то есть в примере OP процесс воссоздается и создает ActivityD (а не ActivityC, как кажется, срабатывает большинство других методов убийства).

Жаль, что я на пару лет опаздываю на ОП, но, надеюсь, другие найдут это полезным.

Ответ 3

Другой метод, возможно, тот, который доступен для сценариев, поскольку для него не требуется DDMS:

Одноразовая настройка: перейдите в "Параметры разработчика", выберите "Настройка ограничения фонового процесса", измените значение "Стандартный лимит" на "Нет фоновых процессов".

Когда вам нужно перезапустить процесс, нажмите кнопку "Домой". Процесс будет убит (вы можете проверить в logcat/Android Monitor в студии - процесс будет отмечен [DEAD]). Затем вернитесь к приложению, используя переключатель задач.

Ответ 4

Этот вопрос старый, но есть ответ на этот вопрос, который не требует adb, Android Studio и т.д. Единственное требование - API 23 или более поздняя версия.

Чтобы имитировать перезапуск приложения по ОС, перейдите в настройки приложения во время его работы, отключите (затем вы можете включить) разрешение и верните приложение из последних приложений. Когда разрешение отключено, ОС убивает приложение, но сохраняет сохраненные состояния экземпляра. Когда пользователь возвращает приложение, приложение и последнее действие (с сохраненным состоянием) воссоздаются.

Метод "без фоновых процессов" иногда вызывает то же поведение, но не всегда. Например, если приложение запускает фоновую службу, "Нет фоновых процессов" ничего не делает. Но приложение может быть убито системой, включая ее сервисы. Метод разрешения работает, даже если приложение имеет сервис.

Пример:

Наше приложение имеет два вида деятельности. ActivityA - это основная деятельность, которая запускается с панели запуска. ActivityB запускается из ActivityA. Я покажу только методы onCreate, onStart, onStop, onDestroy. Android всегда вызывает onSaveInstanceState перед вызовом onStop, поскольку активность, находящаяся в состоянии остановки, может быть прервана системой. [ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]

Метод разрешения:

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop (the order is like this, it is stopped after new one is started)
<go settings>
ActivityB onStop
<disable a permission>
//Application is killed, but onDestroy methods are not called.
//Android does not call onDestroy methods if app will be killed.
<return app by recent apps>
Application onCreate (this is the important part. All static variables are reset.)
ActivityB onCreate WITH savedInstance (user does not notice activity is recreated)
//Note that ActivityA is not created yet, do not try to access it.
ActivityB onStart
<return ActivityA by back>
ActivityA onCreate WITH savedInstance (user does not notice activity is recreated)
ActivityA onStart
ActivityB onStop
ActivityB onDestroy
<press back again, return launcher>
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart

Я хочу сравнить другие методы, которые упоминаются в других ответах.

Не сохранять действия: это не убивает приложение.

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop
ActivityA onDestroy (do not keep)
<return launcher by home button>
ActivityB onStop
ActivityB onDestroy (do not keep) 
<retun app from recent apps>
// NO Application onCreate
ActivityB onCreate WITH savedInstance (user does not notice activity recreated)
ActivityB onStart
<return ActivityA by back>
ActivityA onCreate WITH savedInstance (user does not notice activity recreated)
ActivityA onStart
ActivityB onStop
ActivityB onDestroy
<press back again, return launcher>
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart

Метод принудительной остановки: не сохраняет сохраненные состояния экземпляра

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop
<go settings>
ActivityB onStop
<force stop, return app from recent apps>
Application onCreate
ActivityA onCreate WITHOUT savedInstance 
//This is important part, app is destroyed by user.
//Root activity of the task is started, not the top activity.
//Also there is no savedInstance.

Ответ 5

Я очень опоздал на вечеринку, и несколько человек до меня дали тот же правильный ответ, но для упрощения для тех, кто придет за мной, просто нажмите кнопку "Домой" и выполните команду:

adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill

Приложение не потеряет свое состояние, и, по моему собственному опыту, оно работает так же, как ОС убивало приложение в фоновом режиме. Это работает только для отладки встроенных приложений

Ответ 6

Так вы делаете это в Android Studio.

  • Подключите ваше устройство в режим отладки к вашему компьютеру.
  • Откройте приложение на своем устройстве и перейдите к любой активности, которую вы хотите протестировать, "Вернитесь к ней из мертвых".
  • Нажмите кнопку "Главная" на вашем устройстве.
  • В Android Studio перейдите в Android Monitor → Мониторы и нажмите значок "Завершить приложение".
  • Теперь вы можете либо вернуться в свое приложение через последние приложения, либо щелкнув значок запуска, поведение было таким же в моих тестах.

Ответ 7

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

Ответ 8

Вы можете сделать следующие шаги для воспроизведения искаженного поведения:

  • Откройте приложение, перейдите к верхней активности
  • Используйте панель уведомлений для перехода к любому другому полноэкранному приложению (например, к системным настройкам - в правом верхнем углу).
  • Убейте свой прикладной процесс
  • Нажмите кнопку возврата

Ответ 9

Поместите приложение в фоновом режиме с помощью кнопки HOME

Выберите свой процесс в режиме "Logcat" в Android Studio, затем нажмите "Завершить приложение" в нижнем левом углу.

Теперь запустите ваше приложение из панели запуска на устройстве Android


РЕДАКТИРОВАТЬ: Согласно Интернету, следующее также работает:

 adb shell am kill [my-package-name]

Ответ 10

Всем,    Я просто хотел сообщить вам об этом документе, который нашел:

http://developer.android.com/tools/testing/activity_testing.html

Я не могу сказать со 100% уверенностью, что здесь есть метод kill точно так же, как Android, но это начало. Вы можете имитировать многие части жизненного цикла деятельности здесь, чтобы вы могли имитировать убийство процесса.

Также есть учебник: http://developer.android.com/tools/testing/activity_test.html#StateManagementTests

Надеюсь, это поможет. Приветствия

Ответ 11

Нажмите кнопку "Домой" и сначала установите приложение в фоновом режиме. Затем остановить или убить процесс из DDMS или ADB.

Ответ 12

Корень вашей проблемы кажется, что ваш Activity находится на переднем плане, когда вы убиваете процесс.

Это можно увидеть, нажав на остановку в DDMS, когда отображается Activity (точно так, как вы описали), и сравниваете это с нажатием кнопки "Стоп после дома" и позже возвращаетесь в приложение.

Просто убедитесь, что moveTaskToBack(true) как-то в ваших тестах.

Ответ 13

Я не уверен, что это тот ответ, который вы ищете, это больше похоже на логику.

Я не думаю, что вы действительно можете сделать полностью автоматизированный тест, единственный способ имитировать его, это будет воссоздать его, у AKA есть так много действий, что Android убьет ваше приложение.

Итак, моя идея или предложение - сделать еще одно маленькое приложение, которое продолжает появляться в новых действиях, до тех пор, пока у Android не хватит памяти и начнет убивать процесс в фоновом режиме.

Что-то в строке:

Начать работу я → Проверить запущенный процесс, если приложение находится в списке, увеличить я и перезапустить цикл, не закрывая текущую активность, else → уменьшить я и закрыть текущую активность, вернуться к предыдущей и перепроверять...

Ответ 14

Вы также можете подключиться к своему устройству/эмулятору с терминала с помощью adb shell, затем получить PID вашего процесса с помощью ps | grep <your_package_name и выполнить kill -9 <pid>. Затем откройте свое свернутое приложение из недавнего приложения, и он перезапустит последнюю активность.

Ответ 15

Кажется, вы хотите протестировать onSaveInstanceState и onRestoreInstanceState.

Тестирование на реальном устройстве: взгляните на SetAlwaysFinish. p >

Тестирование в эмуляторе: checkout Немедленно уничтожить опцию действий в Dev Tools App в эмуляторе Android.