Сбой потока на Android 4.0 при выходе из Activity - PullRequest
1 голос
/ 05 марта 2012

При тестировании нескольких игр со стандартным игровым потоком в Android 4.0 он работает хорошо до тех пор, пока действие не будет закрыто (нажатие кнопки «Домой» и т. Д.), В результате чего активность приложения завершается с помощью nullPointer.происходит в примере LunarLander, который запрограммировал Google.

Проблема в том, что Canvas становится нулевым при выходе из действия, и это приводит к сбою приложения.

Сообщение об ошибке от LogCat чуть ниже.

02-27 18:07:58.974: V/MainThread(2667): CANVAS android.view.Surface$CompatibleCanvas@4102bcf0
02-27 18:07:59.164: V/MainThread(2667): CANVAS null
02-27 18:07:59.164: W/dalvikvm(2667): threadid=14: thread exiting with uncaught exception (group=0x409c01f8)
02-27 18:07:59.174: E/AndroidRuntime(2667): FATAL EXCEPTION: Thread-108
02-27 18:07:59.174: E/AndroidRuntime(2667): java.lang.NullPointerException
02-27 18:07:59.174: E/AndroidRuntime(2667):     at com.joakimengstrom.pong.MainThread.run(MainThread.java:49)

Это код при запуске потока, с Log.v, который вы видите выше.

    while(this.running){
        canvas = null;

        try {               
            canvas = this.surfaceHolder.lockCanvas(null);
            synchronized (surfaceHolder) {
                Log.v(TAG, "CANVAS " + canvas);
                canvas.drawColor(Color.BLACK);
                ...

И ниже при создании потока и его закрытии, когда поверхностьуничтожен.

@Override
public void surfaceCreated(SurfaceHolder holder) {
    thread = new MainThread(getHolder());
    thread.setRunning(true);
    thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    boolean retry = true;
    thread.setRunning(false);
    while (retry) {
        try {
            thread.join();
            retry = false;
        } catch (InterruptedException e) {

        }
    }
}

Как выйти из потока безопасным способом, не делая холст нулевым?

1 Ответ

8 голосов
/ 05 марта 2012

В Android 4.0, SurfaceHolder.lockCanvas может вернуть null, когда поверхность разрушена. Итак, здесь:

try {               
            canvas = this.surfaceHolder.lockCanvas(null);
            synchronized (surfaceHolder) {
                Log.v(TAG, "CANVAS " + canvas);
                canvas.drawColor(Color.BLACK);

Просто окружите свой synchronized (surfaceHolder) блок if (canvas != null). Это не должно вызывать каких-либо проблем с поведением вашего приложения, поскольку это происходит, когда рисование не требуется.

...