誰かが非同期のための良いメカニズムを作る方法を教えてもらえますか?ListView / GridViewで使用する画像をダウンロードしますか?多くの提案がありますが、それぞれが典型的な要件の小さなサブセットのみを考慮しています。
以下に、私と同僚が一度に満たすことができないいくつかの合理的な要因(要件または考慮すべき事項)をリストしました。
私はコードを求めているのではなく(歓迎されますが)、説明されているようにビットマップを管理するアプローチだけを求めています。
- ダウンローダーやビットマップの重複はありません
- 不要になった、または自動的に削除される可能性のある画像のダウンロード/割り当てのキャンセル(SoftReferenceなど)
- 注:アダプターは、同じIDに対して複数のビューを持つことができます(getView(0)の呼び出しは非常に頻繁です)
- 注:ビューがリサイクルされる代わりに失われないという保証はありません(List / GridViewのサイズ変更またはテキストによるフィルタリングを検討してください)
- ビューとデータ/ロジックの分離(可能な限り)
- ダウンロードごとに個別のスレッドを開始しない(UIの目に見える速度低下)。キュー/スタック(BlockingQueue?)やスレッドプールなどを使用しますが、アクティビティが停止した場合はそれを終了する必要があります。
- リスト/グリッド内の現在の位置から十分に離れたビットマップをパージする(できればメモリが必要な場合のみ)
- 廃棄されるすべてのビットマップでrecycle()を呼び出します。
- 注:外部メモリは(常にまたは常に)使用できない場合があります。使用する場合は、(ここでダウンロードした画像のみを)できるだけ早くクリアする必要があります(Androidによるアクティビティの破棄/レクリエーションを検討してください)
- 注:データは変更できます:エントリは削除され(複数選択と削除)、追加されます(バックグラウンドスレッドで)。リンク先のエントリがまだ存在する限り、ダウンロード済みのビットマップは保持する必要があります。
- setTextFilterEnabled(true)(ArrayAdapterのメカニズムに基づく場合、配列インデックスに影響します)
- ExpandableListで使用可能(サムネイルが表示される順序に影響します)
- (オプション)ビットマップがダウンロードされたら、関連するImageViewのみを更新します(リスト項目は非常に複雑な場合があります)
個別のポイントに対する回答は投稿しないでください。私の問題は、いくつかの側面に焦点を合わせるほど、他の側面がより曖昧になり、ハイゼンベルグのようになることです。
それぞれが難易度の次元を追加します。特にBitmap.recycleは、操作中およびアクティビティの破棄時に呼び出す必要があります(onDestroy、onStopでさえ呼び出されない場合があることに注意してください)。
これにより、SoftReferencesに依存することもできなくなります。
必要です。または、ビットマップをnullにした後、try-catch(制御されたOutOfMemoryを強制するため)でgc、sleep(20s、偶数)、yield、および巨大な配列割り当てをいくつでも実行した後でもOutOfMemoryErrorが発生します。すでにビットマップ
をリサンプリングしています。