Android: не удалось заблокировать поверхность, dequeueBuffer: BufferQueue был отменен - PullRequest
0 голосов
/ 12 февраля 2020

Я написал очень простой экран spla sh для приложения android.

Иногда (не систематически) я вижу эту ошибку в logcat:

02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]: Could not lock surface
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]: java.lang.IllegalArgumentException
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.Surface.nativeLockCanvas(Native Method)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.Surface.lockCanvas(Surface.java:314)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:3033)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.ViewRootImpl.draw(ViewRootImpl.java:3007)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2794)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2347)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.Choreographer.doCallbacks(Choreographer.java:723)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.Choreographer.doFrame(Choreographer.java:658)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.os.Handler.handleCallback(Handler.java:789)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.os.Handler.dispatchMessage(Handler.java:98)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.os.Looper.loop(Looper.java:164)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at android.os.HandlerThread.run(HandlerThread.java:65)
02-06 18:09:07.872   407   449 E ViewRootImpl[app-name]:    at com.android.server.ServiceThread.run(ServiceThread.java:46)
02-06 18:09:07.875   295   382 E BufferQueueProducer: [Splash Screen com.app-name#0] dequeueBuffer: BufferQueue has been abandoned
02-06 18:09:07.875   407   449 E Surface : dequeueBuffer failed (No such device)

Я хотел бы ее решить, так как я верю, что это может быть root причиной некоторого противоречивого поведения в моем spla sh -экране.

Код выглядит следующим образом:

public class SplashScreen {
    private static Dialog splashDialog;
    private static WeakReference<Activity> activityRef;

    public static void show(final Activity activity, final int themeResId) {
        if (activity == null) return;
        activityRef = new WeakReference<>(activity);
        activity.runOnUiThread(() -> {
            if (!activity.isFinishing()) {
                splashDialog = new Dialog(activity, themeResId);
                splashDialog.setContentView(R.layout.launch_screen);
                splashDialog.setCancelable(false);

                if (!splashDialog.isShowing()) {
                    splashDialog.show();
                }
            }
        });
    }

    public static void show(final Activity activity) {
        show(activity, R.style.SplashScreen_Fullscreen);
    }

    public static void hide(Activity activity) {
        try{
            final Activity finalActivity = getActivityMaybe(activity);
            finalActivity.runOnUiThread(() -> {
                if (splashDialog != null && splashDialog.isShowing()) {
                    if (!finalActivity.isFinishing() && !finalActivity.isDestroyed()) {
                        splashDialog.dismiss();
                    }
                    splashDialog = null;
                }
            });
        }catch(Exception ignored) {}
    }

    public static Activity getActivityMaybe(Activity activity) {
        if (activity == null) {
            if (activityRef == null) {
                throw new Exception("Invalid activity");
            }
            activity = activityRef.get();
        }
        if (activity == null){
            throw new Exception("Invalid activity");
        }
        return activity;
    }
}

Я нашел эту похожую проблему , но она не решает мою проблема.

...