我正在尝试在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.lockCanvas(WallpaperService.java:262) at greencell.bitpatternswallpaper.liveWallpaperService$MyWallpaperEngine.draw(liveWallpaperService.java:206) at greencell.bitpatternswallpaper.liveWallpaperService$MyWallpaperEngine.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)
更新:
我检查了许多其他线程,它们似乎都存在相同的问题,但是到目前为止,我唯一能做的就是在尝试捕获中包装unlockCanvasAndPost和lockCanvas来忽略IllegalArgumentException.
@H_404_22@解决方法:在draw()中,我尝试移动handler.removeCallbacks(drawRunner);在try块之前.可能是在方向更改时调用了onOffsetsChanged(),并且处理程序上的上一个线程可能尚未调用unlockCanvasAndPost(c),这解释了为什么此时出现lockCanvas()错误.但是,如果您在此处发布的代码与您在本地运行的代码完全匹配,则情况并非如此,因为您没有覆盖onOffsetsChanged().
您可以尝试的另一件事是重写onSurfaceChanged()并清除处理程序队列,如下所示:
@OverrIDepublic voID onSurfaceChanged(SurfaceHolder holder, int format, int wIDth, int height) { handler.removeCallbacks(drawRunner); super.onSurfaceChanged(holder, format, wIDth, height);}
最终,我在网上阅读的所有与WallpaperService有关的示例都具有一个try-finally块,该块具有锁定/解锁画布逻辑,因此我不必担心.
总结以上是内存溢出为你收集整理的当屏幕方向更改时,lockCanvas失败全部内容,希望文章能够帮你解决当屏幕方向更改时,lockCanvas失败所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)