1

このlibを使用して画像を表示するアクティビティがいくつかあります。問題は、アプリのメモリが不足していることです。gc.clean()、null参照、imageloaderオブジェクトでclearを呼び出そうとしましたが、無駄でした。

MATで、同じアクティビティのオブジェクトが複数あり、間違っていない限り、デフォルトの動作であることがわかりました。私はsingleInstanceを使用して複数のインスタンスを抑制しましたが、これはメモリリークに役立ちました。

現在、singleInstanceが原因で、ナビゲーションに問題があります。singleInstanceを続行するか、複数のインスタンスでメモリリークを修正する必要があると思いますか?

これがImageViewgcroots検査です: ここに画像の説明を入力してください

UPD:

 Bitmap bitmap=null;
        URL imageUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);
        conn.setInstanceFollowRedirects(true);
        InputStream is=conn.getInputStream();
        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(is, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;

    ImageView imageView = (ImageView) convertView;
    if(convertView == null){
        imageView = new ImageView(_currentActivity);
    }

UPD2(ナビゲーション戦略):

ホームアクティビティ(ギャラリー付き)とプロファイルアクティビティを開始するボタンが付いた一定のヘッダーがあります。次に、リストビュー(imageviews +ラベルで構成される)を使用して別の3つのアクティビティを指す3つのボタンを保持するサブヘッダーがあります。

これらのヘッダー、サブヘッダー要素は、アプリケーションのすべてのアクティビティで使用できます。リンクボタンは次のことだけを行います。

startActivity(new Intent(getActivity(), MainActivity.class));

また

Intent activityIntent = new Intent(getActivity(), SomeActivityWithListViewInside.class);
// passing some data like list id
activityIntent.putExtra("list_id", listId);
startActivity(activityIntent);

したがって、これらのアクティビティインスタンスは、これらのstartActivity呼び出しによって引き起こされます-この問題を回避するために、singleTopまたはその他のインテントパラメーターで遊ぶ必要があると思いますか?

4

3 に答える 3

3

アクティビティの奇妙なフラグを使用しないことを強くお勧めします。また、Android APIを使用したナビゲーションで常に問題が発生しました(フラグメントでも問題が発生します)。

代わりに、メモリの問題を解決することをお勧めします。

メモリリークについてのこのビデオを見て、ビットマップについてこれを読む必要があります。

要するに、ここにいくつかのヒントがあります:

  1. 特にコンテキストを参照する場合は、静的参照を避けるようにしてください。

  2. コンテキストへの参照を避けるようにしてください。

  3. コンテキストを参照する必要がある場合は、ApplicationContextの使用を検討してください。

  4. アクティビティを閉じるときは、スレッドとダイアログを閉じることを忘れないでください(必要な場合)。サービスが不要になったら、サービスを閉じてみてください。

  5. 非静的内部クラスよりも静的内部クラスを優先します(それらは包含クラスへの参照を持っているため)。

  6. 匿名クラスは、それを含むクラスへの参照も持っていることに注意してください。

  7. キャッシュするものに注意してください。ビューやドローアブルなど、コンテキストへの参照を含むクラスをキャッシュしないようにしてください。

  8. 可能であれば、コンテキストを参照する「危険な」オブジェクトを参照するために、softReferenceやweakReferenceを使用してみてください。

  9. android API 10以下では、ビットマップをリサイクルすることを忘れないでください。彼らは通常多くのメモリを取ります。

  10. アクティビティが大量のメモリを消費し、そのアクティビティから別のアクティビティに移動する場合は、古いインスタンスに戻るのではなく、アクティビティを終了して、必要に応じて再作成することを検討してください。

  11. サードパーティのライブラリを使用している場合、またはネイティブコードを使用している場合(たとえば、NDKを使用している場合)、不要なときにそのメモリを解放することを忘れないでください。dalvikはそれについてあなたをあまり助けません。

于 2012-06-25T14:17:35.520 に答える
1

singleInstancelaunchModeは使用しないでください。標準および/またはsingleToplaunchModeを使用して、ナビゲーションを正しく機能させる必要があります。アクティビティのインスタンスが複数あることに気付いたが、それを予期していなかった場合は、ナビゲーションに問題があります。アクティビティのインスタンスが複数あると、すべてのビューと画像が保持されます。これが、メモリ不足の問題の原因である可能性があります。

予想されるナビゲーションとその管理方法で投稿を更新してください。おそらく、それを修正するお手伝いをします。

編集:ポスターのUPDに返信する:

どこに設定しているのかわかりませんが_currentActivity、それが問題かもしれません。アダプタ内にビューを作成するときは、常にアダプタのコンテキスト(作成時に設定されたもの)を使用する必要があります。だからこれを試してみてください:

ImageView imageView = (ImageView) convertView;
if(convertView == null){
    imageView = new ImageView(getContext());
}

編集:ポスターのUPD2に応答する:

ナビゲーションをチェックして、ユーザーがヘッダーまたはサブヘッダーのボタンの1つを選択したときに、アクティビティスタックにアクティビティの複数のインスタンスがないことを確認する必要があります(それが必要でない場合)。アクティビティで大量の画像スペース(ビットマップなど)を使用する場合は、複数のインスタンスがないことを確認する必要があります。ナビゲーションを再考するか、singleTop、clearTop、reorderToFrontなどの組み合わせを使用して、アクティビティのインスタンスを作成し続けるのではなく、アクティビティスタックでそれらを再配置して、目的のナビゲーション動作を取得できます。

于 2012-06-25T17:13:56.847 に答える
0

ビューを作成するときにコンテキストとしてアクティビティを渡すことは適切ではありません。これにより、アクティビティが「解放」されるのを防ぎます。また、ビットマップを本当に必要なサイズに縮小することもできます。

于 2012-06-25T20:06:26.863 に答える