126

こんにちは、Android がどのようにメモリを管理しているのか疑問に思っていますが、どこにも正確な答えが見つかりません。現在のアクティビティ スタックに 5 つのアクティビティを持つアプリケーションがあり (4 つが停止され、1 つが再開されます)、サービスが接続されていないとします。ホームボタンを押して、すべてのアクティビティを停止します。他のメモリを消費するアプリケーションを起動すると、デバイス全体のメモリが少なくなり始めています。そして質問は

... 私のアプリケーションはどうなりますか?

  1. システムは、メモリを回復するためにアクティビティの 1 つまたは一部のみを破棄できますか?
  2. システムはアプリケーションのプロセス全体を強制終了しますか? すべての活動は適切に破棄されますか?
  3. アプリケーションが完全に強制終了されたときにアプリケーションに戻るとどうなりますか? 最初から (最初の開始のように) 開始しますか、それともアクティビティを以前の状態に回復しようとしますか / はいの場合 - スタックの一番上にあるものだけですか、それともすべてですか?

アップデート:

この質問をする前に、アクティビティのライフサイクルを数回見ましたが、私の質問に対する回答がありません。私はいくつかのテストを行い、いくつかの答えを持っています。DDMS の「プロセスの停止」は、テストの手がかりでした。

質問1の回答をテストしていませんが、ガイドが言うように:

アクティビティが一時停止または停止している場合、システムは、アクティビティに終了を要求するか、単にプロセスを強制終了することにより、メモリからアクティビティを削除できます。

プロセスを強制終了することなく、1 つ以上のアクティビティを (onDestroy メソッドを使用して) 穏やかに破棄できるようです。それらに戻ると、単に (onCreate + bundle) を取得します。

質問 2 の答え:

はい。通常、システムはプロセス全体を強制終了します。これは、アクティビティや静的フィールドを含むすべてのデータが破棄されることを意味します。これは適切に行われていません。一時停止/停止したアクティビティに対して onDestroy または finalize() を取得することはできません。これが、onPause メソッドの直前に saveInstanceState() が呼び出される理由です。onPause は基本的に、何かを保存する最後のメソッドです。このメソッドの後では、onStop や onDestroy が表示されないためです。システムは、オブジェクトが保持しているものや実行しているものに関係なく、すべてのオブジェクトを破壊するプロセスを強制終了できます。

質問 3 の答え:

強制終了されたアプリケーションに戻るとどうなりますか?

  • Android 2.2 より前 - アプリケーションは最初からランチャー アクティビティで開始されます。
  • 2.2 以降 - システムは以前のアプリケーションの状態を復元します。どういう意味ですか?これは、最後に表示されたアクティビティが再作成されることを意味します (onCreate + bundle)。アクティビティ スタックはどうなりますか? スタックは問題ありませんが、スタック上のすべてのアクティビティが停止しています。戻るボタンで戻ると、それぞれが再作成されます(onCreate + bundle)。それについてもう1つあります:

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

結論?

  1. android:configChanges="orientation" でアクティビティ ローテーションの問題を処理できるとは思わないでください。そうすることで、あなたが気づいていない他の多くの問題が発生します。
  2. DDMS - プロセス停止ボタンを使用してアプリケーションをテストします。これを見る
  3. 静的変数を使用する場合は注意してください。アクティビティ 1 で初期化したときに、アクティビティ 2 で初期化されるとは思わないでください。グローバルな静的を初期化する唯一の安全な場所は、アプリケーション クラスです。
  4. onStop または onDestroy が表示されない可能性があることに注意してください。ファイル/データベースを閉じ、onPause でダウンローダーを停止します。アプリに BG で何かをさせたい場合は、フォアグラウンド サービスを使用します。

それだけです...エッセイを手伝ってくれることを願っています:)

4

2 に答える 2

32

まず、これを見てください:

img1

onPause() システムが以前のアクティビティの再開を開始しようとしているときに呼び出されます。これは通常、保存されていない変更を永続データにコミットしたり、アニメーションやその他の CPU を消費する可能性があるものを停止したりするために使用されます。このメソッドが戻るまで次のアクティビティが再開されないため、このメソッドの実装は非常に迅速である必要があります。アクティビティが前面に戻った場合は onResume() が続き、ユーザーから見えなくなった場合は onStop() が続きます。

onStop()別のアクティビティが再開され、このアクティビティをカバーしているため、アクティビティがユーザーに表示されなくなったときに呼び出されます。これは、新しいアクティビティが開始されているか、既存のアクティビティがこのアクティビティの前に移動されているか、またはこのアクティビティが破棄されているために発生する可能性があります。このアクティビティがユーザーと対話するために戻ってくる場合は onRestart() が続き、このアクティビティがなくなる場合は onDestroy() が続きます。

したがって、デバイスの「ホーム」ボタンを押すと、現在のフォアグラウンド アクティビティが に置かれonPause()onStop()残りの 4 つが残るはずです。onStop()

