Android线程优先级和进程oom_adj

Android线程优先级和进程oom_adj,第1张

在处理app启动速度的时候,可以设置主线程的优先级,保证主线程占用的cpu足够久。进程的oom_adj,决定了当内存不够的时候,lmk会根据oom_adj的大小依次释放内存。

android中对线程等级划分如下:

设置线程的优先级分为:android 提供的api和java sdk自带的api

注意: 要使用android提供的api设置,用java提供的作用不够显著

作用: 可以在主线程设置主线层等级;在Glide加载图片的时候设置低优先级。当图片量很大的时候可以降低加载图片线程的等级

android内存不够了,会触发oom机制,lowMemoryKiller会根据每个进程的oom_adj的等级,依次杀死进程,释放内存。

lom会根据free的内存的值,来判断kill掉哪个等级下的进程。例如当空闲内存只有64M了。会kill掉oom_adj 为12-15的进程

真实案例:应用A跳到第三方应用B,在第三方应用B中播放视频,加载大量图片,导致返回的时候,应用A走了SplashActivity。通过logcat发现A应用被kill掉了

简单吹下牛:很多app都会要加载图片,但是如果不压缩图片就很容易OOM,

个人看来OOM 出现原因总的来说分为两种:

一种是内存溢出(好像在扯淡,OOM本身就是内存溢出)

另一种是:图片过大,一个屏幕显示不完全造成,似乎也是一。。 如有错误纯属扯淡;

为了避免上面的情况:加载图片的时候可以进行压缩,上传的时候要可以进行压缩,在图片不可见的时候进行回收(onDetach()),再吹一句 用了fresco+压缩之后加载图片完全没问题了。

一、质量压缩方法:

privateBitmap compressImage(Bitmap image) {

ByteArrayOutputStream baos =newByteArrayOutputStream()

image.compress(Bitmap.CompressFormat.JPEG,100, baos)//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中

intoptions =100

while( baos.toByteArray().length /1024>100) {//循环判断如果压缩后图片是否大于100kb,大于继续压缩

baos.reset()//重置baos即清空baos

image.compress(Bitmap.CompressFormat.JPEG, options, baos)//这里压缩options%,把压缩后的数据存放到baos中

options -=10//每次都减少10

}

ByteArrayInputStream isBm =newByteArrayInputStream(baos.toByteArray())//把压缩后的数据baos存放到ByteArrayInputStream中

Bitmap bitmap = BitmapFactory.decodeStream(isBm,null,null)//把ByteArrayInputStream数据生成图片

returnbitmap

}

二、图片按比例大小压缩方法(根据Bitmap图片压缩)

privateBitmap comp(Bitmap image) {

ByteArrayOutputStream baos =newByteArrayOutputStream()

image.compress(Bitmap.CompressFormat.JPEG,100, baos)

if( baos.toByteArray().length /1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出

baos.reset()//重置baos即清空baos

image.compress(Bitmap.CompressFormat.JPEG,50, baos)//这里压缩50%,把压缩后的数据存放到baos中

}

ByteArrayInputStream isBm =newByteArrayInputStream(baos.toByteArray())

BitmapFactory.Options newOpts =newBitmapFactory.Options()

//开始读入图片,此时把options.inJustDecodeBounds 设回true了

newOpts.inJustDecodeBounds =true

Bitmap bitmap = BitmapFactory.decodeStream(isBm,null, newOpts)

newOpts.inJustDecodeBounds =false

intw = newOpts.outWidth

inth = newOpts.outHeight

//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为

floathh = 800f//这里设置高度为800f

floatww = 480f//这里设置宽度为480f

//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可

intbe =1//be=1表示不缩放

if(w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放

be = (int) (newOpts.outWidth / ww)

}elseif(w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放

be = (int) (newOpts.outHeight / hh)

}

if(be <=0)

be =1

newOpts.inSampleSize = be//设置缩放比例

//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了

isBm =newByteArrayInputStream(baos.toByteArray())

bitmap = BitmapFactory.decodeStream(isBm,null, newOpts)

returncompressImage(bitmap)//压缩好比例大小后再进行质量压缩

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/10943132.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-12
下一篇 2023-05-12

发表评论

登录后才能评论

评论列表(0条)

保存