Androidのマルチピクチャ非同期ロードの再考

2443 ワード

2.0.4.1(37)バージョン以前のオープンソースの中国クライアントが初めて画像をロードしたとき、特に動きリストの画像が遅くなることに気づいたかどうか分かりません.ネットの速度が遅いときも、画像がロードされていないような気がします.
なぜなら、ネットワーク画像をダウンロードする際にマルチスレッドを併用して実行する方式で、どういう意味ですか.つまり、複数のスレッドを開いて同時に複数の画像をダウンロードすることです.正常な思考に基づいて、画像のロード操作をしてマルチスレッドを使用するのは正常であるべきで、これは私たちの思考の中で、マルチスレッド資源の利用率がもっと高くて、プログラムの応答がもっと速いためです.
例を挙げると、アプリケーションがローカルファイルシステムからファイルを読み取り、処理する必要があるシナリオです.たとえば、ディスクからファイルを読み込むのに5秒、ファイルを処理するのに2秒かかります.2つのファイルを処理するには
5     A
2     A
5     B
2     B
---------------------
    14 

ディスクからファイルを読み取る場合、ほとんどのCPU時間はディスクがデータを読み取るのを待つために使用されます.この間、CPUは非常に空いていた.他のことをすることができます操作の順序を変えることで、CPUリソースをよりよく使用することができます.次の順番を見て
5     A
5     B + 2     A
2     B
---------------------
    12 

CPUは、最初のファイルの読み取りが完了するのを待ちます.次に、2番目のファイルの読み取りを開始します.第2のファイルが読み込まれると、CPUは第1のファイルを処理する.ディスク読み取りファイルを待つ間、CPUのほとんどの時間はアイドルであることを覚えておいてください.総じて言えば、CPUはIOを待っている間に他のことをすることができる.これは必ずしもディスクIOとは限らない.ネットワークのIO、またはユーザ入力であってもよい.通常、ネットワークおよびディスクのIOは、CPUおよびメモリのIOよりもはるかに遅い.
マルチスレッド同時実行を採用することでCPUの利用率を向上させることができるのに、なぜAndroidの画像ロードに使うのが遅くなったのでしょうか.
ここを見て、あなたはもう原因を考えているはずです.私たちがコードを書いて、一人で2つのAndroidアプリケーションを同時に書いて、オンラインを発表したようです.アプリケーションパブリケーションはオンラインレビューを必要とせず、AとBの機能はほぼ同じであると仮定します.もし私たちが先にアプリケーションAの機能を書いて、Aのある機能が書き終わったときにアプリケーションBと同じ機能を書くと、書くのは自然に速くなります.これが同時実行であり,AとBを同時に実行する.しかしこのようにAとBの完成の総時間は短縮され,単一のAアプリケーションで完成できる時間は長くなった.途中でBアプリを完成させられたからです.
これも、37バージョン以前のOSCクライアントの画像がほぼ同時に出ていることを発見した理由です.
Androidに戻ると、私の前のブログでAsyncTaskがandroid 2にあると話したことがあります.3の时にスレッドプールは1つのコア数が5スレッドで、キューは10スレッドを収容することができて、最大128の任务を実行して、これは1つの问题があって、あなたが本当に138の并発がある时、たとえ携帯电话があなたに支えられていないとしても、それではこの指标を超えて绝対にcrashを使います.その後3.0にアップグレードされ、同時に発生するカラムの問題を回避するために、AsyncTaskはシーケンスエフェクタになりました.つまり、execute N個のAsyncTaskを同時に実行しても、キューごとに実行されます.この点に注意してください.AsyncTaskは3.0以降、非同期で間違いありませんが、同時ではありません.知らない学生は『Thread同時リクエストパッケージ--AsyncTask類を深く理解する』『完全なAndroid非同期タスク類』を見に行くことができます.
今から思えば、Android SDKがパラレル実行をシリアル実行に変更したのも無理はない.
シリアルに戻ると129個の画像を同時にロードしたときにクラッシュするのではないかと心配するかもしれません.もちろん、できません.画像をロードするときにダウンロードタスクをキャンセルするように設計されており、listViewで画像をロードするときに、この画面をスクロールすると、画像のダウンロードタスクはすぐに停止し、新しい画像のダウンロードをロードします.129枚の図が1画面に表示されることはないでしょう.
/**
*         
*
* @param view
*/
public void cancle(View view) {
    for (BitmapWorkerTask task : taskCollection) {
        if (task.imageView.equals(view)) {
            task.cancelTask();
            taskCollection.remove(task);
            break;
        }
    }
}