【问题标题】:Android: SharedPreferences editing not workingAndroid:SharedPreferences 编辑不起作用
【发布时间】:2014-07-25 05:30:51
【问题描述】:

我目前设置了SharedPreferences,如果用户选中checkBoxSharedPreferences 将被编辑为:

public class MainActivity extends Activity {

    public static SharedPreferences prefs;

    public void itemClicked(View v) {
        CheckBox checkBox = (CheckBox)v;
        prefs = this.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
        if(checkBox.isChecked()) prefs.edit().putBoolean("moveToSettings", false).commit();
        else prefs.edit().putBoolean("moveToSettings", true).commit();
    }    

我希望用户能够通过按下按钮resetapp 从另一个活动中编辑这些SharedPreferences。为此,这是我在另一个活动的 .java 文件上尝试的:

public class NextActivity extends Activity {

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

        final Button resetapp = (Button)findViewById(R.id.resetapp);

        resetapp.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {

                MainActivity.prefs.edit().putBoolean("moveToSettings", true).commit();

            }
        });
    }

但是,当用户按下按钮 resetapp 时,应用程序崩溃而不是更改 SharedPreferences。有谁知道为什么会这样?

这是我的LogCat 的输出:

06-04 10:20:20.455: W/dalvikvm(2808): threadid=1: thread exiting with uncaught exception (group=0x42d5d140)
06-04 10:20:20.545: E/AndroidRuntime(2808): FATAL EXCEPTION: main
06-04 10:20:20.545: E/AndroidRuntime(2808): Process: com.example.MyFirstApp, PID: 2808
06-04 10:20:20.545: E/AndroidRuntime(2808): java.lang.NullPointerException
06-04 10:20:20.545: E/AndroidRuntime(2808):     at com.example.MyFirstApp.NextActivity$1.onClick(NextActivity.java:32)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at android.view.View.performClick(View.java:4438)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at android.view.View$PerformClick.run(View.java:18422)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at android.os.Handler.handleCallback(Handler.java:733)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at android.os.Handler.dispatchMessage(Handler.java:95)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at android.os.Looper.loop(Looper.java:136)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at android.app.ActivityThread.main(ActivityThread.java:5017)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at java.lang.reflect.Method.invokeNative(Native Method)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at java.lang.reflect.Method.invoke(Method.java:515)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
06-04 10:20:20.545: E/AndroidRuntime(2808):     at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • 可能是因为prefs 为空,只需在您的其他活动中创建另一个 SharedPreferences 实例
  • 只做正确的方式而不是静态字段...
  • @Gaskoin 我在没有静态的情况下尝试过,然后我得到了Cannot make a static reference to the non-static field MainActivity.prefs
  • 我没有告诉你删除静态修饰符,而是以正常方式进行。创建单独的类来保存您的设置(在共享首选项中)并在两个活动的 onCreate 方法中获取它。然后您将调用方法 settings.setShouldMoveToSettings(true)、boolean shouldMoveToSettings = settings.shouldMoveToSettings() 等,而不是对字符串进行操作。设置类将在后台对共享首选项进行操作
  • 是的,静态是导致此问题的原因。只需在需要它们的地方获取默认首选项:PreferenceManager.getDefaultSharedPreferences(this) 其中this 是上下文实例。

标签: java android nullpointerexception sharedpreferences


【解决方案1】:

您可以为您的应用程序编写一个 SharedPrefance 类,并在其中编写一些 setter 和 getter 方法并使用它们。它;易于管理代码,您永远不会对您的应用程序首选项感到困惑。

    public class Pref {
    private static final String USER_ID = "userID";
    private static final String PREF_NAME = "Tim";

    private static Pref instance;
    private SharedPreferences preferences;
    private Editor editor;

    private Pref(Context context) {
        preferences = context.getSharedPreferences(PREF_NAME, 0);
        editor = preferences.edit();
    }

    public static Pref getInstance(Context context) {
        return instance == null ? new Pref(context) : instance;
    }

    public void setUserID(String userID) {
        editor.putString(USER_ID, userID).commit();
    }

    public String getUserID() {
        return preferences.getString(USER_ID, "");
    }
}

从应用程序中你可以通过调用来访问它

Pref.getInstance(this).setUserID("whatever");
Pref.getInstance(this).getUserID();

【讨论】:

    【解决方案2】:

    这很可能是共享首选项未注入的问题。

    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    
    // Change preferences
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putBoolean(“moveToSettings”, true);
    editor.commit();
    

    希望对你有帮助!

    【讨论】:

    • 这都是我的第二个活动?
    • 是的,我认为需要使用正确的上下文注入它。正如其他人提到的那样,日志转储会很好。
    • 当我尝试像在 MainActivity.java 上一样插入 SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences("com.example.app", Context.MODE_PRIVATE); 时,我收到了错误 The method getDefaultSharedPreferences(Context) in the type PreferenceManager is not applicable for the arguments (String, int)。有没有办法解决这个问题?
    • 像这样尝试 sharedPreferences = PreferenceManager .getDefaultSharedPreferences(getApplicationContext());
    • 是否在他的原始代码中放入布尔返回无效?这就是导致空指针的原因。我不认为 prefs 使用构建器模式。不过我可能是错的。
    【解决方案3】:

    Android 不保证NextActivity 处于前台时MainActivity 仍然存在(即,Activity 从视图中消失后可以立即销毁)。

    要访问可以从多个活动/服务中检索/保存的首选项,我建议将其放在 Android Application 类的子类中。

    例如,创建:

    public class Application extends android.app.Application {
    
        private SharedPreferences mPrefs;
        private static Application mApp;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            mApp = this;
            mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
        }
    
        public static Application get() {
            return mApp;
        }
    
        public static SharedPreferences getPrefs() {
            return get().mPrefs;
        }
    }
    

    您的AndroidManifest.xml 还需要android:name 属性来指向此类:

    <application
            android:name=".Application"
            android:icon="@drawable/ic_launcher"
            android:logo="@drawable/logo"
            android:label="@string/app_name">
    

    然后,您可以从任何 Activity 获取/设置首选项,如下所示:

    // Get a preference
    boolean currentValue = Application.getPrefs().getBoolean("moveToSettings", true);
    
    ...
    // Set a preference
    SharedPreferences.Editor edit = Application.getPrefs().edit();
    edit.putBoolean("moveToSettings", true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
        edit.apply();
    } else {
        edit.commit();
    }
    

    (也可以将上面设置的一些偏好代码封装在自己的helper静态类中)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      相关资源
      最近更新 更多