日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
處理來(lái)自UI線程的位圖

BitmapFactory的decode()方法,在Load Large Bitmaps Efficiently要 點(diǎn)中進(jìn)行討論,不應(yīng)該執(zhí)行在主UI線程如果要讀取源數(shù)據(jù)從磁盤(pán)或網(wǎng)絡(luò)位置(或相對(duì)內(nèi)存來(lái)說(shuō)任何別的真實(shí)來(lái)源).該數(shù)據(jù)需要加載的時(shí)間是不可預(yù)知的,并取決 于多種因素(從磁盤(pán)或網(wǎng)絡(luò)的讀取速度,圖像大小,CPU的功率,等).如果這些任務(wù)阻塞UI線程,系統(tǒng)標(biāo)志您的應(yīng)用程序無(wú)響應(yīng),用戶可以選擇關(guān)閉它響應(yīng) (有關(guān)更多信息,請(qǐng)參閱Designing for Responsiveness).

專(zhuān)注于為中小企業(yè)提供成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)南岔免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了數(shù)千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

本文將引導(dǎo)您通過(guò)在后臺(tái)線程中使用AsyncTask處理位圖,并告訴您如何處理并發(fā)問(wèn)題.

使用一個(gè)異步任務(wù)

AsyncTask類(lèi)提供了一種簡(jiǎn)單的方式來(lái)在一個(gè)后臺(tái)線程中執(zhí)行許多任務(wù),并且把結(jié)果反饋給UI線程.使用的方法是,創(chuàng)建一個(gè)繼承與它的子類(lèi)并且實(shí)現(xiàn)提供的方法.這里是一個(gè)使用AsyncTask和decodeSampledBitmapFromResource()加載一個(gè)大圖片到ImageView中的例子:

 
 
 
  1. class BitmapWorkerTask extends AsyncTask { 
  2.     private final WeakReference imageViewReference; 
  3.     private int data = 0; 
  4.  
  5.     public BitmapWorkerTask(ImageView imageView) { 
  6.         // Use a WeakReference to ensure the ImageView can be garbage collected 
  7.         imageViewReference = new WeakReference(imageView); 
  8.     } 
  9.  
  10.     // Decode image in background. 
  11.     @Override 
  12.     protected Bitmap doInBackground(Integer... params) { 
  13.         data = params[0]; 
  14.         return decodeSampledBitmapFromResource(getResources(), data, 100, 100)); 
  15.     } 
  16.  
  17.     // Once complete, see if ImageView is still around and set bitmap. 
  18.     @Override 
  19.     protected void onPostExecute(Bitmap bitmap) { 
  20.         if (imageViewReference null) { 
  21.             final ImageView imageView = imageViewReference.get(); 
  22.             if (imageView != null) { 
  23.                 imageView.setImageBitmap(bitmap); 
  24.             } 
  25.         } 
  26.     } 
  27.  } 

對(duì)于ImageView來(lái)說(shuō)WeakReference確保那時(shí)AsyncTask并不會(huì)阻礙ImageView和任何它的引用被垃圾回收期回收.不能保證ImageView在任務(wù)完成后仍然存在,所以你必須在onPostExecute()方法中檢查它的引用.ImageView可能不再存在,如果例如,如果在任務(wù)完成之前用戶退出了活動(dòng)或者配置發(fā)生了變化.

為了異步地加載位圖,簡(jiǎn)單地創(chuàng)建一個(gè)新的任務(wù)并且執(zhí)行它:

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

處理并發(fā)

常見(jiàn)的視圖組件例如ListView和GridView如在上一節(jié)中當(dāng)和AsyncTask結(jié)合使用時(shí)引出了另外一個(gè)問(wèn)題.為了優(yōu)化內(nèi)存,當(dāng)用戶滾 動(dòng)時(shí)這些組件回收了子視圖.如果每個(gè)子視圖觸發(fā)一個(gè)AsyncTask,當(dāng)它完成時(shí)沒(méi)法保證,相關(guān)的視圖還沒(méi)有被回收時(shí)已經(jīng)用在了別的子視圖當(dāng)中.此外, 還有異步任務(wù)開(kāi)始的順序是不能保證他們完成的順序.

