关于加载网络图片时候 ,URL.openstream抛出异常的问题的解决

昨天在写一个带图片的列表页的时候遇到了一些问题

在自定义的ListAdapter中使用如下代码加载网络图片导致抛出NetworkOnMainThreadException异常

URL picUrl = new URL("http://www.abc.com/abc.jpg");Bitmap pngBM = BitmapFactory.decodeStream(picUrl.openStream());img.setImageBitmap(head);

try catch后打印出异常信息,得到NetworkOnMainThreadException异常信息

百度后得知

The exception that is thrown when an application attempts to perform a networking operation on its main thread.


This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it‘s heavily discouraged. See the document Designing for Responsiveness.

解释一下,从Honeycomb SDK(3.0)开始,google不再允许网络请求(HTTP、Socket)等相关操作直接在Main Thread类中,其实本来就不应该这样做,直接在UI线程进行网络操作,会阻塞UI、用户体验相当bad!即便google不禁止,一般情况下我们也不 会这么做吧~ 所以,也就是说,在Honeycomb SDK(3.0)以下的版本,你还可以继续在Main Thread里这样做,在3.0以上,就不行了

修改代码讲图片的网络加载请求放到一个单独的线程或者AsyncTask来完成,一切ok.

还有一个小问题就是Adapter中getView方法View的复用的问题导致图片看起来错位的感觉,是因为View的复用导致图片从新加载钱使用的是其他item的图片,使用LRuCache缓存起来每次加载的图片就可以解决!

public class ImageLoaders extends AsyncTask<String,Void,Bitmap> {    String url = null;    ImageView img = null;    static LruCache<String , Bitmap> imageCache = new LruCache<String , Bitmap>( (int)Runtime.getRuntime().maxMemory()/1024);

    public  ImageLoaders(String Url , ImageView imgView) {        this.url = Url;        this.img = imgView;        //imageCache = new LruCache<String , Bitmap>( (int)Runtime.getRuntime().maxMemory()/1024);

    }

    /**     * Override this method to perform a computation on a background thread. The     * specified parameters are the parameters passed to {@link #execute}     * by the caller of this task.     * <p/>     * This method can call {@link #publishProgress} to publish updates     * on the UI thread.     *     * @param params The parameters of the task.     * @return A result, defined by the subclass of this task.     * @see #onPreExecute()     * @see #onPostExecute     * @see #publishProgress     */    @Override    protected Bitmap doInBackground(String... params) {

        try{            Log.i("img param", params[0]);            Log.i("img cache" , ImageLoaders.imageCache.toString());            if (ImageLoaders.imageCache.get(params[0]) != null)                return ImageLoaders.imageCache.get(params[0]);            //Log.i("img cache" , ImageLoaders.imageCache.get(params[0]));            URL picUrl = new URL(params[0]);

            InputStream is = picUrl.openStream();            Bitmap pngBM = BitmapFactory.decodeStream(is);            Log.i("image data", is.toString());            ImageLoaders.imageCache.put(params[0], pngBM);

            return pngBM;

        }catch (Exception ex) {            ex.printStackTrace();        }

        return null;    }

    /**     * <p>Runs on the UI thread after {@link #doInBackground}. The     * specified result is the value returned by {@link #doInBackground}.</p>     * <p/>     * <p>This method won‘t be invoked if the task was cancelled.</p>     *     * @param head The result of the operation computed by {@link #doInBackground}.     * @see #onPreExecute     * @see #doInBackground     * @see #onCancelled(Object)     */    @Override    protected void onPostExecute(Bitmap head) {        //super.onPostExecute(is);

        img.setImageBitmap(head);    }

}
时间: 2024-10-09 23:44:01

关于加载网络图片时候 ,URL.openstream抛出异常的问题的解决的相关文章

iOS开发swift版异步加载网络图片(带缓存和缺省图片)

