You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android动态壁纸屏幕方向切换时lockCanvas调用崩溃问题求助

解决Android动态壁纸屏幕旋转时lockCanvas崩溃的问题

嘿,我之前开发动态壁纸时也踩过这个坑!屏幕旋转时调用lockCanvas崩溃,核心原因是屏幕方向切换过程中,系统会销毁旧的Surface并创建新的Surface,这时候如果你的代码还在尝试锁定一个已经失效的SurfaceHolder,就会抛出异常。下面是我亲测有效的解决方法:

1. 维护Surface有效性标记

在你的MyWallpaperEngine里添加一个布尔标记,用来跟踪Surface是否处于可用状态:

class MyWallpaperEngine extends Engine {
    private boolean isSurfaceValid = false;
    // 其他成员变量...

2. 监听Surface的生命周期事件

重写onSurfaceCreated和onSurfaceDestroyed方法,更新标记位,同时处理资源的初始化和释放:

@Override
public void onSurfaceCreated(SurfaceHolder holder) {
    super.onSurfaceCreated(holder);
    isSurfaceValid = true;
    // 在这里初始化绘制需要的资源,比如画笔、位图等
}

@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
    super.onSurfaceDestroyed(holder);
    isSurfaceValid = false;
    // 停止所有正在运行的绘制线程,释放相关资源
    // 比如如果有自定义的DrawThread,这里可以设置线程停止标记
}

3. 安全调用lockCanvas

在你的绘制逻辑中,先检查Surface是否有效,再尝试锁定Canvas,同时捕获可能的异常:

private void drawFrame() {
    if (!isSurfaceValid) {
        return; // Surface无效时直接返回,避免后续操作
    }

    Canvas canvas = null;
    try {
        canvas = getSurfaceHolder().lockCanvas();
        if (canvas != null) {
            // 这里写你的绘制逻辑,比如清屏、绘制图形等
            canvas.drawColor(Color.BLACK);
            // ...其他绘制代码
        }
    } catch (IllegalArgumentException e) {
        // 捕获Surface失效的异常,更新标记位
        isSurfaceValid = false;
        e.printStackTrace();
    } finally {
        // 一定要确保解锁Canvas,避免Surface卡死
        if (canvas != null) {
            getSurfaceHolder().unlockCanvasAndPost(canvas);
        }
    }
}

4. 处理绘制线程(如果有)

如果你的壁纸用了单独的线程来循环绘制,一定要在Surface销毁时及时终止线程。比如给线程加一个停止标记:

private class DrawThread extends Thread {
    private boolean isRunning = true;

    @Override
    public void run() {
        while (isRunning) {
            drawFrame();
            // 控制绘制帧率
            try {
                Thread.sleep(16);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void stopDrawing() {
        isRunning = false;
        interrupt(); // 中断线程,确保快速退出
    }
}

然后在onSurfaceDestroyed里调用drawThread.stopDrawing();

这样调整后,屏幕旋转时你的代码会先检测Surface状态,避免在无效状态下调用lockCanvas,就能解决崩溃问题啦!

内容的提问来源于stack exchange,提问作者Green Cell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:13:44