blog

Picassoのソースコードコミット 注:画像キャッシュのキーと値とは?

以前のバージョンでは、すべてのリクエストはネットワークから直接ダウンロードされていました。今回は、すでにダウンロードされた画像を再ダウンロードする必要がないように、キャッシュが追加されました。キャッシ...

Feb 24, 2020 · 4 min. read
シェア

以下のコードノートは : a07bd18608800555f7ba6a4dea038be63188b831, commit time: 2013/3/19 9:18 AM. 上の commitId をクリックすると github にジャンプしてコードを見ることができます。

この連載は5つのパートで構成されています。リファクタリングは、同じ機能のためのコードの変更です。フィーチャーは、今回のコミットと比較した新しい機能です。設計は、私が言及できると思うコードの設計です。この部分はプログラマによって異なるかもしれません。Doubtは、コードを見たときに問題がある、あるいは理解できないと思うことです。知識はJavaやAndroidに関する一般的な知識です。

feature

キャッシュ

以前のバージョンでは、すべてのリクエストはネットワークから直接ダウンロードされていました。今回は、すでにダウンロードされたイメージを再ダウンロードする必要がないように、キャッシュが追加されました。キャッシュはハードドライブキャッシュとメモリキャッシュの2つに分かれています。ハードドライブキャッシュは、アプリが終了した後もキャッシュされたデータが存在するようにし、メモリーキャッシュは、キャッシュされたデータをより速く読み込むようにします。キャッシュ戦略はLRUアルゴリズムを使用し、サイズは固定で、満杯になると初期にダウンロードしたイメージや使用頻度の低いイメージを優先します。具体的な実装はDiskLruCache.javaとLruMemoryCache.javaクラスを参照してください、この記事は展開されません。

キャッシュ後に動作するロジックを追加

以前のバージョンでは、作業ロジックはRequestのrunメソッドに配置されていましたが、作業ロジックに関わる変数の多くがPicasso.javaにあるため、作業ロジックはPicasso.javaに配置されました。 void run(Request request) Picasso.javaのメソッドを見てみましょう。

主なコードロジックを簡単に説明します:

  1. まずメモリーキャッシュの中から取って、取れたら返してください。
  2. そして、ハードドライブのキャッシュからそれを取り出し、もしそれが手に入ったら戻し、メモリーのキャッシュに入れます。
  3. キャッシュが利用できない場合は、ネットワーク経由でダウンロードされ、ダウンロードから戻された後、ハードディスク・キャッシュとメモリー・キャッシュに入れられます。

イメージ変換

Bitmap transform(Bitmap source) このバージョンはイメージ変換をサポートしており、4つの組み込みイメージ変換があります。ユーザーはイメージ変換をカスタマイズすることもでき、Transformationインターフェイス内のメソッドを実装するだけです。イメージ変換は Builder によって設定されます。ここでは具体的な変換アルゴリズムを説明するのではなく、主にイメージ変換が適用される場所を見てみましょう。Picasso.javaのtransformResultメソッドを見てください。このメソッドは、ネットワークからダウンロードされたイメージを受け取り、一連の変換を行い、外部で使用できるように変換されたイメージを返します。

再試行に失敗しました

タスクが失敗した場合の処理については触れていませんが、このバージョンでは失敗した場合も処理しています。 void loadFromStream(Request request) Picasso.javaのメソッドでは、キャッチした後、ハンドラーを通してRETRY_REQUESTメッセージが送信されることがわかります。

失敗の再試行にはUIスレッドの操作は関係ありません。では、なぜハンドラーを経由してメインスレッドに切り替えるのでしょうか? スレッドの切り替えに加えて、ハンドラはメッセージキュー関数も持っています。 handler.sendMessageDelayed(handler.obtainMessage(RETRY_REQUEST, request), RETRY_DELAY); リトライメッセージを送信するコードをよく見てください。ここでは sendMessageDelayed を使っています。この時点でメッセージが失敗した場合、すぐに再試行すると失敗する可能性が高いので、遅延させる必要があるからです。

失敗の再試行も最大再試行回数を持つように設計されており、retryCount 変数で追跡して関連するロジックを見ることができます。最後に、リトライする前にリクエストがキャンセルされたかどうかも判断しなければならないことに注意してください。

bitmapOptionsの設定

BitmapFactory.decodeStream(stream) BitmapFactory.decodeStream(stream, null, request.bitmapOptions) bitmapOptionsはBiuderで設定でき、イメージデコードは.NETから.NETに変更されます。

疑わしい点

なぜPicasso.javaのワークロジックなのですか?

ロジックはワーカーであるRequest.javaにあるべきですが、今回はPicasso.javaにあります。なぜこれが問題なのでしょうか?request.picasso.complete(request) request.setFuture(request.picasso.service.submit(request))ハンドラの中にあるのがわかると思いますが、このコードは非常に読みにくいです。

キャッシュのキーと値が正しく設定されていません。

キャッシュを行うためにまず考えなければならないのは、キャッシュのキーと値をどうするかということです。 void loadFromStream(Request request) saveToCaches(path, result) Picasso.javaのメソッドから、キャッシュのキーはイメージのURLで、値は変換後のビットマップであることがわかります。次のリクエストが同じurlを使用した場合、必要な変換は異なるかもしれませんが、最後に変換されたイメージを取得します。変換に関連するキーに変更するか、元のイメージを保存し、それをキャッシュから取り出して再度変換する必要があります。Picassoがこれをどのように修正するかは、後で見てみましょう。

デザイン

タスクを投入するには、まずメモリキャッシュに

Builder の into メソッドでは、まずメモリキャッシュに照会てイメージがあるかどうかを確認し、イメージがある場合はスレッドプールにリクエストを送信しないことがわかります。なぜでしょうか?なぜなら、メモリキャッシュは読み込みが速いので、スレッドプールに送信しても、スレッドプールがそれを確保するのを待つ必要があるからです。この小さな設計は、要求が迅速に応答できるようにするだけでなく、スレッドプールの負担を軽減します。

テストに便利

setBackgroundColor() キャッシュが追加されたと仮定して、どのイメージがウェブからダウンロードされ、どれがキャッシュから読み込まれたかをすばやく知るにはどうすればよいでしょうか。 Picassoは各リクエストにイメージのソースを示すフィールドを追加し、イメージがレンダリングされるときに、アプリ上で一目でわかるように、異なるソースに基づいてイメージに異なる背景色を設定します。コードのこの部分は、RequestMetrics.javaクラスとその使用法で見ることができます。

ナレッジポイント

LRU キャッシュの実装方法

ここでは、外部フォルダ内のファイルを見ることができます。この記事は展開されません。

イメージ変換の実装方法

ここでは、transformationsフォルダ内のファイルを見ることができます。この記事ではこれ以上説明しません。

Read next

クローラーの注意事項

ノード名を直接呼び出すことでノード要素を選択し、string 属性を呼び出すことでノード内のテキストを取得できます。 注釈 複数のノードがある場合、このメソッドは最初のノードにのみマッチします。例えば、上の p ノードでは、親ノードは 1 つだけですが、子ノードはたくさんあります。親と子の比較に注意してください。

Feb 24, 2020 · 4 min read