11

これについてはトラックいっぱいの提案がありますが、(私が見つけた) すべての要因を考慮しているものはありません。要因は次のとおりです。

  1. 非同期ダウンロード、(ダウンローダーとビットマップの)重複なし、ダウンロードのキャンセル/不要になった画像の割り当て
  2. アダプターは、同じ ID に対して複数のビューを持つことができます (getView(0) への呼び出しは非常に頻繁です)。
  3. ビューがリサイクルされる代わりに失われないという保証はありません (List/GridView のサイズ変更またはテキストによるフィルタリングを検討してください)。
  4. ビューとデータ/ロジックの分離 (可能な限り)
  5. ダウンロードごとに個別のスレッドを開始しない (目に見える UI のスローダウン)。キュー/スタック (LinkedBlockingQueue?) とスレッド プールなどを使用しますが、アクティビティが破棄された場合はそれを終了する必要があります。
  6. リスト/グリッド内の現在の位置から十分に離れたビットマップをパージします。メモリが必要な場合にのみ実行することをお勧めします
  7. 破棄されるすべてのビットマップで recycle() を呼び出します。
  8. 外部メモリは (常に、または常に) 利用できない可能性があり、使用している場合は、(ここでダウンロードした画像のみ) できるだけ早く消去する必要があります。Android によるアクティビティの破棄/再作成も検討してください。
  9. 変更中のデータ: エントリが削除され (リストで選択、削除するボタン、即時更新)、バックグラウンド スレッドに追加されます (必要に応じてリストが更新されます)。ダウンロード済みのビットマップは、リンク先のエントリがまだ存在する限り保持する必要があります。
  10. (オプション) 単一の ImageView を更新するために、notifyDataSetChanged (これは、目に見える、潜在的に非常に複雑なリスト項目をすべて更新します) に依存しないでください。
  11. setTextFilterEnabled(true) (ArrayAdapter と同様。Filterable の実装は、他の Adapter メソッドに表示されるデータ配列を置き換えるため、ビューのインデックスが変更されるため、ビットマップにリンクするための ID として使用できません)。
  12. ExpandableList で使用可能 (サムネイルが表示される順序に影響します)

これが答えられていたら、私を許してください。何ヶ月も検索しましたが、解決策が見つかりませんでした。

要件は私には妥当に思えますが、それぞれに難しさの次元が追加されます。特に、操作中およびアクティビティの破棄時に呼び出す必要がある Bitmap.recycle が追加されます (onDestroy、さらには onStop が呼び出されない可能性があることに注意してください)。
これにより、他のいくつかの点を処理できた可能性のある SoftReferences に依存することもできなくなります。
はい、必要です。そうしないと、(制御されたメモリ不足の状況を強制するために) try-catch で gc、スリープ (20 秒、偶数)、yield、巨大な配列割り当てを何度行っても OutOfMemoryError が発生します。
「OutOfMemoryError: ビットマップ サイズが VM の予算を超えています」または「android ビットマップ リサイクル」を検索します。
はい、ビットマップをリサンプリングしています。

4

0 に答える 0