【问题标题】:IllegalArgumentException in unlockCanvasAndPost (android live wallpaper)unlockCanvasAndPost 中的 IllegalArgumentException(android 动态壁纸)
【发布时间】:2012-10-06 09:54:09
【问题描述】:

我创建了我的第一个动态壁纸,在单独的线程中实现绘图。所以现在我有一个 WallpaperService 和我的 WallpaperPainter 来完成这项工作。问题是我在某些设备上的unlockCanvasAndPost 方法中获得了IllegalArgumentException(三星Note 就是其中之一)。我已经阅读了所有我能找到但无法修复该错误的建议。似乎unlockCanvasAndPost 在表面被破坏时被调用,因此画布无效。以下是代码的基本部分:

在壁纸服务中:

    @Override
    public void onSurfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        super.onSurfaceChanged(holder, format, width, height);
        painting.setSurfaceSize(width, height);
    }

    @Override
    public void onSurfaceCreated(SurfaceHolder holder) {
        super.onSurfaceCreated(holder);
        painting.start();
    }

    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        painting.stopPainting();
        while (retry) {
            try {
                painting.join();
                retry = false;
            } catch (InterruptedException e) { }
        }
        super.onSurfaceDestroyed(holder);
    }

在绘画线程中:

public void stopPainting() {
    this.run = false;
    synchronized(this) {
        this.notify();
    }
}

public void run() {
    this.run = true;
    Canvas c = null;
    while (run) {
        try {
            synchronized (this) {
                Thread.sleep(50);
                c = this.surfaceHolder.lockCanvas();
                doDraw(c);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (c != null) {
                this.surfaceHolder.unlockCanvasAndPost(c); // << -- HERE IS THE PROBLEM
            }
        }
        // if pause...
        synchronized (this) {
            if (wait) {
                try {
                    wait();
                } catch (Exception e) { }
            }
        }
    }
}

谁能告诉我我做错了什么?我是 Java 和 Android 的新手。

【问题讨论】:

    标签: java android multithreading live-wallpaper


    【解决方案1】:

    如果错误为:UnlockAndPost Failed,表示没有解锁缓冲区。 在this.surfaceHolder.unlockCanvasAndPost(c);
    之后 您可以附加
    this.surfaceHolder.lockCanvas();
    (对不起,我的英语水平很差)

    【讨论】:

      【解决方案2】:

      当您打开壁纸预览时,创建对象 WallpaperService 并进一步创建 Engine 实例。然后流开始绘制壁纸。

      然后,当您单击“设置壁纸”时 - 不会创建 WallpaperService 的新实例。但他调用了 onCreateEngine() 方法,该方法返回另一个(第二个)Engine 实例。它也运行自己的线程。

      现在你有两个竞争线程!!!因此它们会导致抛出异常。

      修复该错误所需要做的就是编写正确的方法 onCreateEngine()。

      替换这个:

      @Override
      public Engine onCreateEngine() {
          return new SampleEngine();
      }
      

      到这里:

      private SampleEngine engine;
      
      @Override
      public Engine onCreateEngine() {
      
          if (engine!=null) {
              engine.painting.stopPainting();
              engine = null;
          }
          engine = new SampleEngine();
          return engine;
      }
      

      【讨论】:

        【解决方案3】:

        我没有看到明确的问题,但这里有一些想法。

        • 您有可能解锁尚未锁定的画布。我会将c = null; 设置在while 循环的顶部,否则c 的先前值将在下次循环时解锁。

          while (run) {
              Canvas c = null;
              ...
          
        • 您的run 字段应标记为volatile,因为它由多个线程访问。

        • 切勿在 synchronized 块内调用 Thread.sleep(...)。这是一种非常糟糕的做法,因为它会不必要地阻塞其他线程。

        • 确保至少记录您的异常。小心catch (Exception e) {}。所做的只是掩盖你的问题。

        • while 循环内执行join() 没有多大意义。如果您的线程被中断,您应该中断绘画线程并退出。

        • 既然你都在睡觉在等待,那么移除睡眠并执行以下操作会更有意义:

          try {
             synchronized (this) {
                 if (wait) {
                    wait();
                 else {
                    wait(50);
                 }
             }
          } catch (Exception e) {
             e.printStackTrace();
          }
          

        【讨论】:

          【解决方案4】:

          我的动态壁纸也有同样的问题。在 Nexus 5 模拟器上它运行良好,但是当我在 Nexus 10 模拟器上运行它时,它会在应用加载的那一刻崩溃。

          我发现问题是因为模拟器的默认皮肤有错误的分辨率。在我将皮肤更改为“无皮肤”之后,我就不再遇到崩溃了。

          有关如何修复分辨率错误的皮肤的更多信息,请参阅: Android Studio - Tablet emulator not showing correct resolution

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多