android多线程下载图片
生活随笔
收集整理的這篇文章主要介紹了
android多线程下载图片
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
很多時(shí)候我們需要在Android設(shè)備上下載遠(yuǎn)程服務(wù)器上的圖片進(jìn)行顯示,今天Android123整理出兩種比較好的方法來(lái)實(shí)現(xiàn)遠(yuǎn)程圖片的下載。?
? 方法一、直接通過Android提供的Http類訪問遠(yuǎn)程服務(wù)器,這里AndroidHttpClient是SDK 2.2中新出的方法,API Level為8,大家需要注意下,靜態(tài)訪問可以直接調(diào)用,如果SDK版本較低可以考慮Apache的Http庫(kù),當(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í)候無(wú)法獲取完整的數(shù)據(jù),這里我們通過繼承FilterInputStream類的skip方法來(lái)強(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類來(lái)幫助開發(fā)者處理異步下載的實(shí)現(xiàn),相對(duì)于Thread而言他可以運(yùn)行在UI線程中,其內(nèi)部的實(shí)現(xiàn)是從Java 5開始的并發(fā)包c(diǎn)oncurrent中派生而來(lái)的,總體實(shí)現(xiàn)比較可靠就是資源占用略大了些。不過使用起來(lái)比簡(jiǎ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推薦大家使用弱引用來(lái)保存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ì)象?
??????????? }?
??????? }?
??? }?
}
? 方法一、直接通過Android提供的Http類訪問遠(yuǎn)程服務(wù)器,這里AndroidHttpClient是SDK 2.2中新出的方法,API Level為8,大家需要注意下,靜態(tài)訪問可以直接調(diào)用,如果SDK版本較低可以考慮Apache的Http庫(kù),當(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í)候無(wú)法獲取完整的數(shù)據(jù),這里我們通過繼承FilterInputStream類的skip方法來(lái)強(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類來(lái)幫助開發(fā)者處理異步下載的實(shí)現(xiàn),相對(duì)于Thread而言他可以運(yùn)行在UI線程中,其內(nèi)部的實(shí)現(xiàn)是從Java 5開始的并發(fā)包c(diǎn)oncurrent中派生而來(lái)的,總體實(shí)現(xiàn)比較可靠就是資源占用略大了些。不過使用起來(lái)比簡(jiǎ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推薦大家使用弱引用來(lái)保存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ì)象?
??????????? }?
??????? }?
??? }?
}
總結(jié)
以上是生活随笔為你收集整理的android多线程下载图片的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PendingIntent详解
- 下一篇: Android多线程分析之一:使用Thr