Search code examples
androidandroidx

Crash when using androidx.window on OnePlus and Oppo devices


I added this code to my books app to recognize foldable devices (deleted unrelevant code).
On OnePlus and Oppo devices (not foldable) the app crashes.
It happens only in Android OS bigger than 13.

Code:

    private WindowInfoTrackerCallbackAdapter windowInfoTracker;
    private final Consumer<WindowLayoutInfo> layoutStateChangeCallback = new LayoutStateChangeCallback();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_epub_reader);
        windowInfoTracker = new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(this));
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (Utilities.isFoldableDevice(this)) {
            Timber.tag(TAG).d("onStart: isFoldableDevice");
            windowInfoTracker.addWindowLayoutInfoListener(this, Runnable::run, layoutStateChangeCallback);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (Utilities.isFoldableDevice(this)) {
            windowInfoTracker.removeWindowLayoutInfoListener(layoutStateChangeCallback);
        }
    }

    class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> {
        @Override
        public void accept(WindowLayoutInfo newLayoutInfo) {
            EpubReaderActivity.this.runOnUiThread(() -> {
                try {
                    boolean isDeviceFlatFoldable = !newLayoutInfo.getDisplayFeatures().isEmpty();
                    Timber.tag(TAG).d("accept: isDeviceFlatFoldable = %s", isDeviceFlatFoldable);
                    if (preferencesManager.getIsDeviceFlatFoldable() != isDeviceFlatFoldable) {
                        preferencesManager.setIsDeviceFlatFoldable(isDeviceFlatFoldable);
                        EventBus.getDefault().post(new EpubColumnsChangeEvent());
                    }
                } catch (Exception e) {
                    Timber.e(e);
                }
            });
        }
    }

    public static boolean isFoldableDevice(Context context) {
        // at least Android 11 (Version code 30) is required
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_HINGE_ANGLE);
        }
        return false;
    }

build.gradle

implementation 'androidx.window:window-java:1.3.0'

Crash log:

   Fatal Exception: java.lang.AbstractMethodError: abstract method "void androidx.window.sidecar.SidecarInterface$SidecarCallback.onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState)"
   at androidx.window.sidecar.StubSidecar.updateDeviceState(StubSidecar.java:64)
   at androidx.window.sidecar.SampleSidecarImpl.onDisplayFeaturesChanged(SampleSidecarImpl.java:78)
   at androidx.window.sidecar.SampleSidecarImpl.-$$Nest$monDisplayFeaturesChanged()
   at androidx.window.sidecar.SampleSidecarImpl$NotifyOnConfigurationChanged.onDisplayFeaturesChangedForActivity(SampleSidecarImpl.java:194)
   at androidx.window.sidecar.SampleSidecarImpl$NotifyOnConfigurationChanged.onActivityCreated(SampleSidecarImpl.java:182)
   at android.app.Application.dispatchActivityCreated(Application.java:388)
   at android.app.Activity.dispatchActivityCreated(Activity.java:1430)
   at android.app.Activity.onCreate(Activity.java:1758)
   at androidx.core.app.ComponentActivity.onCreate(ComponentActivity.java:88)
   at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:363)
   at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:273)
   at androidx.appcompat.app.AppCompatActivity.onCreate(AppCompatActivity.java:65347)
   at com.yit.evrit.viewer.BaseActivity.onCreate(BaseActivity.kt:37)
   at com.yit.evrit.viewer.BaseActivity.onCreate(BaseActivity.kt:216)
   at com.yit.evrit.reader.BaseReaderActivity.onCreate(BaseReaderActivity.java:78)
   at com.yit.evrit.reader.BaseReaderActivity.onCreate(BaseReaderActivity.java:259)
   at com.yit.evrit.reader.epub.ui.main_screen.EpubReaderActivity.onCreate(EpubReaderActivity.java:461)
   at com.yit.evrit.reader.epub.ui.main_screen.EpubReaderActivity.onCreate(EpubReaderActivity.java:1665)
   at android.app.Activity.performCreate(Activity.java:8757)
   at android.app.Activity.performCreate(Activity.java:8729)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1475)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4005)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4181)
   at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6349)
   at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:6219)
   at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:76)
   at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
   at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:144)
   at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:101)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2643)
   at android.os.Handler.dispatchMessage(Handler.java:106)
   at android.os.Looper.loopOnce(Looper.java:257)
   at android.os.Looper.loop(Looper.java:368)
   at android.app.ActivityThread.main(ActivityThread.java:8839)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:572)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1049)
    

Solution

  • There still seems to be a proguard rule issue with androidx.window:window:1.1.0, 1.2.0 and 1.3.0. https://issuetracker.google.com/issues/165268619.

    For now I found a temp solution by using the following proguard rules from https://issuetracker.google.com/issues/189001730#comment16.

    -keep class androidx.window.extensions.** { *; }
    -dontwarn androidx.window.extensions.**
    
    # Keep the whole library for now since there is a crash with a missing method.
    # TODO(b/165268619) Make a narrow rule
    -keep class androidx.window.** { *; }
    
    # We also neep to keep sidecar.** for the same reason.
    -keep class androidx.window.sidecar.** { *; }
    -dontwarn androidx.window.sidecar.**