安卓加载网络图片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
安卓加载网络图片OOM问题解决的更多相关文章
- (BUG已修改,最优化)安卓ListView异步加载网络图片与缓存软引用图片,线程池,只加载当前屏之说明
原文:http://blog.csdn.net/java_jh/article/details/20068915 迟点出更新的.这个还有BUG.因为软引应不给力了.2.3之后 前几天的原文有一个线程管 ...
- android官方开源的高性能异步加载网络图片的Gridview例子
这个是我在安卓安卓巴士上看到的资料,放到这儿共享下.这个例子android官方提供的,其中讲解了如何异步加载网络图片,以及在gridview中高效率的显示图片此代码很好的解决了加载大量图片时,报OOM ...
- ViewPager做图片浏览器,加载大量图片OOM的问题修正
/** * @author CHQ * @version 1.0 * @date 创建时间: 2016/7/26 17:18 * @parameter * @return * 图片查看器 * //可以 ...
- Android Volley入门到精通:使用Volley加载网络图片
在上一篇文章中,我们了解了Volley到底是什么,以及它的基本用法.本篇文章中我们即将学习关于Volley更加高级的用法,如何你还没有看过我的上一篇文章的话,建议先去阅读Android Volley完 ...
- Android中用双缓存技术,加载网络图片
最近在学校参加一个比赛,写的一个Android应用,里面要加载大量的网络图片,可是用传统的方法图片一多就会造成程序出现内存溢出而崩溃.因为自己也在学习中,所以看了很多博客和视频,然后参照这些大神的写源 ...
- Google官方网络框架-Volley的使用解析Json以及加载网络图片方法
Google官方网络框架-Volley的使用解析Json以及加载网络图片方法 Volley是什么? Google I/O 大会上,Google 推出 Volley的一个网络框架 Volley适合什么场 ...
- 详解ListView加载网络图片的优化,让你轻松掌握!
详解ListView加载网络图片的优化,让你轻松掌握! 写博客辛苦了,转载的朋友请标明出处哦,finddreams(http://blog.csdn.net/finddreams/article/de ...
- Android Volley完全解析(二),使用Volley加载网络图片
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17482165 在上一篇文章中,我们了解了Volley到底是什么,以及它的基本用法. ...
- ImageView和使用第三方库加载网络图片
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android: ...
随机推荐
- 锋利的jquery 事件 动画
事件 $(function){} bind(type, [data],function) 事件类型, 传递参数, 处理函数 hover(enter, leave) 光标停留时,函数enter,离开时函 ...
- Java正则表达式过滤并消除非法字符
package sd; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * @author 大汉 * */ ...
- js高级1
1.每一个元素身上的事件都是天生自带的,不需要我们去定义,只需要我们给这个事件绑定的方法,当事件触发的时候就会执行这个方法. 2.事件绑定的方法 1,div.onclick=function(){} ...
- 中文乱码总结之web乱码情景
情景1.当servlet返回js脚本时弹出框显示中文乱码: 解决:在servlet中加上response.setContentType(“text/html;charset=utf-8”); 情景2. ...
- 在利用node连接数据库遇到的问题
本文持续更新 选择数据库时: connection.query('USE ' + dbName,function(err,rows){ //注意USE后面需要加一个空格,最终才能拼成> USE ...
- 洛谷P3388 【模板】割点(割顶)
题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照 ...
- SSZipArchive解压乱码
https://www.twblogs.net/a/5b7e01e22b7177683854b7b8/zh-cn 搜索 CFStringConvertEncodingToNSStringEncod ...
- python摸爬滚打之day28----黏包处理
1.缓冲区和subprocess模块 1.1 缓冲区( 当send()内容超过输入缓冲区大小或recv()接收内容超过输出缓冲区大小时旧版本(py3.5以前)是会直接报错的, py3.5以后如果出错 ...
- docker的安装和升级
1.删除docker sudo apt-get purge docker.io sudo rm -rf /etc/docker/ sudo apt-get autoremove 2. 安装docker ...
- pandas(二)
层级索引: index=[('a',2010),('b',2011),('c',2010'),('a',2012),('e',2010),('f',2011)] age=[18,17,18,16,18 ...