2

我有一个 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);
    }
}
};

在此错误之前不调用。

4

0 回答 0