13

より具体的に: タスクのキャンセルを onDestroy に配置しても安全ですか? また、受信者の登録を解除してリソースを解放するために onDestroy を使用しても安全ですか?

私の目的は、アクティビティが破棄される前ではなく、タスクがキャンセル/破棄されるようにすることです。

onDestroy():

  1. アクティビティが破棄され、リソースを解放する必要があるときに呼び出されます。
  2. アクティビティが急いで破棄された場合 (システムのリソースが不足している場合など) は呼び出されません。

最初のケースは明らかです。onDestroy ですべてのクリーニングを行い、問題は発生しません。ただし、2番目のケースは少し問題です。アクティビティが破棄され、onDestroy がスキップされると (タスクをキャンセルしないため)、タスクが実行を継続し、完了してデッド アクティビティを更新しようとするため、アプリがクラッシュする可能性がありますか?


本当の質問に来ます:

  1. アクティビティが強制終了され、onDestroy がスキップされると、そのアクティビティにアタッチされているものはすべて自動的に破棄されますか? (onDestroy は、すべてが完全に消去される場合にのみスキップされますか? タスク、登録済みの受信者など)
  2. onDestroy がスキップされた場合、これはアプリ全体が強制終了されたことを意味しますか?

ソリューションは onPause() または onStop() にはないため、onDestroy() に注目しましょう。引数:

  • onDestroy と同様に、Activity が破棄されているときに onStop() をスキップできます。
  • onPause の呼び出しが早すぎて頻繁に呼び出されるため、ユース ケースには適していません。例:

画面ロック: デバイスの画面がロックされているときに onPause を呼び出すことができます。多くの場合、これはスクリーンセーバーのように発生し、ユーザーはそこに立って画面を見ているため、すぐにロックを解除します。このような場合にタスクをキャンセルし、アプリが行っていることをすべて停止すると、ユーザー エクスペリエンスが低下するだけです。偶発的な「スクリーンセーバー」が原因で、アプリがチョークしたり誤動作したりしたくありません。

サンプルアプリには、アクティビティである 2 つの画面があります。ユーザーはそれらをすばやく切り替えることができます。このアプリでは、ユーザーは画面を頻繁かつ迅速に切り替える傾向があります。

ナビゲーション: 画面の 1 つに、システムから更新された位置情報を受け取る地図があります。場所 (ルート) の変更の正確なグラフィカル ログを記録するため、アクティビティが閉じられるまで常に実行する必要があります。通常、onResume と onPause で受信者を登録および登録解除します。ただし、ユーザーが移動するたびにマップの更新が停止するため、アプリが非常に使いにくくなります。そのため、onDestroy で受信者を登録解除したいと考えています。

Loading list : 2 番目の画面には、Web サービスからのデータを表示するリストがあります。データのダウンロードには 4 秒かかります。私は AsyncTask を使用しており、必要に応じてキャンセルする必要があることを知っています。ユーザーが画面を切り替えている間もロードを続行する必要があるため、onPause でキャンセルしないでください。したがって、onDestroy でキャンセルしたいと思います。

もっと多くの例があります。それらのいくつかは、すべての人の意見では完全に適切ではないかもしれません (AsyncTask の代わりにサービスを使用することを提案することさえあります)。しかし、アイデアは重要であり、それらのすべてが同じアイデアを持っています: アクティビティが一時停止している間、アクティビティに固有の作業を続けますが、アクティビティが破棄されたときにそれを停止するようにしてください. (AsyncTask を使用しているか、Service を使用しているかは問題ではありません。いずれの場合も、Activity が破棄された時点で作業を停止する必要があります。)

PS答えがonDestroy でクリーンアップを行うのは安全ではないということである場合、これは Android フレームワークが onPause で行っているすべてのことを停止する必要があることを意味します。そして、onDestroyを使用する理由がわかりません...

4

3 に答える 3

1

この赤ちゃんを紹介したいと思います:http://developer.android.com/reference/android/content/ComponentCallbacks2.html#onTrimMemory(int)

基本的に、システムがタスクをキャンセルしてメモリを消去するのに役立つすべての場所を提供します。

次の 2 つのケースを詳しく見てください。

TRIM_MEMORY_UI_HIDDEN - プロセスはユーザー インターフェイスを表示していましたが、表示されなくなりました。

TRIM_MEMORY_COMPLETE - プロセスがバックグラウンド LRU リストの終わりに近づいています。

あなたが尋ねたもののほとんどの場合はどれですか。

同じ方法で TRIM_MEMORY_RUNNING_CRITICAL をキャッチすることもできます。これは、システムにメモリがなく、特別なアクションをすぐに実行する必要がある場合に警告します。

この方法により、同様のケースで私の開発ライフが大幅に改善されました。

于 2014-04-28T08:21:37.620 に答える
0

私がアンドロイドで行った限りでは、

1アプリがクラッシュすると、それに関連するすべてのリソースが破棄されます。

2デバイスの構成が変更され、アクティビティが破棄されて再作成された場合。

3バックグラウンドで実行されているアプリと Android が低メモリで実行されているためにそれを強制終了する場合

これらとは別に、他のコールバック メソッドが呼び出されます。

1 別のアクティビティが前に来るか、デバイスがロックされたとき..など

いずれの場合も、要件に応じて、onDestroy ですべてのリソースを解放し、スレッドと非同期タスクをキャンセルして、すべてのサービスを停止することができます。破棄が呼び出されている間、タスクを一時停止したままにしておきたい場合は、構成を保存して保持することができます。 onCreate がチェックによって再度呼び出されている間、null かどうか。

于 2013-01-29T13:36:03.447 に答える