軟引用是解決加載大量圖片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();
}
}