有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Canvas尝试使用回收的位图

自从我将我的SDK/ADT升级到Android 4.4以来的最新变化,我不确定这是否与此相关,但这是自这个错误开始以来唯一的重大变化,我在我的应用程序中遇到了这个错误

日志中没有说明这在我的应用程序中发生的位置。尽管有对DrawerLayout的引用。另外,它似乎引用了支持库v4,但我使用的是v13

   11-16 15:45:12.406: E/AndroidRuntime(1236): FATAL EXCEPTION: main
    11-16 15:45:12.406: E/AndroidRuntime(1236): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap 安卓.graphics.Bitmap@41f1e4e8
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.graphics.Canvas.throwIfRecycled(Canvas.java:1058)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.graphics.Canvas.drawBitmap(Canvas.java:1097)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.View.draw(View.java:13854)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewGroup.drawChild(ViewGroup.java:3086)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.support.v4.widget.DrawerLayout.drawChild(DrawerLayout.java:804)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.View.draw(View.java:13823)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewGroup.drawChild(ViewGroup.java:3086)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.View.draw(View.java:13823)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewGroup.drawChild(ViewGroup.java:3086)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.View.draw(View.java:13823)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewGroup.drawChild(ViewGroup.java:3086)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.View.draw(View.java:13947)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.widget.FrameLayout.draw(FrameLayout.java:467)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at com.安卓.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2224)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2482)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewRootImpl.draw(ViewRootImpl.java:2395)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewRootImpl.performDraw(ViewRootImpl.java:2239)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1872)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.Choreographer.doCallbacks(Choreographer.java:562)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.Choreographer.doFrame(Choreographer.java:532)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.os.Handler.handleCallback(Handler.java:730)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.os.Handler.dispatchMessage(Handler.java:92)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.os.Looper.loop(Looper.java:137)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at 安卓.app.ActivityThread.main(ActivityThread.java:5103)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at java.lang.reflect.Method.invokeNative(Native Method)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at java.lang.reflect.Method.invoke(Method.java:525)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    11-16 15:45:12.406: E/AndroidRuntime(1236):     at dalvik.system.NativeStart.main(Native Method)

这里是我仅有的在异步任务中使用BitMap的代码;这与我的抽屉listView标题中的图像有关:

 static class GetProfileImageURL extends AsyncTask<String, String, Void> {
    private Bitmap b;
    private Context mContext;

    public GetProfileImageURL(Context c) {
        mContext = c;
    }

    @Override
    protected Void doInBackground(String... params) {

        URL url;
        try {
            String profImage = String.valueOf(Rateit.userId);
            url = new URL(Rateit.PROFILE_PIC_URL + profImage + ".jpg");
            b = BitmapFactory.decodeStream(url.openConnection()
                    .getInputStream());

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;

    }

    protected void onPostExecute(Void v) {

        if (mContext != null) {
            if (b != null) {
                userIcon.setImageBitmap(ImageHelper.getRoundedCornerBitmap(
                        b, 50));
            }
        }
    }
}

这个AsyncTask仅在创建Activity时调用

根据请求,ImageHelper类:

public class ImageHelper { 
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { 
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap 
                .getHeight(), Config.ARGB_8888); 
        Canvas canvas = new Canvas(output); 

        final int color = 0xff424242; 
        final Paint paint = new Paint(); 
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 
        final RectF rectF = new RectF(rect); 
        final float roundPx = pixels; 
        final Rect topRightRect = new Rect(bitmap.getWidth()/2, 0, bitmap.getWidth(), bitmap.getHeight()/2); 
        final Rect bottomRect = new Rect(0, bitmap.getHeight()/2, bitmap.getWidth(), bitmap.getHeight()); 

        paint.setAntiAlias(true); 
        canvas.drawARGB(0, 0, 0, 0); 
        paint.setColor(color); 
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint); 
        // Fill in upper right corner 
        canvas.drawRect(topRightRect, paint); 
        // Fill in bottom corners 
        canvas.drawRect(bottomRect, paint); 

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
        canvas.drawBitmap(bitmap, rect, rect, paint); 

        return output; 

共 (1) 个答案

  1. # 1 楼答案

    我来猜一猜

    在OnCreate中,引用抽屉的布局组件时,布局管理器。充气机没有意识到任务中固有的异步延迟,因此它在不知道异步任务尚未完成的情况下继续进行

    问题可能是,在onCreate()中构建的视图需要能够在任务完成之前将某些内容组合在一起。当任务完成时,它需要更改视图资源的状态,并发出某些视图组件应该刷新的信号。例如,参考资料中的一个虚拟bmp代表圆形位图,很快就会从网络上的异步检索中出现

    我不知道你为什么不在<;4.4.

    我想你的问题与方向改变无关

    有可能this code会进一步澄清asnyc导致的一些滞后问题。可能根本不相关