android,如果过早重启应用程序,为什么保存到首选项不起作用?

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

在 Android 应用程序中,有一个带有复选框项的选项菜单,当单击复选框进行切换时,它想要重新启动应用程序以开始进行一些更改。

所以当复选框被点击时,在

onOptionsItemSelected
它将选中状态保存到首选项,然后重新启动应用程序。但是似乎当应用程序重新启动并且从首选项中读取它仍然具有未更改的检查状态(与点击之前的状态相同)。

但是如果延迟重启100ms,那么在重启的时候会正常获取保存的检查状态。

应用程序重新启动的方式有什么问题吗?



    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
           
            case R.id.is_checked:

                boolean checked = !item.isChecked();

                Log.w("+++", "+++ onOptionsItemSelected(), !item.isChecked() - checked: "+checked);

                item.setChecked(checked);
                updateIsCheckedInRegistry(checked);  //<=== save to prefs

                boolean isChecked_reg = getIsCheckedFromRegistry(); //<=== read from the registry to verify
                Log.w("+++", "+++  after save, make sure reading from the prefs, reg - isChecked_reg: "+isChecked_reg);

                //restartApp(this);  //<=== immediately call does not work, after restart app still having the old check state

                final Context THIS = this;
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        restartApp(THIS);
                    }
                };
                new Handler().postDelayed(runnable, 100);  // delay 50 ms does not work either

                
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
    public static void restartApp(Context context) {
        PackageManager packageManager = context.getPackageManager();
        Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
        ComponentName componentName = intent.getComponent();
        Intent mainIntent = Intent.makeRestartActivityTask(componentName);
        context.startActivity(mainIntent);
        
        Runtime.getRuntime().exit(0);
    }
        
    private boolean getIsCheckedFromRegistry() {
        return PreferenceManager.getDefaultSharedPreferences(this)
                .getBoolean(PREFS_DEMO_IS_CHECKED, true);
    }
    
    private void updateIsCheckedInRegistry(boolean isChecked) {
        Log.w("+++", "+++ updateIsCheckedInRegistry(), isChecked: "+isChecked);

        PreferenceManager.getDefaultSharedPreferences(this).edit()
                .putBoolean(PREFS_DEMO_IS_CHECKED, isChecked).apply();
    }
android sharedpreferences application-restart
2个回答
0
投票

因为你正在使用apply。 Apply 在后台执行此操作以避免阻塞线程。如果您想立即写入,请改用 commit() 。


0
投票

SharedPreferences.Editor#apply() 会立即在内存中进行更改,并且磁盘更改会排队等待异步写入。主线程继续执行,无需等待写入发生在工作线程上。

如果进程没有等待磁盘变化就结束了,下次它会从磁盘加载旧值。

值得检查SharedPreferencesImpl

的源代码
© www.soinside.com 2019 - 2024. All rights reserved.