IllegalArgumentException при вращении устройства в средстве выбора живых обоев Android 3.0

Я разрабатываю живые обои для Honeycomb 3.0, но получаю случайную ошибку.

Когда я нахожусь в средстве выбора обоев (окно с кнопками "Установить обои" и "Настройки...", чтобы понять) и отображаются живые обои, если я поворачиваю устройство, обои должны перезагружаться. с конфигурацией, адаптированной к новой ориентации. Иногда получается, иногда вылетает.

Ошибка каким-то образом связана с методом BaseSurfaceHolder.unlockCanvasAndPost, но я действительно не знаю, в чем проблема. Я думаю, что он не может правильно загрузить некоторые ресурсы.

Вот журнал ошибок:

07-21 16:07:38.490: WARN/WindowManager(292): java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@40d19f28 does not exist
07-21 16:07:38.490: WARN/WindowManager(292):     at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:6731)
07-21 16:07:38.490: WARN/WindowManager(292):     at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:6722)
07-21 16:07:38.490: WARN/WindowManager(292):     at com.android.server.wm.WindowManagerService.removeWindow(WindowManagerService.java:2414)
07-21 16:07:38.490: WARN/WindowManager(292):     at com.android.server.wm.Session.remove(Session.java:149)
07-21 16:07:38.490: WARN/WindowManager(292):     at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:120)
07-21 16:07:38.490: WARN/WindowManager(292):     at com.android.server.wm.Session.onTransact(Session.java:111)
07-21 16:07:38.490: WARN/WindowManager(292):     at android.os.Binder.execTransact(Binder.java:320)
07-21 16:07:38.490: WARN/WindowManager(292):     at dalvik.system.NativeStart.run(Native Method)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): FATAL EXCEPTION: main
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): java.lang.IllegalArgumentException
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at android.view.Surface.unlockCanvasAndPost(Native Method)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at com.android.internal.view.BaseSurfaceHolder.unlockCanvasAndPost(BaseSurfaceHolder.java:215)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at mx.livewallpaper.clock.CubeWallpaper1$CubeEngine.drawFrame(CubeWallpaper1.java:686)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at mx.livewallpaper.clock.CubeWallpaper1$CubeEngine$1.run(CubeWallpaper1.java:292)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at android.os.Handler.handleCallback(Handler.java:587)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at android.os.Handler.dispatchMessage(Handler.java:92)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at android.os.Looper.loop(Looper.java:132)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at android.app.ActivityThread.main(ActivityThread.java:4028)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at java.lang.reflect.Method.invokeNative(Native Method)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at java.lang.reflect.Method.invoke(Method.java:491)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768):     at dalvik.system.NativeStart.main(Native Method)
07-21 16:07:38.500: ERROR/android.os.Debug(292): Dumpstate > /data/log/dumpstate_app_error

РЕДАКТИРОВАТЬ: код ниже - это метод drawFrame() в строке 686:

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

            Canvas c = null;
            try {
                c = holder.lockCanvas();
                if (c != null) {

                    drawLogo3(c);
                }
            } finally {
                if (c != null) holder.unlockCanvasAndPost(c);
            }

Это метод по умолчанию, присутствующий во всех живых обоях, я взял его из CubeWallpaper Live Wallpaper Sample из Android SDK.

РЕДАКТИРОВАТЬ 2:

Похоже на ошибку буфера. Если я установлю частоту кадров на 10 кадров в секунду вместо 40 кадров в секунду, средство выбора живых обоев вообще не сработает. Можно ли редактировать поведение живых обоев только для действия «Выбор живых обоев»?


person Mariux    schedule 21.07.2011    source источник
comment
Не могли бы вы рассказать нам, что происходит в строке 686 CubeWallpaper1.java?   -  person mopsled    schedule 21.07.2011
comment
в строке 686 есть метод drawFrame() для живых обоев по умолчанию, см. код в редактировании выше.   -  person Mariux    schedule 22.07.2011
comment
когда устройство меняет ориентацию, все ваши вещи уничтожаются и создаются заново. вы должны учитывать это в своем наивном рисунке. трассировка стека указывает, что unlockCanvasAndPost генерирует исключение недопустимого аргумента. это происходит потому, что, как указано в самой первой строке вашей трассировки, окно, в которое вы пытаетесь рисовать, уничтожено и больше недоступно из-за изменения ориентации. вы должны получить обратный вызов держателя поверхности для этого, который вы, вероятно, игнорируете. Вы должны быть готовы к тому, что поверхность может уйти в любой момент.   -  person escape-llc    schedule 30.12.2011
comment
Привет @escape-llc! Мой метод drawFrame похож на описанный выше, но я не уверен, понял ли я его: мне нужно добавить holder.addCallback(new Callback() { public void surfaceDestroyed(SurfaceHolder holder) { destroyed = true; }}); после getSurfaceHolder() и перед блоком try-catch? И прежде чем звонить unlockCanvasAndPost(c), я должен проверить, есть ли !destroyed? Возможно, вы могли бы преобразовать свой комментарий в ответ и опубликовать фрагмент кода. Спасибо!   -  person Ethan Leroy    schedule 17.05.2012


Ответы (2)


соедините резьбу, прежде чем разрушить поверхность

@Override
public void onSurfaceDestroyed(SurfaceHolder holder)
{
    try 
    {
        updater.join();
    } 
    catch (InterruptedException e) 
    {

    }
    super.onSurfaceDestroyed(holder);
}
person user1447952    schedule 11.06.2012

когда вы меняете ориентацию устройства, вызывается функция «onsurfacechange()».

@Override
        public void onSurfaceChanged(SurfaceHolder holder, int format,
                int width, int height) {
                        int lockwidth = 0;
            int lockheight = 0;
            mholder = holder;
            try {

                canvas = mholder.lockCanvas();
                lockwidth = canvas.getWidth();
                lockheight = canvas.getHeight();
                if (width > height) {
                    Utils.Width = lockheight;
                    Utils.screenWidth = lockheight;
                    Utils.screenHeight = lockwidth;
                    Utils.isWidth = true;
                    if (width == 1280 && height == 720 && lockwidth == 800
                            && lockheight == 480) {
                        Utils.screenWidth = 480;
                        Utils.screenHeight = 854;
                    }
                } else {
                    Utils.Width = lockwidth;
                    Utils.screenWidth = lockwidth;
                    Utils.screenHeight = lockheight;
                    Utils.isWidth = false;
                    if (width == 720 && height == 1280 && lockwidth == 480
                            && lockheight == 800) {
                        Utils.screenWidth = 480;
                        Utils.screenHeight = 854;
                    }
                }
                mholder.unlockCanvasAndPost(canvas);
            } catch (Exception e) {
            }
            Utils.rateX = (float) Utils.Width / (float) Utils.FLA_Width;
            Utils.ratio = Utils.screenWidth / Utils.FLA_Width;
            Utils.Width = lockwidth;
            Utils.Height = lockheight;
        }
person jakie    schedule 06.07.2012
comment
@Jakie..Можете ли вы сказать мне, для чего предназначены эти Utils? Это класс? - person micky; 20.08.2014