Android實(shí)現(xiàn)多線程下載圖片的方法
很多時(shí)候我們需要在Android設(shè)備上下載遠(yuǎn)程服務(wù)器上的圖片進(jìn)行顯示,今天整理出兩種比較好的方法來實(shí)現(xiàn)遠(yuǎn)程圖片的下載。 
方法一、直接通過Android提供的Http類訪問遠(yuǎn)程服務(wù)器,這里AndroidHttpClient是SDK 2.2中新出的方法,API Level為8,大家需要注意下,靜態(tài)訪問可以直接調(diào)用,如果SDK版本較低可以考慮Apache的Http庫,當(dāng)然HttpURLConnection 或URLConnection也可以。
 static Bitmap downloadBitmapByCwj(String url) { 
 final AndroidHttpClient client = AndroidHttpClient.newInstance("Android123"); 
 final HttpGet getRequest = new HttpGet(url); 
 try { 
  HttpResponse response = client.execute(getRequest); 
  final int statusCode = response.getStatusLine().getStatusCode(); 
  if (statusCode != HttpStatus.SC_OK) { 
   Log.e("cwjDebug", "Error " + statusCode + " while retrieving bitmap from " + url); 
   return null; 
  } 
   
  final HttpEntity entity = response.getEntity(); 
  if (entity != null) { 
   InputStream inputStream = null; 
   try { 
    inputStream = entity.getContent(); 
    final Bitmap bitmap = BitmapFactory.decodeStream(inputStream); 
    return bitmap; 
   } finally { 
    if (inputStream != null) { 
     inputStream.close(); 
    } 
    entity.consumeContent(); 
   } 
  } 
 } catch (Exception e) { 
   getRequest.abort(); 
  Log.e("android123Debug", "Error while retrieving bitmap from " + url, e.toString()); 
 } finally { 
  if (client != null) { 
   client.close(); 
  } 
 } 
 return null; 
}
這里Android開發(fā)網(wǎng)提醒大家,BitmapFactory類的decodeStream方法在網(wǎng)絡(luò)超時(shí)或較慢的時(shí)候無法獲取完整的數(shù)據(jù),這里我們通過繼承FilterInputStream類的skip方法來強(qiáng)制實(shí)現(xiàn)flush流中的數(shù)據(jù),主要原理就是檢查是否到文件末端,告訴http類是否繼續(xù)。
static class FlushedInputStream extends FilterInputStream { 
 public FlushedInputStream(InputStream inputStream) { 
  super(inputStream); 
 } 
 @Override 
 public long skip(long n) throws IOException { 
  long totalBytesSkipped = 0L; 
  while (totalBytesSkipped < n) { 
   long bytesSkipped = in.skip(n - totalBytesSkipped); 
   if (bytesSkipped == 0L) { 
     int byte = read(); 
     if (byte < 0) { 
      break; // we reached EOF 
     } else { 
      bytesSkipped = 1; // we read one byte 
     } 
   } 
   totalBytesSkipped += bytesSkipped; 
  } 
  return totalBytesSkipped; 
 } 
} 
方法二、AsyncTask異步任務(wù)
從Android 1.5固件開始Google提供了一個(gè)AsyncTask類來幫助開發(fā)者處理異步下載的實(shí)現(xiàn),相對(duì)于Thread而言他可以運(yùn)行在UI線程中,其內(nèi)部的實(shí)現(xiàn)是從Java 5開始的并發(fā)包c(diǎn)oncurrent中派生而來的,總體實(shí)現(xiàn)比較可靠就是資源占用略大了些。不過使用起來比簡單。這里下載圖片類 ImageDownloader類的download方法可以很好的處理實(shí)現(xiàn)UI顯示等操作,參數(shù)一url為遠(yuǎn)程server上文件的url,第二個(gè)參數(shù)為imageview對(duì)象,可以直接讓imageview顯示出下載的遠(yuǎn)程圖片。
 public class ImageDownloader { 
 public void download(String url, ImageView imageView) { 
   BitmapDownloaderTask task = new BitmapDownloaderTask(imageView); 
   task.execute(url); 
  } 
 } 
} 
有關(guān)具體的AsyncTask類實(shí)現(xiàn),考慮到圖片可能較大,為了給JVM充分的空間存儲(chǔ),這里Android123推薦大家使用弱引用來保存ImageView對(duì)象。
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> { 
 private String url; 
 private final WeakReference<ImageView> imageViewReference; //使用WeakReference解決內(nèi)存問題 
 public BitmapDownloaderTask(ImageView imageView) { 
  imageViewReference = new WeakReference<ImageView>(imageView); 
 } 
 @Override 
 protected Bitmap doInBackground(String... params) { //實(shí)際的下載線程,內(nèi)部其實(shí)是concurrent線程,所以不會(huì)阻塞 
 
   return downloadBitmap(params[0]); 
 } 
 @Override 
  protected void onPostExecute(Bitmap bitmap) { //下載完后執(zhí)行的 
  if (isCancelled()) { 
   bitmap = null; 
  } 
  if (imageViewReference != null) { 
   ImageView imageView = imageViewReference.get(); 
   if (imageView != null) { 
    imageView.setImageBitmap(bitmap); //下載完設(shè)置imageview為剛才下載的bitmap對(duì)象 
   } 
  } 
 } 
}
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
 Android開發(fā)筆記之:如何屏蔽Button setClickable與setEnabled
本篇文章是對(duì)在Android中,如何屏蔽Button setClickable與setEnabled的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
 Android9.0上針對(duì)Toast的特殊處理圖文詳解
這篇文章主要給大家介紹了關(guān)于Android9.0上針對(duì)Toast的特殊處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
 Android 實(shí)現(xiàn)不同字體顏色的TextView實(shí)現(xiàn)代碼
這篇文章主要介紹了Android 實(shí)現(xiàn)不同字體顏色的TextView實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-05-05
 Android中用onSaveInstanceState保存Fragment狀態(tài)的方法
這篇文章主要介紹了Android中用onSaveInstanceState保存Fragment狀態(tài)的方法,onSaveInstanceState可以將數(shù)據(jù)保存在Fragment或Activity中,需要的朋友可以參考下2016-04-04
 Android開發(fā)筆記 Handler使用總結(jié)
當(dāng)應(yīng)用程序啟動(dòng)時(shí),Android首先會(huì)開啟一個(gè)主線程(也就是UI線程),主線程為管理界面中的UI控件,進(jìn)行事件分發(fā)2012-11-11
 丟失Android系統(tǒng)庫或者Conversion to Dalvik format failed with error
這篇文章主要介紹了丟失Android系統(tǒng)庫或者Conversion to Dalvik format failed with error 1錯(cuò)誤的解決方法,分析了Android系統(tǒng)庫丟失及版本問題的處理技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-12-12

