• 安卓加载网络图片OOM问题解决


    前言:次片是上篇后续出现的问题,在网上找了很多博客,越解决越乱,好在最后看了郭霖的博客给了我一点思路

    借鉴http://blog.csdn.net/guolin_blog/article/details/9316683

    请仔细阅读这边博客的说明部分,不要急着看代码(这也是我一贯的做法,其实有时候把说明部分多读读能快速理解代码的意思,事半功倍)

    代码:

    /**
         * 获取网络图片(需要开线程)
         * @param url
         * @return
         */
        public static void getHttpBitmap(final int position, final String url){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        URL myUrl;
                        Bitmap bitmap = null;
                        myUrl = new URL(url);
                        //获得连接
                        HttpURLConnection conn = (HttpURLConnection)myUrl.openConnection();
                        //设置超时时间为6000毫秒,conn.setConnectionTiem(0);表示没有时间限制
                        conn.setConnectTimeout(6000);
                        //连接设置获得数据流
                        conn.setDoInput(true);
                        //不使用缓存
                        conn.setUseCaches(false);
                        //此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP请求正文的流
                        conn.setChunkedStreamingMode(51200); // 128K
                        //这句可有可无,没有影响
                        //conn.connect();
                        //得到数据流
                        InputStream is = conn.getInputStream();
                        if (is != null){
                            BitmapFactory.Options options = new BitmapFactory.Options();
                            options.inJustDecodeBounds = true;
                            byte [] data = inputStream2ByteArr(is);
                            BitmapFactory.decodeByteArray(data,0,data.length,options);
                            options.inSampleSize = calculateInSampleSize(options,146,146);
                            options.inJustDecodeBounds = false;
                            //解析得到图片
                            bitmap = BitmapFactory.decodeByteArray(data,0,data.length,options);
                            // EventBus
                            EventBus.getDefault().post(new MyEventBus(MyEventBus.EVENT_CREATE_BITMAP,position,bitmap)); //可以注释掉,请不要在意这部分,这里是通过EventBus将bitmap传递个Activity,读者测试可用Handle,
                        }
    
                        //关闭数据流
                        is.close();
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                }
            }){}.start();
        }
    
    
    
        /**
         * 输入流转成字节数组(重复读取)
         * @param inputStream
         * @return
         * @throws IOException
         */
    
        public static byte[] inputStream2ByteArr(InputStream inputStream) throws IOException {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            byte[] buff = new byte[1024];
            int len = 0;
            while ( (len = inputStream.read(buff)) != -1) {
                outputStream.write(buff, 0, len);
            }
            inputStream.close();
            outputStream.close();
            return outputStream.toByteArray();
        }
    
        /**
         * 计算options.InSampleSize值 此算法可根据需求改动
         * @param options
         * @param reqWidth 期望宽
         * @param reqHeight 期望高
         * @return
         */
    
        public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
            // 源图片的高度和宽度
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;
            if (height > reqHeight || width > reqWidth) {
                // 计算出实际宽高和目标宽高的比率
                final int heightRatio = Math.round((float) height / (float) reqHeight);
                final int widthRatio = Math.round((float) width / (float) reqWidth);
                // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
                // 一定都会大于等于目标的宽和高。
                inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
            }
            return inSampleSize;
        }
    

    注意几点:

    1、(郭霖博客中)

    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
    

     设置为true 时,返回的BitMap 将为 Null

    2、读取网络图片用的是decodeStream,但是此处却不能直接这样用,为何,这里总共会读取两次,而第二次读的时候流已经改变,所以最后一次读取的是null,这里用字节数组存储流,以后可以多次使用

    这里在推荐一遍博客:https://blog.csdn.net/xiejc01/article/details/17421957

     

  • 相关阅读:
    链表实现
    @Aspect
    mybatis plus
    using
    50道题
    梦想,青春,时间
    存储过程!!!
    事务,视图,索引
    高级查询--嵌套和相关,两套分页!!!
    学习笔记
  • 原文地址:https://www.cnblogs.com/linwen5723/p/9150293.html
Copyright © 2020-2023  润新知