在处理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)//压缩好比例大小后再进行质量压缩
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)