Android ActivityInjector:语言更改后获取生命周期异常

问题描述 投票:0回答:1

在我的 Android 应用程序中,我可以在两种语言之间进行简单的语言切换。

一切正常,语言切换良好,但我在真实设备上调试时注意到一个错误,这是以前没有的(小米红米9)。它说:

E/ActivityInjector:获取生命周期异常 java.lang.ClassCastException:android.os.BinderProxy 无法转换为 android.app.servertransaction.ClientTransaction 在 android.app.ActivityInjector.checkAccessControl(ActivityInjector.java:24) 在 android.app.Activity.onResume(Activity.java:1995) 在 androidx.fragment.app.FragmentActivity.onResume(FragmentActivity.java:434) 在 android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1457) 在 android.app.Activity.performResume(Activity.java:8264) 在 android.app.ActivityThread.performResumeActivity(ActivityThread.java:4494) 在 android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4536) 在 android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 在 android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) 在 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 在 android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:58) 在 android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5498) 在 android.app.ActivityThread.access 3400 美元(ActivityThread.java:244) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2114) 在 android.os.Handler.dispatchMessage(Handler.java:106) 在 android.os.Looper.loop(Looper.java:236) 在 android.app.ActivityThread.main(ActivityThread.java:7861) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)

但是应用程序没有崩溃并且运行良好,但错误仍然存在。

原因可能是,当我在语言更改生效并重新启动MainActivity后调用

super.recreate()
时。

当我阅读其他讨论时,这可能与小米有关,但我没有解决方案如何避免这种情况,或者至少尝试使用某些东西来代替

recreate()

这是 MainActivity,您可以在

saveLang
方法中看到我正在重新创建活动以反映新语言:

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");
    }
}

我尝试删除

super.recreate()
,然后错误就消失了,但是语言当然没有更新。

唯一有帮助的是使用:

Intent i = new Intent(MainActivity.this, MainActivity.class);
        overridePendingTransition(0, 0);
        startActivity(i);
        overridePendingTransition(0, 0);

而不是简单的

recreate()

有了这个,它就可以正常工作,没有任何错误,但我认为这有点矫枉过正。

android recreate
1个回答
0
投票

通过在托管片段的活动的清单中添加

 android:configChanges="orientation|screenSize|uiMode"
来解决。

MainActivity 托管片段所以

 <activity
        android:name=".activity.MainActivity"
        android:configChanges="orientation|screenSize|uiMode"
        android:exported="false"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateHidden" />

上面是清单中的最终代码。 您还应该在 style.xml 或 theme.xml 中添加以下内容

 <item name="android:forceDarkAllowed" tools:ignore="NewApi">false</item>
© www.soinside.com 2019 - 2024. All rights reserved.