197

Androidは、プロセスがバックグラウンドにあり、OSがリソース(RAM、CPUなど)が必要であると判断した場合、プロセスを強制終了します。アプリケーションが正しく動作していることを確認できるように、テスト中にこの動作をシミュレートできる必要があります。自動化された方法でこれを実行できるようにしたいので、これが発生するたびにアプリケーションが正しく動作するかどうかをテストできます。つまり、すべてのアクティビティなどでこれをテストする必要があります。

私は自分のプロセスを殺す方法を知っています。それは問題ではありません。問題は、(DDMS 、、などを使用して)プロセスを強制終了するとadb shell killProcess.killProcess()AndroidOSがそれ自体を強制終了した場合と同じようにAndroidが再起動しないことです。

Android OSがプロセスを強制終了した場合(リソース要件のため)、ユーザーがアプリケーションに戻ったときに、Androidはプロセスを再作成してから、アクティビティスタックの最上位のアクティビティを再作成します(呼び出しonCreate())。

一方、プロセスを強制終了すると、Androidはアクティビティスタックの一番上のアクティビティが不正な動作をしたと見なすため、プロセスを自動的に再作成してから、アクティビティスタックから一番上のアクティビティを削除し、その下にあったアクティビティを再作成します。最上位のアクティビティ(onCreate() `の呼び出し)。これは私が望む振る舞いではありません。Androidがプロセスを強制終了するときと同じ動作が必要です。

絵で説明するために、私のアクティビティスタックが次のようになっている場合:

    ActivityA -> ActivityB -> ActivityC -> ActivityD

Androidがプロセスを強制終了し、ユーザーがアプリケーションに戻ると、Androidはプロセスを再作成し、ActivityDを作成します。

プロセスを強制終了すると、Androidはプロセスを再作成し、ActivityCを作成します。

4

14 に答える 14

151

私にとってこれをテストする最良の方法は、これを行うことでした:

  • アプリケーションで ActivityD を開く
  • ホームボタンを押します
  • Terminate ApplicationAndroid Studio の Logcat ウィンドウを押します (これによりアプリ プロセスが強制終了されます。上部の Logcat ドロップダウンでデバイスとプロセスを選択していることを確認してください)。
  • ホームの長押しまたは開いているアプリでアプリに戻ります (デバイスによって異なります)。
  • アプリケーションは再作成された ActivityD で開始されます (ActivityA、ActivityB、ActivityC は無効であり、それらに戻ったときに再作成されます)

一部のデバイスでは、[アプリケーション] -> [ランチャー アイコン] を使用してアプリケーション (ActivityD) に戻ることもできますが、他のデバイスでは代わりに ActivityA が開始されます。

これは、Androidのドキュメントがそれについて言っていることです:

通常、ユーザーがホーム画面からそのタスクを再選択すると、システムは特定の状況でタスクをクリアします (ルート アクティビティの上のスタックからすべてのアクティビティを削除します)。通常、これは、ユーザーが一定時間 (30 分間など) タスクにアクセスしていない場合に行われます。

于 2013-09-09T10:14:10.937 に答える
67

これは私にとってはうまくいくようです:

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.

そのため、フォアグラウンドにある場合、プロセスを強制終了しません。これは、アプリから離れて移動すると、実行adb shell am kill <package_name>するとアプリが強制終了されるという点で、OPが望んでいたように機能するようです(デバイスで使用してこれを確認しpsました)。次に、アプリに戻ると、以前のアクティビティに戻ります。つまり、OPの例では、プロセスが再作成され、ActivityDが作成されます(他のほとんどの殺害方法がトリガーされるように見えるActivityCではなく)。

申し訳ありませんが、私はOPに数年遅れていますが、うまくいけば、他の人がこれを役に立つと思うでしょう.

于 2014-11-12T15:13:01.623 に答える
15

この質問は古いですが、adb、Android Studio などを必要としないこの質問に対する回答があります。唯一の要件は API 23 以降です。

OS によるアプリの再起動をシミュレートするには、アプリの実行中にアプリの設定に移動し、アクセス許可を無効にして (その後、有効にすることができます)、最近のアプリからアプリを返します。アクセス許可が無効になっている場合、OS はアプリを強制終了しますが、保存されたインスタンスの状態は保持します。ユーザーがアプリを返すと、アプリと最後のアクティビティ (保存された状態) が再作成されます。

「バックグラウンド プロセスなし」メソッドは、同じ動作を引き起こす場合がありますが、常にではありません。たとえば、アプリがバックグラウンド サービスを実行している場合、「バックグラウンド プロセスなし」は何もしません。ただし、アプリは、そのサービスを含むシステムによって強制終了される可能性があります。アプリにサービスがある場合でも、許可方法は機能します。

例:

アプリには 2 つのアクティビティがあります。ActivityA は、ランチャーから開始されるメイン アクティビティです。ActivityB は ActivityA から開始されます。onCreate、onStart、onStop、onDestroy メソッドのみを示します。Android は常に onStop を呼び出す前に onSaveInstanceState を呼び出します。これは、停止状態のアクティビティがシステムによって強制終了される可能性があるためです。[ 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.
于 2017-03-19T15:18:32.777 に答える
9

私はパーティーに非常に遅れており、私の前のいくつかは同じ正解を出しましたが、私の後に来る人のために簡単にするために、ホームボタンを押して次のコマンドを実行してください:

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

アプリは状態を失うことはありません。私自身の経験から、これは OS がバックグラウンドでアプリを強制終了したのと同じように機能します。これは、ビルドされたアプリケーションをデバッグする場合にのみ機能します

于 2016-11-24T10:06:53.437 に答える
1

を使用して端末からデバイス/エミュレーターに接続し、 を使用しadb shellてプロセスの PID を取得しps | grep <your_package_nameて実行することもできkill -9 <pid>ます。次に、最近のアプリ ピッカーから最小化されたアプリを開くと、最後のアクティビティが再開されます

于 2016-03-10T08:48:10.190 に答える
0

これがあなたが探している答えかどうかはわかりません。論理的な考え方に似ています。

完全に自動化されたテストを実際に作成できるとは思いません。それをシミュレートする唯一の方法は、それを再作成することです。AKAには非常に多くのアクティビティがあり、Androidがアプリケーションを強制終了します。

したがって、私のアイデアまたは提案は、Android がメモリを使い果たし、バックグラウンドでプロセスを強制終了し始めるまで、新しいアクティビティをポップアップし続ける別の小さなアプリを作成することです。

行の中の何か:

アクティビティ i を開始 -> アプリがリストにある場合は実行中のプロセスを確認し、i を増やして現在のアクティビティを閉じずにループを再開します。それ以外の場合 -> i を減らして現在のアクティビティを閉じ、前に戻って再確認します...

于 2014-02-11T22:07:11.753 に答える
0

あなたの問題の根本はActivity、プロセスを強制終了するときにあなたがフォアグラウンドにいることです。

これは、 が表示されているときに DDMS で停止を押すことで確認できActivityます (まさにあなたが説明したとおりに発生します)。

moveTaskToBack(true)テストで何とかしてください。

于 2013-05-21T21:29:13.160 に答える