這篇文章透過(guò)Multithreading for Performance功能討論處理并發(fā),并且提供了一個(gè)當(dāng)任務(wù)完成后ImageView將一個(gè)引用存儲(chǔ)到后面能被檢查的AsyncTask的解決方案. 使用類(lèi)似的方法,從上一節(jié)的AsyncTask可以擴(kuò)展到遵循類(lèi)似的模式.

創(chuàng)建一個(gè)專(zhuān)用的Drawable的子類(lèi)來(lái)存儲(chǔ)一個(gè)引用備份到工作任務(wù)中.在這種情況下,一個(gè)BitmapDrawable被使用以便任務(wù)完成后一個(gè)占位符圖像可以顯示在ImageView中:

 
 
 
  1. static class AsyncDrawable extends BitmapDrawable { 
  2.     private final WeakReference bitmapWorkerTaskReference; 
  3.  
  4.     public AsyncDrawable(Resources res, Bitmap bitmap, 
  5.             BitmapWorkerTask bitmapWorkerTask) { 
  6.         super(res, bitmap); 
  7.         bitmapWorkerTaskReference = 
  8.             new WeakReference(bitmapWorkerTask); 
  9.     } 
  10.  
  11.     public BitmapWorkerTask getBitmapWorkerTask() { 
  12.         return bitmapWorkerTaskReference.get(); 
  13.     } 
  14.  } 

執(zhí)行BitmapWorkerTask前,你創(chuàng)建一個(gè)AsyncDrawable,并將其綁定到目標(biāo)ImageView:

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

如果別的正在運(yùn)行的任務(wù)已經(jīng)和這個(gè)ImageView關(guān)聯(lián),cancelPotentialWork引用在上面的代碼示例檢查中.如果這樣,它試圖通過(guò)調(diào)用cancel()取消先前的任務(wù).在少數(shù)情況下,新的任務(wù)數(shù)據(jù)匹配現(xiàn)有的任務(wù),而且并不需要做什么.下面是實(shí)現(xiàn) cancelPotentialWork:

 
 
 
  1. public static boolean cancelPotentialWork(int data, ImageView imageView) { 
  2.     final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); 
  3.     if (bitmapWorkerTask != null) { 
  4.         final int bitmapData = bitmapWorkerTask.data; 
  5.         if (bitmapData != data) { 
  6.             // Cancel previous task 
  7.             bitmapWorkerTask.cancel(true); 
  8.         } else { 
  9.             // The same work is already in progress 
  10.             return false; 
  11.         } 
  12.     } 
  13.     // No task associated with the ImageView, or an existing task was cancelled 
  14.     return true; 
  15.  } 

一個(gè)幫助方法,getBitmapWorkerTask(),使用以上來(lái)檢索一個(gè)和特定ImageView相關(guān)的任務(wù):

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

這***一步是在BitmapWorkerTask更新onPostExecute()方法,以便任務(wù)取消時(shí)并且當(dāng)前任務(wù)和這個(gè)ImageView關(guān)聯(lián)時(shí)進(jìn)行檢查:

 
 
 
  1. class BitmapWorkerTask extends AsyncTask { 
  2.     ... 
  3.     @Override 
  4.     protected void onPostExecute(Bitmap bitmap) { 
  5.         if (isCancelled()) { 
  6.             bitmap = null; 
  7.         } 
  8.         if (imageViewReference != null && bitmap != null ) { 
  9.             final ImageView imageView = imageViewReference.get(); 
  10.             final BitmapWorkerTask bitmapWorkerTask = 
  11.                     getBitmapWorkerTask(imageView); 
  12.             if (this == bitmapWorkerTask && imageView != null) { 
  13.                 imageView.setImageBitmap(bitmap); 
  14.             } 
  15.         } 
  16.     } 
  17.  } 

現(xiàn)在這個(gè)實(shí)現(xiàn)適合使用ListView和GridView控 件組件以及回收其子視圖的任何其他組件.在你正常地給你的ImageView控件設(shè)置圖片時(shí)簡(jiǎn)單地調(diào)用loadBitmap就行了.例如,在一個(gè) GridView中實(shí)現(xiàn)的方式是在支持的適配中的[android.view.View, android.view.ViewGroup) getView()](http://docs.eoeandroid.com/reference/android/widget /Adapter.html#getView(int,)方法中.


當(dāng)前名稱(chēng):處理來(lái)自UI線程的位圖
文章起源:http://www.5511xx.com/article/ccohgjs.html