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
相关产品推荐
相关产品推荐