Googleのドキュメントによると:

  • 画面のフォアグラウンド (スタックの一番上) にあるアクティビティは、アクティブまたは実行中です。
  • アクティビティがフォーカスを失ったが、まだ表示されている場合 (つまり、フルサイズでない新しいアクティビティまたは透明なアクティビティがアクティビティの上にフォーカスされている場合)、そのアクティビティは一時停止されています。一時停止されたアクティビティは完全に有効ですが (すべての状態とメンバー情報を維持し、ウィンドウ マネージャーに接続されたままになります)、メモリが極端に少ない状況では、システムによって強制終了される可能性があります。
  • アクティビティが別のアクティビティによって完全に隠されている場合、そのアクティビティは停止されます。すべての状態とメンバー情報は引き続き保持されますが、ユーザーには表示されなくなるため、ウィンドウが非表示になり、他の場所でメモリが必要になるとシステムによって強制終了されることがよくあります。
  • アクティビティが一時停止または停止している場合、システムはアクティビティに終了を要求するか、単にプロセスを強制終了することで、メモリからアクティビティを削除できます。ユーザーに再び表示されるときは、完全に再起動して以前の状態に復元する必要があります。

そして、プロセスのライフサイクルについて:

プロセスのライフサイクル3. バックグラウンド アクティビティ (ユーザーには表示されず、一時停止されているアクティビティ) はもはや重要ではないため、システムはそのプロセスを安全に強制終了して、他のフォアグラウンドまたは表示されているプロセスのためにメモリを再利用できます。そのプロセスを強制終了する必要がある場合、ユーザーがアクティビティに戻ったときに (再び画面に表示されるように)、その onCreate(Bundle) メソッドが、以前に onSaveInstanceState(Bundle) で提供されていた savedInstanceState で呼び出されます。ユーザーが最後に終了したときと同じ状態で再起動できます。

上記の引用はすべて以下からのものです: Android Developers Reference: Activity

メモリを消費するアプリケーションを起動すると、システムが非アクティブなアクティビティを破棄し、メモリをリサイクルできることが確認されています。そして、次のように実装できisFinishing()ます。アクティビティで、DDMS の「kill」ボタンを使用して、どのアクティビティがシステムによってドロップされているかを検出します。しかし、システムは古いものから最初に破棄すると思います。ただし、「Launch Activity」がリサイクルされた場合、他のアクティビティを保持しても意味がありません。

アップデート

ここから見つけたいくつかの意見を次に示します。

停止状態

アクティビティが表示されていなくてもメモリ内にある場合、それは停止状態にあると言います。停止したアクティビティを前面に戻して、再び実行中のアクティビティにすることができます。または、破棄してメモリから削除することもできます。

システムは、ユーザーがすぐにそれらのアクティビティに戻りたいと思う可能性が高く、停止したアクティビティを再開する方がアクティビティを最初から開始するよりもはるかに安価であるため、アクティビティを停止した状態に保ちます。これは、すべてのオブジェクトが既にメモリにロードされており、すべてをフォアグラウンドに持ってくる必要があるためです。

停止したアクティビティは、いつでもメモリから削除できます。

于 2013-01-17T10:25:51.057 に答える
1

システムは、メモリを回復するためにアクティビティの 1 つまたは一部のみを破棄できますか?

はい。Android は、メモリが必要なときにバックグラウンドで実行されているアクティビティを強制終了します。1つまたはすべてを殺すことは、いくつかの条件に依存する場合があります. 一時停止または停止したインスタンスの場合、android はアクティビティまたはプロセス自体を強制終了できます。ここで、 Activity Lifecycleの下で、以下のポイントを取得できます。そのページを完全に通過することをお勧めします。あなたの疑問を確実に解消してくれます。

アクティビティがフォーカスを失ったが、まだ表示されている場合 (つまり、フルサイズではない新しいアクティビティまたは透明なアクティビティがアクティビティの上にフォーカスされている場合)、そのアクティビティは一時停止されています。一時停止されたアクティビティは完全に有効ですが (すべての状態とメンバー情報を維持し、ウィンドウ マネージャーに接続されたままになります)、メモリが極端に少ない状況では、システムによって強制終了される可能性があります。

アクティビティが別のアクティビティによって完全に隠されている場合、そのアクティビティは停止されます。すべての状態とメンバー情報は引き続き保持されますが、ユーザーには表示されなくなるため、ウィンドウが非表示になり、他の場所でメモリが必要になるとシステムによって強制終了されることがよくあります。

アクティビティが一時停止または停止している場合、システムはアクティビティに終了を要求するか、単にプロセスを強制終了することで、メモリからアクティビティを削除できます。ユーザーに再び表示されるときは、完全に再起動して以前の状態に復元する必要があります。


システムはアプリケーションのプロセス全体を強制終了しますか? すべての活動は適切に破棄されますか?

活動は個人に関係しますが、プロセスは活動のグループに関係します。上記の 3 番目のポイントをもう一度見てください。前述のように、プロセスが強制終了されます。


アプリケーションが完全に強制終了されたときにアプリケーションに戻るとどうなりますか?

restart に似ています。繰り返しますが、3番目のポイントは次のようないくつかの答えを提供しますWhen it is displayed again to the user, it must be completely restarted and restored to its previous state

メモリ関連の詳細については、こちらを参照してください。

編集:
アプリケーション内のすべてのアクティビティは、単一のプロセスで実行されます。したがって、プロセスが強制終了されると、5 または 10 に関係なく、すべてのアクティビティが強制終了されます。つまり、再起動されます。再起動すると、アプリケーションは保存されていない状態から開始されます。

于 2013-01-17T10:58:28.837 に答える