Canvas和surfaceView示例崩溃/冻结 - 内存泄漏?

时间:2011-04-13 14:23:21

标签: android canvas surfaceview

http://www.helloandroid.com/tutorials/how-use-canvas-your-android-apps-part-1

在本教程结束时,可以获得源代码下载链接。 我下载了代码并尝试了这个例子,它在屏幕上绘制了一只袋鼠,在1-2分钟内我崩溃了/应用程序冻结了。

我尝试使用Archos 70 Internet Tablet。

“我想知道原因,或者是否有些错误”

这是 LogCat

04-13 17:03:24.089:DEBUG / ondraw(2070):lefutott
04-13 17:03:24.097:DEBUG / ondraw(2070):lefutott
04-13 17:03:24.113:DEBUG / ondraw(2070):lefutott
04-13 17:03:24.128:DEBUG / ondraw(2070):lefutott
04-13 17:03:24.136:DEBUG / ondraw(2070):lefutott
04-13 17:03:24.152:DEBUG / ondraw(2070):lefutott
04-13 17:03:24.167:DEBUG / ondraw(2070):lefutott
04-13 17:03:24.175:DEBUG / ondraw(2070):lefutott
04-13 17:04:10.019:WARN / ActivityManager(1302):广播超时BroadcastRecord {457f99c8 android.intent.action.TIME_TICK} - receiver=android.app.ActivityThread$PackageInfo$ReceiverDispatcher$InnerReceiver@4561a5c8
04-13 17:04:10.019:WARN / ActivityManager(1302):超时期间的接收器:BroadcastFilter {454ed4c8 ReceiverList {454fbd70 1302 system / 1000 local:4561a5c8}}
04-13 17:04:38.972:INFO / Process(1302):发送信号。 PID:1302 SIG:3
04-13 17:04:38.972:INFO / dalvikvm(1302):threadid = 3:对信号3做出反应
04-13 17:04:39.097:INFO / dalvikvm(1302):将堆栈跟踪写入'/data/anr/traces.txt'
04-13 17:05:09.097:INFO / Process(1302):发送信号。 PID:1302 SIG:3
04-13 17:05:09.097:INFO / dalvikvm(1302):threadid = 3:对信号3作出反应
04-13 17:05:09.128:INFO / dalvikvm(1302):将堆栈跟踪写入'/data/anr/traces.txt'
04-13 17:05:09.128:INFO / Process(1302):发送信号。 PID:1433 SIG:3
04-13 17:05:09.128:INFO / dalvikvm(1433):threadid = 3:对信号3作出反应
04-13 17:05:09.144:INFO / dalvikvm(1433):将堆栈跟踪写入'/data/anr/traces.txt'
04-13 17:05:11.144:INFO / Watchdog_N(1302):dumpKernelStacks
04-13 17:05:11.144:ERROR / Watchdog_N(1302):无法打开tid 1302:13的堆栈(权限被拒绝)
04-13 17:05:11.144:ERROR / Watchdog_N(1302):无法打开tid 1303:13的堆栈(权限被拒绝)

1 个答案:

答案 0 :(得分:2)

onDraw看起来像这样:

    @Override
    public void onDraw(Canvas canvas) {

            Paint paint = new Paint();


            Bitmap kangoo = BitmapFactory.decodeResource(getResources(),
                            R.drawable.kangoo);
            canvas.drawColor(Color.BLACK);
            canvas.drawBitmap(kangoo, 10, 10, null);
    }

因此,每次运行时,它都会创建一个新的绘图,并且可能(我没有使用BitmapFactory),创建一个新的位图。这似乎有点矫枉过正(特别是因为油漆没有使用,尽管它似乎在第2部分)。我会考虑将这些位移动到面板的构造函数中,以查看它是否有所作为,例如:

public class Panel extends SurfaceView implements SurfaceHolder.Callback{
    // rest of class ignored for brevity

    private Paint paint;
    private Bitmap kangoo;

    public Panel(Context context, AttributeSet attrs) {
    super(context, attrs); 
    getHolder().addCallback(this);
    canvasthread = new CanvasThread(getHolder(), this);
    setFocusable(true);
         paint = new Paint();


         kangoo = BitmapFactory.decodeResource(getResources(),
                            R.drawable.kangoo);
}

    @Override
    public void onDraw(Canvas canvas) {                
            canvas.drawColor(Color.BLACK);
            canvas.drawBitmap(kangoo, 10, 10, null);
    }
}

在模拟器中运行它可能也值得看看是否遇到同样的问题,或者它是否是特定于设备的。

编辑: 值得注意的是,CanvasThread类中的run()方法没有任何睡眠,因此它可以尽可能快地运行,重新绘制屏幕。对于一个教程来说这可能没问题,但是在一个真正的应用程序中我会期望某种目标帧速率在run方法中有适当的睡眠,否则你似乎会使用大量的cpu周期(并且可能是电池)用户可能不会注意到。