BinderProxy не может быть приведен к исключению ClientTransaction при изменении DefaultNightMode - PullRequest
0 голосов
/ 28 апреля 2020

В моем приложении есть одно действие с нижней навигацией и несколькими фрагментами, и я использую компонент Навигация.

В моем фрагменте настроек у меня есть ListPreference, где пользователь может переключаться между светлым и темным режимом.

if (themePreference != null) {
            String[] entries = {getResources().getString(R.string.dark), getResources().getString(R.string.light)};
            String[] entryValues = {Integer.toString(MODE_NIGHT_YES), Integer.toString(MODE_NIGHT_NO)};
            themePreference.setEntries(entries);
            themePreference.setEntryValues(entryValues);

            if (themePreference.getValue() == null) {
                themePreference.setValue(Integer.toString(MODE_NIGHT_YES));
            }

            themePreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    final String userSelectedValue = (String) newValue;

                    SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit();
                    sharedPreferencesEditor.putString(THEME, userSelectedValue);
                    sharedPreferencesEditor.apply();

                    AppCompatDelegate.setDefaultNightMode(Integer.parseInt(userSelectedValue));

                    return true;
                }
            });
        }

Когда я выбираю режим из записей ListPreference, режим меняется, но я получаю это сообщение об ошибке в Logcat:

2020-04-28 16:50:42.342 17540-17540/de.xxxx.xxxx E/ActivityInjector: get life cycle exception
    java.lang.ClassCastException: android.os.BinderProxy cannot be cast to android.app.servertransaction.ClientTransaction
        at android.app.ActivityInjector.checkAccessControl(ActivityInjector.java:24)
        at android.app.Activity.onResume(Activity.java:1854)
        at androidx.fragment.app.FragmentActivity.onResume(FragmentActivity.java:455)
        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1454)
        at android.app.Activity.performResume(Activity.java:8051)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4236)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4278)
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:57)
        at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5298)
        at android.app.ActivityThread.access$3500(ActivityThread.java:220)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2050)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7520)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

Все объяснения, которые я нашел для этой ошибки, о привязке и услугах. Я не понимаю, какое это имеет отношение к моему делу. Это из-за воссоздания активности, когда она переходит в ночной / дневной режим?

Это происходит, когда я пытаюсь это сделать на моем Xiaomi Mi 9, но не на эмуляторе, например на Pixel 3 или Nexus 4. Может быть это проблема Xiaomi?

Есть идеи как это исправить? Заранее спасибо.

Редактировать:

Основная деятельность

public class MainActivity extends AppCompatActivity implements ProviderInstaller.ProviderInstallListener {

    private static final int ERROR_DIALOG_REQUEST_CODE = 1;

    private boolean retryProviderInstall;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setTheme(R.style.AppTheme_NoActionBar);
        super.onCreate(savedInstanceState);

        ProviderInstaller.installIfNeededAsync(this, this);

        setContentView(R.layout.activity_main);

        Toolbar actionBarToolBar = findViewById(R.id.toolbar);
        setSupportActionBar(actionBarToolBar);

        BottomNavigationView navView = findViewById(R.id.nav_view);

        AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
                R.id.navigation_search, R.id.navigation_bookmarks, R.id.navigation_settings, R.id.navigation_about)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
        NavigationUI.setupWithNavController(navView, navController);

        onNewIntent(getIntent());
    }

    @Override
    public boolean onSupportNavigateUp() {
        return Navigation.findNavController(this, R.id.nav_host_fragment).navigateUp()
                || super.onSupportNavigateUp();
    }

    @Override
    public void onProviderInstalled() {
        // Provider is up-to-date, app can make secure network calls.
    }

    @Override
    public void onProviderInstallFailed(int errorCode, Intent recoveryIntent) {
        GoogleApiAvailability availability = GoogleApiAvailability.getInstance();
        if (availability.isUserResolvableError(errorCode)) {
            // Recoverable error. Show a dialog prompting the user to
            // install/update/enable Google Play services.
            availability.showErrorDialogFragment(
                    this,
                    errorCode,
                    ERROR_DIALOG_REQUEST_CODE,
                    new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialog) {
                            // The user chose not to take the recovery action
                            onProviderInstallerNotAvailable();
                        }
                    });
        } else {
            // Google Play services is not available.
            onProviderInstallerNotAvailable();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == ERROR_DIALOG_REQUEST_CODE) {
            retryProviderInstall = true;
        }
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        if (retryProviderInstall) {
            ProviderInstaller.installIfNeededAsync(this, this);
        }
        retryProviderInstall = false;
    }

    private void onProviderInstallerNotAvailable() {
    }
}

1 Ответ

0 голосов
/ 28 апреля 2020

Это, конечно, специфика устройства c проблема ... что я предлагаю вам сделать следующим образом

@Override
protected void onCreate(Bundle savedInstanceState) {

    // must do this before super call or setContentView
    // pick which theme DAY or NIGHT from settings
    setTheme(someSettings.get(PREFFERED_THEME) ? R.style.AppThemeLight : R.style.AppThemeDark);

    super.onCreate(savedInstanceState);
}

// Somewhere in your activity where the button switches the theme
btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        // save theme of as user preference
        someSettings.save(PREFFERED_THEME);

        MainActivity.this.recreate();
    }
});

MainActivity.this.recreate (); // воссоздадим активность

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...