10

私たちは、ユーザーがアプリ全体をナビゲートできるようにするドロップダウン ダッシュボードを持つアプリケーションを開発してきました。このメニューはほとんどすべてのアクティビティからアクセスできるため、ナビゲーションはあまり標準的ではありません。メニューを使用してアクティビティを開いてしばらくプレイした後、スタックがどんどん大きくなり始めます。

これらのすべてのアクティビティには、内部にいくつかのイメージビューを含むリストビューが含まれており、それぞれ約 3 MB かかります。ユーザーが十分にプレイし、スタックに 25 を超えるアクティビティを作成すると、次のようになります。

  1. メモリ不足エラーがスローされます (ヒープがなくなるまでヒープが増加します)。
  2. 例外によりダイアログが表示されます (残念ながら、%activity% は停止しました。)
  3. outofmemerror がスローされたアクティビティは終了しました。
  4. スタック内のすべてのアクティビティが終了しますが、履歴が保持されるため、バックアップが可能であり、各アクティビティは OS によって自動的に再作成されます。

OutOfMemoryError がスローされる前に、システムがスタック内の最も古いアクティビティを自動的に強制終了することを期待していました...

OS が古いアクティビティを強制終了していないことを確認するために、毎回 1 MB を割り当てるテスト アプリを作成しました。推測: 動作は同じで、outofmemerror がスローされます。

問題は、「残念ながら、アクティビティが停止しました」というメッセージが表示されないように、必要に応じてアクティビティとそのリソースの割り当てを解除できることを Android OS に伝えるにはどうすればよいかということです。ダイアログ?

コンセプトの証明

    パッケージ com.gaspar.memorytest;

import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MemoryTestActivity extends Activity { /** Called when the activity is first created. */ private byte[] mData; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main1); ((Button)findViewById(R.id.button)).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent i = new Intent(MemoryTestActivity.this, MemoryTestActivity.class); startActivity(i); } }); mData = new byte[1*1024*1024]; } }

4

6 に答える 6

14

OutOfMemoryError がスローされる前に、システムがスタック内の最も古いアクティビティを自動的に強制終了することを期待していました

Android はこれを行いません。Android はプロセスを終了して、他のプロセスのためにシステム メモリを解放します。同様の方法でアプリ内のメモリ使用量に関与することはありません。

「残念ながら、アクティビティが停止しました」というメッセージが表示されないように、必要に応じてアクティビティとそのリソースの割り当てを解除できることを Android OS に伝えるにはどうすればよいでしょうか。ダイアログ?

できません。

代わりに、使用するアクティビティを減らすか、アクティビティごとのリソースを減らすようにアプリケーションを設計する必要があります。たとえば、既存のアクティビティ インスタンスをFLAG_ACTIVITY_REORDER_TO_FRONT、または (Tornquist 氏が指摘したように)finish()自分で手動で「リサイクル」することができます。

メニューを使用してアクティビティを開いてしばらくプレイした後、スタックがどんどん増えていきます。

FLAG_ACTIVITY_REORDER_TO_FRONT毎回新しいアクティビティを作成するのではなく、既存のアクティビティをタスクに持ち込むために、おそらくこれらのメニュー項目を使用する必要があります。

于 2012-07-23T16:45:14.800 に答える
1

finish()新しいアクティビティを開始するときに呼び出すと、残すアクティビティの割り当てが解除されます。これにより、戻るボタンでアクセスできなくなりますが、メモリは少なくなります。

于 2012-07-23T16:31:04.003 に答える
0

Android 開発者ガイドによると、システムが古いアクティビティを強制終了してメモリを解放するという印象も受けました。

「システムがアクティビティの 1 つを停止すると (新しいアクティビティが開始されたときやタスクがバックグラウンドに移動したときなど)、システム メモリを回復する必要がある場合、システムはそのアクティビティを完全に破棄する可能性があります。これが発生すると、アクティビティの状態に関する情報これが発生した場合でも、システムはアクティビティがバック スタックにあることを認識していますが、アクティビティがスタックの一番上に移動すると、システムはそれを (再開するのではなく) 再作成する必要があります。ユーザーの作業が失われる場合は、アクティビティに onSaveInstanceState() コールバック メソッドを実装して、積極的に保持する必要があります。」

リンクを参照してください: アンドロイドの活動

于 2012-10-05T10:53:33.427 に答える