日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Android Load Picture Asynchronously

發布時間:2025/7/25 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Load Picture Asynchronously 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

眾所周知Android應用開發中不能在UI線程中做耗時的操作,否則就會彈出煩人的ANR窗口。

應用開發中如果需要加載來自網絡、磁盤或其他非內存中圖片資源時,因加載時間會受到其他因素(如磁盤、網絡、圖片大小、CPU等等)的影響,很容易產生耗時操作。所以在進行類似操作時要避免在UI線程中進行。今天就和大家分享一下如何通過AsyncTask異步加載圖片和怎么處理多線程并發問題。

如何使用 AsyncTask加載圖片?

通過AysncTask可以很容易的在啟動后臺線程加載資源,然后將結果返回到UI線程中。使用它時,需要創建它的子類并實現相應的方法,如下是一個通過AysncTask和decodeSampledBitmapFromResource()方法加載一張大圖片到ImageView中的例子:

class BitmapWorkerTask extends AsyncTask {private final WeakReference imageViewReference;private int data = 0;public BitmapWorkerTask(ImageView imageView) {// Use a WeakReference to ensure the ImageView can be garbage collectedimageViewReference = new WeakReference(imageView);}// Decode image in background. @Overrideprotected Bitmap doInBackground(Integer... params) {data = params[0];return decodeSampledBitmapFromResource(getResources(), data, 100, 100));}// Once complete, see if ImageView is still around and set bitmap. @Overrideprotected void onPostExecute(Bitmap bitmap) {if (imageViewReference != null && bitmap != null) {final ImageView imageView = imageViewReference.get();if (imageView != null) {imageView.setImageBitmap(bitmap);}}} }

使用WeakReference 保存ImageView的原因,是為了在內存資源緊張時確保AsyncTask 不會阻止對其進行資源回收,因此當task結束時不能保證Imageview還存在,所以你應該在onPostExecute中對它進行驗證(本例中在Task結束前如果用戶關閉Activity,或系統設置改變時,ImageView可能會被回收)。

通過以下方式我們就可以異步加載圖片:

1 2 3 4 public void loadBitmap(int resId, ImageView imageView) { ????BitmapWorkerTask task = new BitmapWorkerTask(imageView); ????task.execute(resId); }

如何處理并發操作?

常用的View組件中 像ListView、GridView等 為了高效實用內存,用戶在進行View滾動操作時系統會對不再使用子View進行資源回收,,采用上面的方式進行圖片加載時會引入另外一個問題。如果在每個子View中開啟AsyncTask,不能保證在任務完成時,相關的View是否已經被回收。此外,也不能保證他們加載完成的順序

我們可以通過將AsyncTask的引用保存ImageView關聯Drawable中,任務完成時檢查引用是否存在.

創建一個專用的Drawable子類,存儲工作任務線程的引用。這樣在任務完成時即可將圖片設置在ImageView中

static class AsyncDrawable extends BitmapDrawable {private final WeakReference bitmapWorkerTaskReference;public AsyncDrawable(Resources res, Bitmap bitmap,BitmapWorkerTask bitmapWorkerTask) {super(res, bitmap);bitmapWorkerTaskReference =new WeakReference(bitmapWorkerTask);}public BitmapWorkerTask getBitmapWorkerTask() {return bitmapWorkerTaskReference.get();} }

在執行BitmapTask前,你可以創建AsyncDrawable并將其綁定到ImageView中

1 2 3 4 5 6 7 8 9 public void loadBitmap(int resId, ImageView imageView) { ????if (cancelPotentialWork(resId, imageView)) { ????????final BitmapWorkerTask task = new BitmapWorkerTask(imageView); ????????final AsyncDrawable asyncDrawable = ????????????????new AsyncDrawable(getResources(), mPlaceHolderBitmap, task); ????????imageView.setImageDrawable(asyncDrawable); ????????task.execute(resId); ????} }

?

上面代碼中通過cancelPotentialWork判斷是否已經存在正在運行的任務綁定在ImageView中,若有,通過執行任務cancel方法取消它,當然這種情況不常發生,

下面是cancelPotentialWork的實現:

public static boolean cancelPotentialWork(int data, ImageView imageView) {final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);if (bitmapWorkerTask != null) {final int bitmapData = bitmapWorkerTask.data;if (bitmapData != data) {// Cancel previous taskbitmapWorkerTask.cancel(true);} else {// The same work is already in progressreturn false;}}// No task associated with the ImageView, or an existing task was cancelledreturn true; }

下面是一個輔助方法,通過ImageView查找與其關聯的異步任務;

1 2 3 4 5 6 7 8 9 10 private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { ???if (imageView != null) { ???????final Drawable drawable = imageView.getDrawable(); ???????if (drawable instanceof AsyncDrawable) { ???????????final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; ???????????return asyncDrawable.getBitmapWorkerTask(); ???????} ????} ????return null; }

?

下一步需要在BitmapWorkerTask中的onPostExecute中執行更新操作,

首先檢查任務是否取消,如后更行與其關聯的ImageView:

class BitmapWorkerTask extends AsyncTask {... @Overrideprotected void onPostExecute(Bitmap bitmap) {if (isCancelled()) {bitmap = null;}if (imageViewReference != null && bitmap != null) {final ImageView imageView = imageViewReference.get();final BitmapWorkerTask bitmapWorkerTask =getBitmapWorkerTask(imageView);if (this == bitmapWorkerTask && imageView != null) {imageView.setImageBitmap(bitmap);}}} }

通過以上方法,你就可以在ListView、GridView或者其他具有子view回收處理的組件中使用,通過調用

loadBitmap你可以很簡單的添加圖片到ImageView中,如:在GirdView的 Adapter中的getView方法中調用。

轉載于:https://www.cnblogs.com/qiengo/archive/2012/05/26/2519168.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的Android Load Picture Asynchronously的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。