iOS开发之swift版异步加载网络图片 与SDWebImage异步加载网络图片的功能相似,只是代码比较简单,功能没有SD的完善与强大,支持缺省添加图片,支持本地缓存. 异步加载图片的核心代码如下:  func setZYHWebImage(url:NSString?, defaultImage:NSString?, isCache:Bool){         var ZYHImage:UIImage?         if url == nil {             return   

iOS_第3方类库_EGOImageView异步加载网络图片

异步加载网络图片是很常见的需求 下载,导入,-fno-objc-arc 1.导入头文件 2.创建EGOImageView,并指定占位图,设置url即可 最终效果图:(后补) 附EGO原文件地址:

UIButton 加载网络图片

以后就可以 用这个分类   UIButton轻松加载网络图片了, UIButton+WebCache.h #import <UIKit/UIKit.h> @interface UIButton (WebCache) - (void)xr_setButtonImageWithUrl:(NSString *)urlStr; @end UIButton+WebCache.m #import "UIButton+WebCache.h" @implementation UIButto

Android Volley入门到精通:使用Volley加载网络图片

在上一篇文章中,我们了解了Volley到底是什么,以及它的基本用法.本篇文章中我们即将学习关于Volley更加高级的用法,如何你还没有看过我的上一篇文章的话,建议先去阅读Android Volley完全解析(一),初识Volley的基本用法. 在上篇文章中有提到过,Volley是将AsyncHttpClient和Universal-Image-Loader的优点集成于一身的一个框架.我们都知道,Universal-Image-Loader具备非常强大的加载网络图片的功能,而使用Volley,我们

ios UIImageView异步加载网络图片

方法1:在UI线程中同步加载网络图片 UIImageView *headview = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)]; NSURL *photourl = [NSURL URLWithString:@"http://www.exampleforphoto.com/pabb/test32.png"]; //url请求实在UI主线程中进行的 UIImage *images = [UIImage ima

Android批量图片加载经典系列——采用二级缓存、异步加载网络图片

一.问题描述 Android应用中经常涉及从网络中加载大量图片,为提升加载速度和效率,减少网络流量都会采用二级缓存和异步加载机制,所谓二级缓存就是通过先从内存中获取.再从文件中获取,最后才会访问网络.内存缓存(一级)本质上是Map集合以key-value对的方式存储图片的url和Bitmap信息,由于内存缓存会造成堆内存泄露, 管理相对复杂一些,可采用第三方组件,对于有经验的可自己编写组件,而文件缓存比较简单通常自己封装一下即可.下面就通过案例看如何实现网络图片加载的优化. 二.案例介绍 案例新

Android中用双缓存技术,加载网络图片

最近在学校参加一个比赛,写的一个Android应用,里面要加载大量的网络图片,可是用传统的方法图片一多就会造成程序出现内存溢出而崩溃.因为自己也在学习中,所以看了很多博客和视频,然后参照这些大神的写源码,自己写了一个加载网络图片工具类. 里面要用到一个经典的图片缓存库DiskLruCache 下载地址为:  DiskLruCache下载 下面是使用这个类实现的 双缓存网络图片加载 [java] view plain copy public class DiskLruCacheUtils { pr

IOS加载网络图片的框架(共有4中方法)

框架名为:UIImage+WebCache.h   继承于UIimageView 框架里面加载网络图片的方法共4中:分别为1.普通加载   2.线程NSThread    3. #import "ViewController.h" #import "UIImage+WebCache.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [su

iOS 开发之 为UIButton添加类别方法加载网络图片

iOS 开发之 为UIButton添加类别方法加载网络图片 使用GCD线程队列实现 工程如下: UIButton+WebCache.h #import <UIKit/UIKit.h> // 为Button添加类别方法 @interface UIButton (WebCache) - (void)xr_setButtonImageWithUrl:(NSString *)urlStr; @end UIButton+WebCache.m #import "UIButton+WebCache