gpt4 book ai didi

java - 屏幕方向更改时 lockCanvas 失败

转载 作者:太空宇宙 更新时间:2023-11-03 13:09:21 30 4
gpt4 key购买 nike

我正在尝试在 Android 中构建动态壁纸,但当方向改变时应用程序崩溃了。尝试将 Canvas 锁定在表面支架上时看起来它正在崩溃,但我不确定我能做些什么来防止它。

这是类:

public class LiveWallpaperService extends WallpaperService
{
public void onCreate() {
super.onCreate();
}

public void onDestroy() {
super.onDestroy();
}

public Engine onCreateEngine() {
return new MyWallpaperEngine();
}

class MyWallpaperEngine extends Engine
{
private final Handler handler = new Handler();
private final Runnable drawRunner = new Runnable() {
@Override
public void run() {
draw();
}
};
private boolean visible = true;

Paint paint;

MyWallpaperEngine() {
paint = new Paint();
}

public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
}

@Override
public void onVisibilityChanged(boolean visible) {
this.visible = visible;

if (visible) {
handler.post(drawRunner);
}
else {
handler.removeCallbacks(drawRunner);
}
}

@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
this.visible = false;
handler.removeCallbacks(drawRunner);
}

public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels) {
draw();
}

void draw() {
final SurfaceHolder holder = getSurfaceHolder();

Canvas c = null;

try {
c = holder.lockCanvas();

if (c != null) {
// Paint stuff here.
}
}
finally {
if (c != null) {
holder.unlockCanvasAndPost(c);
}
}

handler.removeCallbacks(drawRunner);
if (visible) {
handler.postDelayed(drawRunner, 10);
}
}
}
}

这是方向改变时发生的异常:

E/StudioProfiler: JVMTI error: 15(JVMTI_ERROR_THREAD_NOT_ALIVE) 
E/Surface: dequeueBuffer failed (No such device)
E/BaseSurfaceHolder: Exception locking surface
java.lang.IllegalArgumentException
at android.view.Surface.nativeLockCanvas(Native Method)
at android.view.Surface.lockCanvas(Surface.java:318)
at com.android.internal.view.BaseSurfaceHolder.internalLockCanvas(BaseSurfaceHolder.java:194)
at com.android.internal.view.BaseSurfaceHolder.lockCanvas(BaseSurfaceHolder.java:158)
at android.service.wallpaper.WallpaperService$Engine$1.lockCanvas(WallpaperService.java:262)
at greencell.bitpatternswallpaper.LiveWallpaperService$MyWallpaperEngine.draw(LiveWallpaperService.java:206)
at greencell.bitpatternswallpaper.LiveWallpaperService$MyWallpaperEngine$1.run(LiveWallpaperService.java:51)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

更新:

我已经检查了许多其他似乎有相同问题的线程,但到目前为止我唯一能做的就是尝试包装 unlockCanvasAndPostlockCanvas catch 以忽略 IllegalArgumentException

最佳答案

draw() 中,我尝试将 handler.removeCallbacks(drawRunner); 移动到 try block 之前。可能是 onOffsetsChanged() 在方向更改时被调用,并且处理程序上的前一个线程可能尚未调用 unlockCanvasAndPost(c),这解释了为什么你那时 lockCanvas() 出现错误。但是,如果您在此处发布的代码与您在本地运行的代码完全匹配,则情况不应如此,因为您没有覆盖 onOffsetsChanged()

您可以尝试的另一件事是覆盖 onSurfaceChanged() 并像这样清除处理程序队列:

@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
handler.removeCallbacks(drawRunner);
super.onSurfaceChanged(holder, format, width, height);
}

最终,我在网上阅读的关于 WallpaperService 的所有示例都有一个带有锁定/解锁 Canvas 的 try-finally block 逻辑,所以我不会担心。

关于java - 屏幕方向更改时 lockCanvas 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49575622/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com