Android SurfaceView,已调用 OnDraw 但显示不会在没有 invalidate() 的情况下更新

标签 android multithreading graphics surfaceview invalidation

我在遵循典型的 Android 图形流程时遇到了一些麻烦。有很多例子,但我的似乎不起作用。在我的主要 Activity 中,我这样做:

super.onCreate(savedInstanceState);                           
setContentView(R.layout.activity_main); 

在我的资源文件中,我有 3 个覆盖 SurfaceView 的自定义类。在我的这些 Surface Views 的构造函数中,我有这样的东西:

super(context, attrs);
getHolder().addCallback(this);
this.thread = new MyThread(getHolder(),this);

在我线程的运行方法中,我这样做(从我见过的许多例子中提取):

Canvas c;
try {
    c = surfaceHolder.lockCanvas(null);
    synchronized (surfaceHolder) {
        panel.onDraw(c);
    }
} finally {
    if (c != null) {
    surfaceHolder.unlockCanvasAndPost(c);
}

此线程在我的 SurfaceView 的“surfaceCreated”事件中启动。在 onDraw 中,我这样做:

public void onDraw(Canvas canvas) { 
    super.onDraw(canvas);
    <some drawing stuff here using canvas>
}

当我运行时,线程确实在运行,我可以看到正在调用 onDraw(我在其中放置了日志打印命令),但是我的图形没有按预期更新。但是,如果我调用 this.invalidate(),图形会像我预期的那样更新几次,直到我崩溃:

E/AndroidRuntime(748): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

根据我看到的示例,我意识到我不需要在 OnDraw 中调用 invalidate,但我这样做只是为了验证我的 onDraw 中的代码是否有效。所以,在我看来,如果没有 invalidate() 就会调用 onDraw 事件,我的代码应该正确更新图形,但屏幕永远不会更新。我遗漏了主要 Activity 如何实际决定它需要重新绘制其子项的内容。

任何想法将不胜感激。我花了一段时间尝试从一些工作演示中复制内容,但我似乎被卡住了。谢谢

最佳答案

你在 run() 中做的事情会做你做的任何事情 - 一次。 您需要重复绘图过程。

一种方法是将所有内容放在while 循环中

while(true){
    try {
        c = surfaceHolder.lockCanvas(null);
        synchronized (surfaceHolder) {
            panel.onDraw(c);
        }
    } finally {
        if (c != null) {
        surfaceHolder.unlockCanvasAndPost(c);
    }
}

关于Android SurfaceView,已调用 OnDraw 但显示不会在没有 invalidate() 的情况下更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12311731/

相关文章:

java - Android 中未找到 WirelessOnlinePath、未找到 BatteryVoltagePath 和 BatteryTemperaturePath 错误

java - Android - 在继续方法之前等待 json 获取值

c# - 使用MemoryBarrier传播Dictionary <int,T>多线程应用程序中的更改

java - 如何在java中设置线程的时间?

android - 在类里面获取 NULL 指针异常以检查互联网

java - 如何让我的 Java Applet 显示卡片图像?

java - 使用鼠标运动监听器绘制线条

Android:在 OnItemClick 后替换 GridView 数组中的图像

android - 重命名日期选择器中的默认按钮(android)

javascript - 以二维方式显示迷宫游戏服务的单元格