我有一个 viewPager,我在其中保存片段,每个片段都有一个 GifDecoderView
public class GifDecoderView extends ImageView {
private boolean mIsPlayingGif = false;
private GifDecoder mGifDecoder;
private Bitmap mTmpBitmap;
final Handler mHandler = new Handler();
final Runnable mUpdateResults = new Runnable() {
public void run() {
if (mTmpBitmap != null && !mTmpBitmap.isRecycled()) {
GifDecoderView.this.setImageBitmap(mTmpBitmap);
}
}
};
public GifDecoderView(Context context, InputStream stream) {
super(context);
playGif(stream);
}
public GifDecoderView(Context context, AttributeSet attrs) {
super(context,attrs);
}
public void doNothing(){
//do nothing
int a = 2+2;
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
}
public void playGif(InputStream stream) {
mGifDecoder = new GifDecoder();
mGifDecoder.read(stream);
mIsPlayingGif = true;
new Thread(new Runnable() {
public void run() {
final int n = mGifDecoder.getFrameCount();
final int ntimes = mGifDecoder.getLoopCount();
int repetitionCounter = 0;
do {
for (int i = 0; i < n; i++) {
mTmpBitmap = mGifDecoder.getFrame(i);
int t = mGifDecoder.getDelay(i);
mHandler.post(mUpdateResults);
try {
Thread.sleep(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(ntimes != 0) {
repetitionCounter ++;
}
} while (mIsPlayingGif && (repetitionCounter <= ntimes));
GifDecoderView.this.setImageResource(0);
for (int i = 0; i < n; i++) {
mGifDecoder.getFrame(i).recycle();
}
mGifDecoder = null;
}
}).start();
}
public void stopRendering() {
mIsPlayingGif = false;
}
}
由于 gif 占用大量内存,我想在用户滑动到另一个页面后删除 gif,所以我使用
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser == true) { Log.i("img","visible");}
else if (isVisibleToUser == false) { if(done){iv.stopRendering(); Log.i("img","DESTROYED");} }
}
调用
public void stopRendering() {
mIsPlayingGif = false;
}
因此线程停止循环并执行
} while (mIsPlayingGif && (repetitionCounter <= ntimes));
GifDecoderView.this.setImageResource(0);
for (int i = 0; i < n; i++) {
mGifDecoder.getFrame(i).recycle();
}
mGifDecoder = null;
如果我通过向左滑动而不是看到空视图返回到上一个片段,我会收到此错误:
11-25 13:19:21.721: E/AndroidRuntime(697): Uncaught handler: thread main exiting due to uncaught exception
11-25 13:19:21.759: E/AndroidRuntime(697): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@44d24e10
11-25 13:19:21.759: E/AndroidRuntime(697): at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.graphics.Canvas.drawBitmap(Canvas.java:1044)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:323)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.widget.ImageView.onDraw(ImageView.java:845)
11-25 13:19:21.759: E/AndroidRuntime(697): at com.example.test.GifDecoderView.onDraw(GifDecoderView.java:45)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.View.draw(View.java:6535)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.View.draw(View.java:6538)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.View.draw(View.java:6538)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.support.v4.view.ViewPager.draw(ViewPager.java:2094)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.View.draw(View.java:6538)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.widget.FrameLayout.draw(FrameLayout.java:352)
11-25 13:19:21.759: E/AndroidRuntime(697): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1830)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewRoot.draw(ViewRoot.java:1349)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewRoot.performTraversals(ViewRoot.java:1114)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.os.Handler.dispatchMessage(Handler.java:99)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.os.Looper.loop(Looper.java:123)
11-25 13:19:21.759: E/AndroidRuntime(697): at android.app.ActivityThread.main(ActivityThread.java:4363)
11-25 13:19:21.759: E/AndroidRuntime(697): at java.lang.reflect.Method.invokeNative(Native Method)
11-25 13:19:21.759: E/AndroidRuntime(697): at java.lang.reflect.Method.invoke(Method.java:521)
11-25 13:19:21.759: E/AndroidRuntime(697): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
11-25 13:19:21.759: E/AndroidRuntime(697): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
11-25 13:19:21.759: E/AndroidRuntime(697): at dalvik.system.NativeStart.main(Native Method)
所以我不确定 viewPager 在哪里保留对位图的引用,因为
final Runnable mUpdateResults = new Runnable() {
public void run() {
if (mTmpBitmap != null && !mTmpBitmap.isRecycled()) {
GifDecoderView.this.setImageBitmap(mTmpBitmap);
}
}
};
在此错误之前不调用。