私は疑問に思っています:アプリが強制終了されるとき、Android は現在実行中の関数が戻るのを待つのですか、それとも Android がそれ自体で終了する前にそれを停止しますか?
7 に答える
OSは、すべてのスレッドのすべての「関数」を使用して、JVMプロセスを強制終了します。実際には、メソッドがトランザクションであると想定するべきではありません。代わりに、いつでも終了できると想定し、適切に設計する必要があります。
更新: テスト後、Android は現在実行中のすべてのスレッド/AsynTask を強制終了します (onPostExecute()/onCancelled() を呼び出さずに);
アプリケーションを正常に閉じた場合。UIスレッドは停止しますが、メソッドを Thread / AsyncTask / Service に実装すると、終了するまで実行され続けます。
ただし、Thread / AsyncTask は引き続き実行される可能性がありますが、アプリケーションのインスタンスのコールバックがある場合、またはアプリケーションの UI に対して何かを行う場合、完全に機能する場合と機能しない場合があります。これにより、実行されている内容に応じて例外が発生する場合があります。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Thread(new Runnable() {
@Override
public void run() {
try {
int i = 0;
while (true) {
i++;
Thread.sleep(2000);
Log.i("not dead", "not dead" + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
このコードを実行して、いくつかのゲームをプレイしてください。その結果、スレッドはシステムによって強制終了されました。
アプリは、そのコードの別の行が実行されることなく、いつでもシステムによって強制終了される可能性があります。ただし、ドキュメントによると、「killable」ではないメソッドがいくつかあります。
- onCreate()
- onRestart()
- onStart()
- onResume()
- onPause()
onDestroy() が確実に呼び出されるわけではないため、onPause()メソッドを使用して永続データをストレージに書き込む方が節約になります。
protected void onPause(){
super.onPause();
if(isFinishing()){
// store data
}
}
各Androidアプリは、個別のDalvikVMで実行されます。Androidがそのアプリを強制終了すると、そのVMインスタンスが破棄されます。使用しているスレッドやスレッドが何をしているのかを気にしない場合は、クライアントが接続してアプリを強制終了するまでブロックするtcpサーバーソケットを作成することで、簡単にテストできます。何も起こらず、割り込み例外が発生しません。 VMインスタンス自体が強制終了されるためです。
Android はいつでもどこでもアプリを強制終了できます。しかし、Android は、アプリに十分なリソースがある場合、またはフォアグラウンド アクティビティまたはサービスがある場合、アプリを実行し続けようとします。
アプリを強制終了する前に、Android は SDK ドキュメントに従ってコンポーネントのライフサイクル メソッドを呼び出します。すべてのライフサイクル メソッドが呼び出されることが保証されているわけではありません。
実行中にメソッドを強制終了することは理にかなっています。多くの「ハング」は、1 つのメソッドのループ内の無限ループ状態が原因であると考えてください。OS は、メソッドの実行中にアプリを強制終了せずに、そのようなアプリを強制終了するにはどうすればよいでしょうか?
これも考慮してください。OSがアプリを強制終了する前に「現在の」メソッドの実行を終了させてからアプリを強制終了した場合でも、OSが最初に呼び出したメソッドを呼び出したメソッドの途中でアプリを強制終了します。終了するまで実行を継続できます。では、この考え方を極端に続けてください。OS がアプリを強制終了する前に実行中の各関数を終了できるようにした場合、最終的な結果として、OS はアプリ全体を最後まで実行できるようになります。したがって、OS は、アプリを強制終了するときに、"a"... 実際には "many".... 関数の途中でアプリを終了する必要があります。コールスタックにあるすべての関数には、終了する機会がありません!
殺し方にもよると思います。クラッシュによる殺害?すべてのスレッドは、どこにいても停止します。ウォッチドッグタイマーによる殺害?どこにいてもすべてのスレッドが殺されました。ユーザーがアクティビティを閉じたために殺されましたか? アクティビティ/スレッドは、実行していることを終了します。基本的にあてにできませんが、発生する可能性があります。閉鎖によるデータの破損が心配な場合は、トランザクション モデルを使用する必要があります。