11

I am trying to recreate the fragment and the activity after changing the language setting in my app but getActivity().recreate(); part is making errors that I couldn't understand why. The error is :

E/ActivityInjector: get life cycle exception

The error occurs when I try to recreate the activity. Here's the code in my SettingsActivity.java:

public class SettingsActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);
        getSupportFragmentManager().beginTransaction().replace(R.id.settings, new SettingsFragment()).commit();
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }

    }

    public static class SettingsFragment extends PreferenceFragmentCompat {
        ListPreference languages;

        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey);

        }

        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            languages = getPreferenceManager().findPreference("language");
            languages.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    boolean anyChanges=false;
                    if (newValue.toString().equals("turkish")) {
                        LocaleHelper.setLocale(getContext(),"tr-rTR");
                        anyChanges = true;
                    }
                    if (newValue.toString().equals("english")){
                        LocaleHelper.setLocale(getContext(),"en");
                        anyChanges = true;
                    }
                    if (anyChanges){
                        getActivity().recreate();
                    }
                    return true;
                }
            }
            );

            return super.onCreateView(inflater, container, savedInstanceState);
        }
    }

2 Answers2

12

I have the same problem, and the result of my investigation of the problem is this: thig is a bug in MIUI from Xiaomi, so I bet you're using this ROM (like me), and the error occurs.

I believe there is nothing we can do about it.

STEPS TO REPRODUCE

It's very easy to reproduce the bug. We simply have to create a new Android Studio project, add a button to the activity's layout, and we recreate() the activity on the button click.

MainActivity.java:

package com.example;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button b = findViewById(R.id.button);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                recreate();
            }
        });
    }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Clicking the button on Galaxy Nexus Emulator (API 28, Android 9) gives this output in Logcat:

2021-03-16 05:47:34.981 5927-6028/com.example D/EGL_emulation: eglMakeCurrent: 0xe3a05120: ver 2 0 (tinfo 0xe3a03290)
2021-03-16 05:47:34.989 5927-6028/com.example D/OpenGLRenderer: endAllActiveAnimators on 0xce2d9080 (RippleDrawable) with handle 0xe3a03600
2021-03-16 05:47:35.077 5927-6028/com.example D/EGL_emulation: eglMakeCurrent: 0xe3a05120: ver 2 0 (tinfo 0xe3a03290)

Clicking on the button on my first real device - Samsung Galaxy S3 (API 25, Android 7.1.2, LineageOS 14.1) - gives no output.

Whereas another physical device - Xiaomi Redmi 7 (API 29, Android 10, MIUI Global 11.0.1) gives this on every button press and activity recreation:

2021-03-16 05:54:57.496 10989-10989/com.example W/ActivityThread: SCHED: com.example/.MainActivity [95, r=152ms, a=8ms, w=7395ms]
2021-03-16 05:54:57.517 10989-11032/com.example D/OpenGLRenderer: endAllActiveAnimators on 0x7c2ca87f00 (RippleDrawable) with handle 0x7ccb20d560
2021-03-16 05:54:57.591 10989-10989/com.example 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:1859)
        at androidx.fragment.app.FragmentActivity.onResume(FragmentActivity.java:456)
        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1454)
        at android.app.Activity.performResume(Activity.java:8050)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4245)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4287)
        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:5320)
        at android.app.ActivityThread.access$3500(ActivityThread.java:223)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2053)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:221)
        at android.app.ActivityThread.main(ActivityThread.java:7542)
        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)

So when we recreate the activity, the error:

E/ActivityInjector: get life cycle exception

clearly comes from MIUI/Xiaomi (at least in this experiment).

Rado
  • 133
  • 2
  • 7
  • 4
    I can confirm that this is Xiaomi Redmi Issue. I am trying to use the recreate() function on a Redmi 10S (MIUI 12.5.12, Android 11) and it keeps crashing with this exception. – El Nuru Oct 14 '21 at 15:52
  • In my case, the crash happened because I'm setting the brightness manually with `window.attributes.layoutParams.screenBrightness` – flamyoad Apr 14 '22 at 14:40
  • 1
    I can confirm that problem is observed on POCO X3 NFC (MIUI 12.5.8.0, Android 11) when I try to switch dark mode using `AppCompatDelegate.setDefaultNightMode`. The app does not crash and continues to work, but an error appears in the log. – Mikhail Feb 16 '23 at 14:34
  • same error case: xiaomi device @Mikhail show log error – Roger Jun 07 '23 at 05:10
0

Yes, recreate() itself causes an error on Xiaomi devices (might be some firmware or MIUI issues, but they don't care). However the app doesn't crash and works for me even if the error is shown in the logs.

I suggest to replace recreate() with

Intent i = new Intent(MainActivity.this, MainActivity.class); //change for your case
startActivity(i);

you can add overridePendingTransition(0, 0); to avoid flashing.

The error is now gone.

Darksymphony
  • 2,155
  • 30
  • 54