博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android 内存溢出oom错误的一些小见解
阅读量:5955 次
发布时间:2019-06-19

本文共 2047 字,大约阅读时间需要 6 分钟。

转:

 

我们在代码里调用setBackgroundResource(int resid)来设置一个view控件的背景时,如果图片过大,或者调用setBackgroundResource(int resid)多次时,有可能导致内存溢出.查看代码:

    public void setBackgroundResource(int resid) {

        if (resid != 0 && resid == mBackgroundResource) {
            return;
        }
        Drawable d= null;
        if (resid != 0) {
            d = mResources.getDrawable(resid);
        }
        setBackgroundDrawable(d);
        mBackgroundResource = resid;
    }

可以发现,背景图片最后设置为了一个Drawable对象.Drawable对象占用的内存分为java层的和底层的两部份.JAVA层的内存,如果在你的view释放时,你的背景图片调用了Drawable的setCallback(null), 即取消你的背景图片在VM里的引用,则JAVA这部份的内存空间,在系统调用GC函数时可以把它回收. 但是在native层的内存,GC是释放不了的.这样就会导致有内存泄漏. 解决这个问题的办法有很多种,下面我来说说最简单的一种:

        设置背景时,不要调用setBackgroundResource(int resid),而改用setBackgroundDrawable(Drawable d) 这个函数,这个函数的参数d 用一个BitmapDrawable new出来.上代码:

 

[java] 
 
  1. Bitmap mBgBitmap = null;  
  2.         mBgBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.unlock_bg);  
  3.         setBackgroundDrawable(new BitmapDrawable(mBgBitmap));  

 

这样的好处就是,我们可以保留图片的Bitmap引用mBgBitmap,在我们的VIEW释放时,我们显示的调用

 

[java] 
 
  1. if(mBgBitmap != null  && !mBgBitmap.isRecycled())  
  2.         {  
  3.             mBgBitmap.recycle();  
  4.             mBgBitmap = null;  
  5.         }     

这段代码,就可以把native层的内层也给释放掉,这样就可以彻底解决内存泄漏的问题

 

加上LruCache效果相比更佳

private LruCache mMemoryCache;@Overrideprotected void onCreate(Bundle savedInstanceState) {    ...    // Get memory class of this device, exceeding this amount will throw an    // OutOfMemory exception.    final int memClass = ((ActivityManager) context.getSystemService(            Context.ACTIVITY_SERVICE)).getMemoryClass();    // Use 1/8th of the available memory for this memory cache.    final int cacheSize = 1024 * 1024 * memClass / 8;    mMemoryCache = new LruCache(cacheSize) {        @Override        protected int sizeOf(String key, Bitmap bitmap) {            // The cache size will be measured in bytes rather than number of items.            return bitmap.getByteCount();        }    };    ...}public void addBitmapToMemoryCache(String key, Bitmap bitmap) {    if (getBitmapFromMemCache(key) == null) {        mMemoryCache.put(key, bitmap);    }}public Bitmap getBitmapFromMemCache(String key) {    return mMemoryCache.get(key);}

  

转载地址:http://lyexx.baihongyu.com/

你可能感兴趣的文章
springboot 常用插件
查看>>
一个基于特征向量的近似网页去重算法——term用SVM人工提取训练,基于term的特征向量,倒排索引查询相似文档,同时利用cos计算相似度...
查看>>
[转]Newtonsoft.Json高级用法
查看>>
Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简述及技术选型介绍
查看>>
DFI、DPI技术
查看>>
hibernate 执行存储过程 方法
查看>>
RapidIOIP核的验证方法研究_王玉欢
查看>>
崩溃日志的实例
查看>>
base64是啥原理
查看>>
字符串中去除连续相同的字符保留一个
查看>>
实战 Windows Server 2012 群集共享卷
查看>>
CSS 元素超出部分滚动, 并隐藏滚动条
查看>>
React中那些纠结你的地方(一)
查看>>
Docker入门安装教程
查看>>
PhoneGap极光推送 cordova消息推送
查看>>
Subarray Sum Equals K
查看>>
preventDefault, stopPropagation, stopImmediatePropagation 三者的区别
查看>>
算法题解:找出包含给定字符的最小窗口(枚举的一般方法)
查看>>
超级账本HyperLedger初体验
查看>>
完美解决html中select的option不能隐藏的问题。
查看>>