安卓软引用解决图片OOM问题
最后更新于:2022-04-01 14:43:46
软引用是解决加载大量图片OOM问题的一个很好的思路,之前介绍了用LRUCACHE的策略了,这两个策略应该说是缓存的最好的两个策略吧。
系统在GC的时候会检查软引用,在内存不足的时候会回收掉只有软引用的对象(这里存在一些疑惑,回收是所有只有软引用的对象都回收呢还是按照某些策略回收其中的一些呢?我还要研究下)。
下面这个应用的目标是做动画效果,原本想用安卓里面的逐帧动画来做的,但是发现内存是个很大的问题,而自己对动画这部分又不是很了解,所以最后还是设计一个定时器70MS刷一次算了。用了软引用队列保存图片资源,但是命中率不是很好,还需要改进一下。
下面是代码:
~~~
package com.example.anima;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv;
private ArrayList<SoftReference<Drawable>> drawables;
// 在timer中更新
private int drawIndex = -1;
private int drawAmount = 0;
private ArrayList<Integer> picId;
private Timer timer = null;
private Handler handler = new Handler() {
@SuppressLint("NewApi")
public void handleMessage(android.os.Message msg) {
Drawable drawable = drawables.get(drawIndex).get();
System.out.println(drawIndex+" " +(drawable==null));
iv.setBackground(drawable);
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initPicName();
iv = (ImageView) findViewById(R.id.aniPic);
drawables = new ArrayList<SoftReference<Drawable>>();
timer = new Timer(true);
timer.scheduleAtFixedRate(task, 0, 70);
}
/**
* 在计数器里面进行标号的更新和图片软引用的处理
*/
private TimerTask task = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
drawIndex ++;
drawIndex %= drawAmount;
SoftReference<Drawable> ref = null;
try {
ref = drawables.get(drawIndex);
Drawable refDraw = ref.get();
if (refDraw == null) {
System.out.println("fffffffffffffff");
Drawable drawable = getResources().getDrawable(picId.get(drawIndex));
ref = new SoftReference<Drawable>(drawable);
drawables.set(drawIndex, ref);
}
} catch (IndexOutOfBoundsException e) {
// TODO Auto-generated catch block
Drawable drawable = getResources().getDrawable(picId.get(drawIndex));
ref = new SoftReference<Drawable>(drawable);
drawables.add(ref);
}finally {
Message msg = Message.obtain();
handler.sendMessage(msg);
}
}
};
/**
* 初始化picNames,也就是获得动画每一帧图片资源名称
*/
private void initPicName() {
picId = new ArrayList<Integer>();
picId.add(R.drawable.man1);
picId.add(R.drawable.man2);
picId.add(R.drawable.man3);
picId.add(R.drawable.man4);
picId.add(R.drawable.man5);
picId.add(R.drawable.man6);
picId.add(R.drawable.man7);
picId.add(R.drawable.man8);
picId.add(R.drawable.man9);
picId.add(R.drawable.man10);
drawAmount = picId.size();
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
timer.cancel();
super.onPause();
}
}
~~~