Android底下多线程下载远程图片

  1. 在某些时候我们需要在Android设备上下载远端服务器上的图片来进行显示,这里我整理出两种比较好的方法来实现远程图片的下载。  
  2.   
  3.   方法一、直接通过Android官方提供的Http类访来问远程服务器,这里AndroidHttpClient是SDK 2.2中新出的方法,API Level为8,大家需要注意下,静态访问可以直接调用,如果SDK版本较低可以考虑Apache的Http库,当然HttpURLConnection或URLConnection也可以。  
  4.   
  5.     static Bitmap downloadBitmap(String url) {  
  6.         final AndroidHttpClient client = AndroidHttpClient.newInstance("linux初学三月");  
  7.         final HttpGet getRequest = new HttpGet(url);  
  8.   
  9.         try {  
  10.             HttpResponse response = client.execute(getRequest);  
  11.             final int statusCode = response.getStatusLine().getStatusCode();  
  12.             if (statusCode != HttpStatus.SC_OK) {    
  13.                 Log.e("cwjDebug""Error " + statusCode + " while retrieving bitmap from " + url);    
  14.                 return null;  
  15.             }  
  16.                
  17.             final HttpEntity entity = response.getEntity();  
  18.             if (entity != null) {  
  19.                 InputStream inputStream = null;  
  20.                 try {  
  21.                     inputStream = entity.getContent();    
  22.                     final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);  
  23.                     return bitmap;  
  24.                 } finally {  
  25.                     if (inputStream != null) {  
  26.                         inputStream.close();     
  27.                     }  
  28.                     entity.consumeContent();  
  29.                 }  
  30.             }  
  31.         } catch (Exception e) {  
  32.               getRequest.abort();  
  33.             Log.e("Debug""Error while retrieving bitmap from " + url, e.toString());  
  34.         } finally {  
  35.             if (client != null) {  
  36.                 client.close();  
  37.             }  
  38.         }  
  39.         return null;  
  40.     }  
  41.   
  42. 复制代码  
  43. 这里提醒大家,BitmapFactory类的decodeStream方法在网络超时或较慢的时候无法获取完整的数据,这里我们通过继承FilterInputStream类的skip方法来强制实现flush流中的数据,主要原理就是检查是否到文件末端,告诉http类是否继续。  
  44.     //这个方法没有使用到
  45.     static class FlushedInputStream extends FilterInputStream {  
  46.         public FlushedInputStream(InputStream inputStream) {  
  47.             super(inputStream);  
  48.         }  
  49.   
  50.         @Override  
  51.         public long skip(long n) throws IOException {  
  52.             long totalBytesSkipped = 0L;  
  53.             while (totalBytesSkipped < n) {  
  54.                 long bytesSkipped = in.skip(n - totalBytesSkipped);  
  55.                 if (bytesSkipped == 0L) {  
  56.                       int byte = read();  
  57.                       if (byte < 0) {  
  58.                           break;  // we reached EOF  
  59.                       } else {  
  60.                           bytesSkipped = 1// we read one byte  
  61.                       }  
  62.                }  
  63.                 totalBytesSkipped += bytesSkipped;  
  64.             }  
  65.             return totalBytesSkipped;  
  66.         }  
  67.     }  
  68.   
  69. 复制代码  
  70. 方法二、通过AsyncTask的异步任务  
  71.   
  72.   从Android 1.5固件开发平台开始Google提供了一个AsyncTask类来帮助开发者处理异步下载的实现,相对于Thread线程而言他可以运行在UI线程中,其内部的实现是从Java 5开始的并发包concurrent中派生而来的,总体实现比较可靠就是资源占用略大了些。不过使用起来比简单。这里下载图片类ImageDownloader类的download方法可以很好的处理实现UI显示等操作,参数一url为远程server上文件的url,第二个参数为imageview对象,可以直接让imageview显示出下载的远程图片。  
  73.   
  74.     public class ImageDownloader {  
  75.   
  76.         public void download(String url, ImageView imageView) {  
  77.                 BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);  
  78.                 task.execute(url);  
  79.             }  
  80.         }  
  81.   
  82.     }  
  83.   
  84. 复制代码  
  85. 有关具体的AsyncTask类实现,考虑到图片可能较大,为了给JVM充分的空间存储,这里推荐大家使用弱引用来保存ImageView对象。  
  86.   
  87.     class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {  
  88.         private String url;  
  89.         private final WeakReference<ImageView> imageViewReference;  //使用WeakReference解决内存问题  
  90.   
  91.         public BitmapDownloaderTask(ImageView imageView) {  
  92.             imageViewReference = new WeakReference<ImageView>(imageView);  
  93.         }  
  94.   
  95.   
  96.       @Override  
  97.         protected Bitmap doInBackground(String... params) {   //实际的下载线程,内部其实是concurrent线程,所以不会阻塞  
  98.          
  99.              return downloadBitmap(params[0]);     //这方法在前面方法一中
  100.   
  101.       }  
  102.   
  103.         @Override  
  104.          protected void onPostExecute(Bitmap bitmap) {   //下载完后执行的  
  105.             if (isCancelled()) {  
  106.                 bitmap = null;  
  107.             }  
  108.   
  109.             if (imageViewReference != null) {  
  110.                 ImageView imageView = imageViewReference.get();  
  111.                 if (imageView != null) {  
  112.                     imageView.setImageBitmap(bitmap);  //下载完设置imageview为刚才下载的bitmap对象  
  113.                 }  
  114.             }  
  115.         }  
  116.     }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值