In my android app I have a simple language switch between 2 languages.
Everything is working fine, the language is switched well, but I noticed an error when debugging on real device, that was not there before (Xiaomi Redmi 9). It says:
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:1995) at androidx.fragment.app.FragmentActivity.onResume(FragmentActivity.java:434) at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1457) at android.app.Activity.performResume(Activity.java:8264) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4494) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4536) 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:58) at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5498) at android.app.ActivityThread.access$3400(ActivityThread.java:244) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2114) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:236) at android.app.ActivityThread.main(ActivityThread.java:7861) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
However the app doesn't crash and works well, but the error is there.
The cause might be, when I call super.recreate()
after the language is changed to take effect and restart the MainActivity.
As I read other discussions, it might be Xiaomi related, but I have no solution how to avoid this or at least to try using something instead recreate()
.
Here is MainActivity, you can see in saveLang
method I am recreating the activity to reflect the new language:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(getSupportActionBar() != null){
getSupportActionBar().hide();}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if(!prefs.getBoolean("firstTime", false)) {
String languageToLoad;
languageToLoad = Resources.getSystem().getConfiguration().getLocales().get(0).getLanguage();
lng = "sk".equals(languageToLoad) ? "sk" : "en";
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstTime", true);
editor.putString("langx", lng);
editor.apply();
} else {lng = readLang();}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
updateBaseContextLocale(getBaseContext());
}
this.setContentView(R.layout.activity_main);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(updateBaseContextLocale(base));
}
private Context updateBaseContextLocale(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
if(!prefs.getBoolean("firstTime", false)) {
String languageToLoad;
languageToLoad = Resources.getSystem().getConfiguration().getLocales().get(0).getLanguage();
if ("sk".equals(languageToLoad) || "cs".equals(languageToLoad))
{lng = "sk";} else {lng = "en";}
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstTime", true);
editor.putString("langx", lng);
editor.apply();}
else {
lng = prefs.getString("langx", "sk");
}
if(lng==null) {lng="sk";}
Locale locale = new Locale(lng);
Locale.setDefault(locale);
return updateResourcesLocale(context, locale);
}
private Context updateResourcesLocale(Context context, Locale locale) {
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
return context.createConfigurationContext(configuration);
}
public void Langsk(View view)
{
String lng = readLang();
String newlng;
if (!lng.equals("sk")) {
newlng = "sk";
saveLang(newlng);
}
}
public void Langen(View view)
{
String lng = readLang();
String newlng;
if (lng.equals("sk")) {
newlng = "en";
saveLang(newlng);
}
}
private void saveLang(String lng) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
sharedPreferences.edit().putString("langx", lng).apply();
super.recreate();
overridePendingTransition(0, 0);
}
private String readLang() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
return sharedPreferences.getString("langx", "sk");
}
}
I tried to remove super.recreate()
, then the error is gone, but of course the language is not updated.
The only thing that helped is to use:
Intent i = new Intent(MainActivity.this, MainActivity.class);
overridePendingTransition(0, 0);
startActivity(i);
overridePendingTransition(0, 0);
instead of simple recreate()
.
With this is it working without any error, however I think this is a bit an overkill.