- 浏览: 592286 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
kangh:
转载的也拿出来 都不试一下 完全错误
Nginx+ffmpeg的HLS开源服务器搭建配置及开发详解 -
wangtxlz:
#cd builders/cmake#cmake .系统提示命 ...
crtmpserver流媒体服务器的介绍与搭建 -
hnraysir:
支持支持支持
手机Android音视频采集与直播推送,实现单兵、移动监控类应用 -
wuent:
把web服务器和php框架绑定到一起?真不建议这样。。。
Swoole(PHP高级Web开发框架) -
wuent:
有更详细的性能比较吗?php,python,java
PHP中的(伪)多线程与多进程
在编写Android程序的时候,我们总是难免会碰到OOM(OUT OF MEMORY)的错误,那么这个错误究竟是怎么来的呢,可以先看一下这篇文章ANDROID BITMAP内存限制OOM,OUT OF MEMORY。
这里,我使用Gallery来举例,在模拟器中,不会出现OOM错误,但是,一旦把程序运行到真机里,图片文件一多,必然会出现OOM,我们通过做一些额外的处理来避免。
1.创建一个图片缓存对象HashMap<Integer,Bitmap> dataCache,integer对应Adapter中的位置position,我们只用缓存处在显示中的图片,对于之外的位置,如果dataCache中有对应的图片,我们需要进行回收内存。在这个例子中,Adapter对象的getView方法首先判断该位置是否有缓存的bitmap,如果没有,则解码图片(bitmapDecoder.getPhotoItem,BitmapDecoder类见后面)并返回bitmap对象,设置dataCache在该位置上的bitmap缓存以便之后使用;若是该位置存在缓存,则直接取出来使用,避免了再一次调用底层的解码图像需要的内存开销。有时为了提高Gallery的更新速度,我们还可以预存储一些位置上的bitmap,比如存储显示区域位置外向上3个向下3个位置的bitmap,这样上或下滚动Gallery时可以加快getView的获取。
Java代码
Java代码
2.由于Gallery控件的特点,总有一个item处于当前选择状态,我们利用此时进行dataCache中额外不用的bitmap的清理,来释放内存。
Java代码
这里,我使用Gallery来举例,在模拟器中,不会出现OOM错误,但是,一旦把程序运行到真机里,图片文件一多,必然会出现OOM,我们通过做一些额外的处理来避免。
1.创建一个图片缓存对象HashMap<Integer,Bitmap> dataCache,integer对应Adapter中的位置position,我们只用缓存处在显示中的图片,对于之外的位置,如果dataCache中有对应的图片,我们需要进行回收内存。在这个例子中,Adapter对象的getView方法首先判断该位置是否有缓存的bitmap,如果没有,则解码图片(bitmapDecoder.getPhotoItem,BitmapDecoder类见后面)并返回bitmap对象,设置dataCache在该位置上的bitmap缓存以便之后使用;若是该位置存在缓存,则直接取出来使用,避免了再一次调用底层的解码图像需要的内存开销。有时为了提高Gallery的更新速度,我们还可以预存储一些位置上的bitmap,比如存储显示区域位置外向上3个向下3个位置的bitmap,这样上或下滚动Gallery时可以加快getView的获取。
Java代码
public View getView(int position, View convertView, ViewGroup parent) { if(convertView==null){ LayoutInflater inflater = LayoutInflater.from(context); convertView = inflater.inflate(R.layout.photo_item, null); holder = new ViewHolder(); holder.photo = (ImageView) convertView.findViewById(R.id.photo_item_image); holder.photoTitle = (TextView) convertView.findViewById(R.id.photo_item_title); holder.photoDate = (TextView) convertView.findViewById(R.id.photo_item_date); convertView.setTag(holder); }else { holder = (ViewHolder) convertView.getTag(); } cursor.moveToPosition(position); Bitmap current = dateCache.get(position); if(current != null){//如果缓存中已解码该图片,则直接返回缓存中的图片 holder.photo.setImageBitmap(current); }else { current = bitmapDecoder.getPhotoItem(cursor.getString(1), 2) ; holder.photo.setImageBitmap(current); dateCache.put(position, current); } holder.photoTitle.setText(cursor.getString(2)); holder.photoDate.setText(cursor.getString(4)); return convertView; } public View getView(int position, View convertView, ViewGroup parent) { if(convertView==null){ LayoutInflater inflater = LayoutInflater.from(context); convertView = inflater.inflate(R.layout.photo_item, null); holder = new ViewHolder(); holder.photo = (ImageView) convertView.findViewById(R.id.photo_item_image); holder.photoTitle = (TextView) convertView.findViewById(R.id.photo_item_title); holder.photoDate = (TextView) convertView.findViewById(R.id.photo_item_date); convertView.setTag(holder); }else { holder = (ViewHolder) convertView.getTag(); } cursor.moveToPosition(position); Bitmap current = dateCache.get(position); if(current != null){//如果缓存中已解码该图片,则直接返回缓存中的图片 holder.photo.setImageBitmap(current); }else { current = bitmapDecoder.getPhotoItem(cursor.getString(1), 2) ; holder.photo.setImageBitmap(current); dateCache.put(position, current); } holder.photoTitle.setText(cursor.getString(2)); holder.photoDate.setText(cursor.getString(4)); return convertView; } }BitmapDecoder.class
Java代码
package com.wuyi.bestjoy; import java.io.FileNotFoundException; import java.io.FileOutputStream; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; public class BitmapDecoder { private static final String TAG = "BitmapDecoder"; private Context context; public BitmapDecoder(Context context) { this.context = context; } public Bitmap getPhotoItem(String filepath,int size) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize=size; Bitmap bitmap = BitmapFactory.decodeFile(filepath,options); bitmap=Bitmap.createScaledBitmap(bitmap, 180, 251, true);//预先缩放,避免实时缩放,可以提高更新率 return bitmap; } } package com.wuyi.bestjoy; import java.io.FileNotFoundException; import java.io.FileOutputStream; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; public class BitmapDecoder { private static final String TAG = "BitmapDecoder"; private Context context; public BitmapDecoder(Context context) { this.context = context; } public Bitmap getPhotoItem(String filepath,int size) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize=size; Bitmap bitmap = BitmapFactory.decodeFile(filepath,options); bitmap=Bitmap.createScaledBitmap(bitmap, 180, 251, true);//预先缩放,避免实时缩放,可以提高更新率 return bitmap; } }
2.由于Gallery控件的特点,总有一个item处于当前选择状态,我们利用此时进行dataCache中额外不用的bitmap的清理,来释放内存。
Java代码
@Override public void onItemSelected(AdapterView<?> parent, View view, int position,long id) { releaseBitmap(); Log.v(TAG, "select id:"+ id); } private void releaseBitmap(){ //在这,我们分别预存储了第一个和最后一个可见位置之外的3个位置的bitmap //即dataCache中始终只缓存了(M=6+Gallery当前可见view的个数)M个bitmap int start = mGallery.getFirstVisiblePosition()-3; int end = mGallery.getLastVisiblePosition()+3; Log.v(TAG, "start:"+ start); Log.v(TAG, "end:"+ end); //释放position<start之外的bitmap资源 Bitmap delBitmap; for(int del=0;del<start;del++){ delBitmap = dateCache.get(del); if(delBitmap != null){ //如果非空则表示有缓存的bitmap,需要清理 Log.v(TAG, "release position:"+ del); //从缓存中移除该del->bitmap的映射 dateCache.remove(del); delBitmap.recycle(); } } freeBitmapFromIndex(end); } /** * 从某一位置开始释放bitmap资源 * @param index */ private void freeBitmapFromIndex(int end) { //释放之外的bitmap资源 Bitmap delBitmap; for(int del =end+1;del<dateCache.size();del++){ delBitmap = dateCache.get(del); if(delBitmap != null){ dateCache.remove(del); delBitmap.recycle(); Log.v(TAG, "release position:"+ del); } } } @Override public void onItemSelected(AdapterView<?> parent, View view, int position,long id) { releaseBitmap(); Log.v(TAG, "select id:"+ id); } private void releaseBitmap(){ //在这,我们分别预存储了第一个和最后一个可见位置之外的3个位置的bitmap //即dataCache中始终只缓存了(M=6+Gallery当前可见view的个数)M个bitmap int start = mGallery.getFirstVisiblePosition()-3; int end = mGallery.getLastVisiblePosition()+3; Log.v(TAG, "start:"+ start); Log.v(TAG, "end:"+ end); //释放position<start之外的bitmap资源 Bitmap delBitmap; for(int del=0;del<start;del++){ delBitmap = dateCache.get(del); if(delBitmap != null){ //如果非空则表示有缓存的bitmap,需要清理 Log.v(TAG, "release position:"+ del); //从缓存中移除该del->bitmap的映射 dateCache.remove(del); delBitmap.recycle(); } } freeBitmapFromIndex(end); } /** * 从某一位置开始释放bitmap资源 * @param index */ private void freeBitmapFromIndex(int end) { //释放之外的bitmap资源 Bitmap delBitmap; for(int del =end+1;del<dateCache.size();del++){ delBitmap = dateCache.get(del); if(delBitmap != null){ dateCache.remove(del); delBitmap.recycle(); Log.v(TAG, "release position:"+ del); } } }经过这些额外的操作,有效的避免了OOM的问题。
发表评论
-
Android之SurfaceView实现视频播放
2016-03-22 00:53 7911.案例一 布局文件: <?xml ver ... -
谈谈Android中的SurfaceTexture
2016-03-22 00:52 750由于很多人要代码,我把代码下载链接放在这里了。不过还是要说一 ... -
Android 5.0(Lollipop)中的SurfaceTexture,TextureView,
2016-03-22 00:37 1382SurfaceView, GLSurfaceView, Su ... -
TextureView+SurfaceTexture+OpenGL ES来播放视频(一)
2016-03-22 00:34 1358文/子雷(简书作者) ... -
Android画图最基本的三个对象(Color,Paint,Canvas)
2015-11-29 15:41 0Android画图最基本的三个对象(Color,Paint, ... -
android资源地址
2015-11-08 15:31 0Android Fragment 真正的完全解析 ... -
关于android分辨率兼容问题(一)
2015-11-07 16:38 833关于手机分辨率相关术语和概念 屏幕尺寸:实际 ... -
并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
2015-03-17 11:01 1093在Java多线程应用中,队列的使用率很高,多数生产消费模型的 ... -
RabbitMQ (五)主题(Topic)
2015-02-27 17:05 0转载请标明出处:http://blog.csdn.net/l ... -
RabbitMQ (四) 路由选择 (Routing)
2015-02-27 17:04 0上一篇博客我们建立了一个简单的日志系统,我们能够广播日志消 ... -
RabbitMQ (三) 发布/订阅
2015-02-27 17:02 1210转发请标明出处:http://blog.csdn.net/l ... -
RabbitMQ (二)工作队列
2015-02-27 17:01 1236转载请标明出处:http:/ ... -
RabbitMQ 入门 Helloworld
2015-02-27 17:00 1140转载请标明出处:http://blog.csdn.net/l ... -
Android之NDK开发
2015-01-20 16:20 614一、NDK产生的背景 ... -
Android推送方案分析(MQTT/XMPP/GCM)
2015-01-18 20:18 1072方案1、 使用GCM服务(Go ... -
android AsyncTask
2014-12-22 16:44 759/** * AsyncTask是抽象类, ... -
Androidndk开发打包时我们应该如何注意平台的兼容(x86,arm,arm-v7a)
2014-12-17 17:44 1228很多朋友在开发Android JNI的的时候,会遇到fi ... -
android对html支持接口总结
2014-12-15 16:40 700项目中往往需要显示一段文本,如果对文本需要特定的效果,就 ... -
Smali基本语法
2014-11-10 23:30 0.field private isFlag:z 定义变量 ... -
android的Environment类
2014-11-10 23:29 737String MEDIA_BAD_REMO ...
相关推荐
ANDROIDBITMAP内存限制OOM,OUTOFMEMORY.pdf
android bitmap outofMemory 用来解决android中常见的bitmap outOfMemory
ANDROIDBITMAP内存限制OOM,OUTOFMEMORY[文].pdf
处理bitmap内存溢出问题
Bitmap内存限制 by 7dot9's Laputa,保存的网页
Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts); 设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,即opts.width和opts.height。有了这两个参数,再通过...
测试图片占用的内存大小,测试空bitmap和一张真实图片的内存大小对比,测试bitmap内存释放,测试bitmap优化后占内存大小等,理清bitmap到底怎么一回事,主要的类是BitmapDemo.java,csdn博客讲解:...
大家应该知道,我们编写的应用程序都是有一定内存限制的,程序占用了过高的内存就容易出现OOM(OutOfMemory)异常。我们可以通过下面的代码看出每个应用程序最高可用内存是多少。 int maxMemory = (int) (Runtime.
bitmap内存管理 google官方提供的demo
测试图片占用的内存大小,测试空bitmap和一张真实图片的内存大小对比,测试bitmap内存释放,测试bitmap优化后占内存大小等,理清bitmap到底怎么一回事,主要的类是BitmapDemo.java
Converting a bitmap to a region - memory leak fix将一个位图转换成一个区域--内存泄露的修正(4KB)
可以很好的出来android开发过程中,由bitmap导致的内存溢出的问题。
Converting a bitmap to a region - memory leak fix将位图转化为一个区域 - 修补了内存漏洞(179KB)
C#下读取、修改位置Bitmap,以及几种不同方法修改位图数据
c#.net Bitmap类的基本使用方法
Bitmap方法C语言实现,支持插入、删除和查找功能。
主要介绍了 Android canvas drawBitmap方法详解及实例的相关资料,需要的朋友可以参考下
Bitmap类的构造方法都是私有的,所以开发者不能直接new出一个Bitmap对象,只能通过BitmapFactory类的各种静态方法来实例化一个Bitmap。仔细查看BitmapFactory的源代码可以看到,生成Bitmap对象最终都是通过JNI调用...
通过压缩Bitmap来避免OOM,相关博文:http://www.cnblogs.com/tianzhijiexian/p/4254110.html