我正在尝试在android上实现分形渲染器。它使用SurfaceView显示结果。
我使用单独的Thread进行渲染以在处理期间保持UI工作,但它会锁定直到调用unlockCanvasAndPost。这是预期的行为吗?如何防止用户界面锁定? 在这个例子中,我通过Thread.sleep来模拟长处理。
我的SurfaceView-Class看起来像这样:
public class MyView extends SurfaceView implements SurfaceHolder.Callback {
RenderThread rt = null;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
rt = new RenderThread(holder);
rt.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
rt.setStop();
}
}
这是RenderThread-class:
public class RenderThread extends Thread {
SurfaceHolder holder;
boolean running = true;
public RenderThread(SurfaceHolder holder) {
this.holder = holder;
}
public void setStop() {
running = false;
}
@Override
public void run() {
while(running) {
Canvas canvas = holder.lockCanvas();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(canvas == null) return;
Paint p = new Paint();
p.setARGB(255, 255, 0, 0);
canvas.drawLine(0, 0, 100, 100, p);
holder.unlockCanvasAndPost(canvas);
}
}
}
答案 0 :(得分:1)
几种可能性。
您没有展示如何将MyView类合并到包含它的活动中。因为您已经将SurfaceView子类化,所以您必须在活动中添加代码以专门处理您使用RenderThread添加的内容。例如,活动的onPause()方法应该向MyView类发送信号以停止其RenderThread。
SurfaceHtroyed()方法在SurfaceHolder表面被销毁之前被调用。在RenderThread停止触摸之前,您无法从该方法返回。这是通过同步完成的。 Official Android documentation for surfaceDestroyed()
有一个很好的例子,说明如何在ApiDemos项目的WindowSurface.java中正确完成所有这些操作(对于Eclipse,通过Android SDK Manager安装“Samples for SDK”)。将项目加载到Eclipse后(使用File-> New-> Project-> Android Sample Project),在项目中的com.example.android.apis.graphics中找到WindowSurface.java。
最后,如果您在线程的run方法中的实际代码(为了简洁起见,您已经使用Thread.sleep替换了这些代码)对画布执行了任何操作,那么您对canvas == null的检查应该紧接在尝试之下锁定那个画布。理想情况下,无论如何都是更好的形式。