フラグメントを保持する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);
}
}
};
このエラーの前に呼び出されません。