Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 1177|回复: 0

开发交流:Android多线程下载远程图片

[复制链接]

该用户从未签到

发表于 2011-10-24 10:49:36 | 显示全部楼层 |阅读模式
很多时候我们需要在Android设备上下载远程服务器上的图片进行显示,今天Android123整理出两种比较好的方法来实现远程图片的下载。

  方法一、直接通过Android提供的Http类访问远程服务器,这里AndroidHttpClient是SDK 2.2中新出的方法,API Level为8,大家需要注意下,静态访问可以直接调用,如果SDK版本较低可以考虑Apache的Http库,当然HttpURLConnection或URLConnection也可以。 tatic 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开发网提醒大家,BitmapFactory类的decodeStream方法在网络超时或较慢的时候无法获取完整的数据,这里我们通过继承FilterInputStream类的skip方法来强制实现flush流中的数据,主要原理就是检查是否到文件末端,告诉http类是否继续。 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异步任务

  从Android 1.5固件开始Google提供了一个AsyncTask类来帮助开发者处理异步下载的实现,相对于Thread而言他可以运行在UI线程中,其内部的实现是从java 5开始的并发包concurrent中派生而来的,总体实现比较可靠就是资源占用略大了些。不过使用起来比简单。这里下载图片类ImageDownloader类的download方法可以很好的处理实现UI显示等操作,参数一url为远程server上文件的url,第二个参数为imageview对象,可以直接让imageview显示出下载的远程图片。 public class ImageDownloader {



    public void download(String url, ImageView imageView) {

            BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);

            task.execute(url);

        }

    }



}
复制代码有关具体的AsyncTask类实现,考虑到图片可能较大,为了给JVM充分的空间存储,这里Android123推荐大家使用弱引用来保存ImageView对象。 class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {

    private String url;

    private final WeakReference<ImageView> imageViewReference;  //使用WeakReference解决内存问题



    public BitmapDownloaderTask(ImageView imageView) {

        imageViewReference = new WeakReference<ImageView>(imageView);

    }



    @Override

    protected Bitmap doInBackground(String... params) {   //实际的下载线程,内部其实是concurrent线程,所以不会阻塞

   

         return downloadBitmap(params[0]);   



  }



    @Override

     protected void onPostExecute(Bitmap bitmap) {   //下载完后执行的

        if (isCancelled()) {

            bitmap = null;

        }



        if (imageViewReference != null) {

            ImageView imageView = imageViewReference.get();

            if (imageView != null) {

                imageView.setImageBitmap(bitmap);  //下载完设置imageview为刚才下载的bitmap对象

            }

        }

    }

}
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2024-5-19 02:30 , Processed in 0.365273 second(s), 38 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表