Android:使用SharedPreferences时出现奇怪的NullPointerException

Android: Strange NullPointerException while using SharedPreferences

我正在尝试创建一个静态包装类来处理我的应用程序的共享首选项。我创建了一个助手类MyHelper,其中包含另一个类Setting,用于处理应用程序共享首选项的设置和获取值。我想用这种方式使用helper方法-

1
2
MyHelper.Setting.saveBoolean("auto_start", true);
MyHelper.Setting.grabBoolean("auto_start");

这是我的助手课程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MyHelper{

    public static class Setting extends android.app.Application {
        private static Context currentContext;
        private static SharedPreferences preferences;
        private static Editor updater;

        @Override
        public void onCreate(){
            super.onCreate();
            currentContext = this;
            preferences = PreferenceManager
                .getDefaultSharedPreferences(currentContext);
            updater = preferences.edit();
        }

        public static boolean grabBoolean(String key) {
            return preferences.getBoolean(key, false);
        }
        public static void saveBoolean(String key, boolean value) {
            preferences.putBoolean(key, value).commit();
        }
    }

    /*
    *    Some other nested classes here...
    */
}

我用preferences.getBoolean()方法得到NullPointerException。在静态调用方法时,我假定preferences为空。

通过扩展android.app.Application获取应用程序上下文的方法是否错误?我想知道从应用程序中使用的任何服务、活动、广播接收器或助手类获取应用程序上下文的最佳方法是什么。

我已经阅读了Android开发者的参考资料和其他几个问题,但没有一个能解决这个问题。对于这个问题的任何指导、建议或确切的解决方案,我们都将非常感谢。

更新:logcat错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
12-04 12:14:47.467: E/AndroidRuntime(514): FATAL EXCEPTION: main

12-04 12:14:47.467: E/AndroidRuntime(514): java.lang.RuntimeException: Unable to start activity ComponentInfo{np.com.njs.statusinformer/np.com.njs.statusinformer.Setup}: java.lang.NullPointerException
12-04 12:14:47.467: E/AndroidRuntime(514):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
12-04 12:14:47.467: E/AndroidRuntime(514):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
12-04 12:14:47.467: E/AndroidRuntime(514):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
12-04 12:14:47.467: E/AndroidRuntime(514):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
12-04 12:14:47.467: E/AndroidRuntime(514):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-04 12:14:47.467: E/AndroidRuntime(514):     at android.os.Looper.loop(Looper.java:123)
12-04 12:14:47.467: E/AndroidRuntime(514):     at android.app.ActivityThread.main(ActivityThread.java:3683)
12-04 12:14:47.467: E/AndroidRuntime(514):     at java.lang.reflect.Method.invokeNative(Native Method)
12-04 12:14:47.467: E/AndroidRuntime(514):     at java.lang.reflect.Method.invoke(Method.java:507)
12-04 12:14:47.467: E/AndroidRuntime(514):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
12-04 12:14:47.467: E/AndroidRuntime(514):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
12-04 12:14:47.467: E/AndroidRuntime(514):     at dalvik.system.NativeStart.main(Native Method)
12-04 12:14:47.467: E/AndroidRuntime(514): Caused by: java.lang.NullPointerException
12-04 12:14:47.467: E/AndroidRuntime(514):     at np.com.njs.statusinformer.InformerHelper$Setting.grabBoolean(InformerHelper.java:115)
12-04 12:14:47.467: E/AndroidRuntime(514):     at np.com.njs.statusinformer.Setup.loadPreferences(Setup.java:102)
12-04 12:14:47.467: E/AndroidRuntime(514):     at np.com.njs.statusinformer.Setup.onCreate(Setup.java:31)
12-04 12:14:47.467: E/AndroidRuntime(514):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-04 12:14:47.467: E/AndroidRuntime(514):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
12-04 12:14:47.467: E/AndroidRuntime(514):     ... 11 more

这是我的舱单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<application
    android:allowBackup="true"
    android:debuggable="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    <receiver android:name="np.com.njs.statusinformer.BootCompleteReceiver">
        <intent-filter>
           
           
           
        </intent-filter>
    </receiver>

    <service android:name=".InformerService">
        <intent-filter>
           
        </intent-filter>
    </service>

    <activity
        android:name="np.com.njs.statusinformer.Setup"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:label="@string/app_name">
        <intent-filter>
           

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>


你的saveBoolean方法是错误的。纠正这一点。奇怪的是,方法返回类型是空的,您从中返回了一些东西。

1
2
3
4
5
public static void saveBoolean(String key, boolean value) {
    updater.putBoolean(key, value);
     updater.commit();

}

您可以编写如下帮助方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MyPrefs {

        private static final String PREF_NAME ="My_prefs";

        public static void saveBoolean(Context mContext, String key, boolean value) {
            SharedPreferences sharedPref = mContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPref.edit();
            editor.putBoolean(key, value);
            editor.commit();
        }

        public static boolean getBoolean(Context mContext, String key) {
            SharedPreferences sharedPref = mContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
            return sharedPref.getBoolean(key, false);
        }

    }

并用作

1
2
3
4
// To store
MyPrefs.saveBoolean(getApplicationContext(),"my_bool", true);
// To read
MyPrefs.getBoolean(getApplicationContext(),"my_bool");


发出请求后,请执行以下操作:)

1
prefs.edit().commit();


通过清除所有共享的前缀(清除应用程序数据)解决了这个问题。这个问题是由数据类型的不同引起的,例如,我以布尔值的形式访问一个字符串。


您的首选项为空,因为您正在使用MyHelper类对象初始化它,而该对象不是活动。您必须提供活动实例才能初始化您的首选项。在放入值后,使用commit()完成保存操作。


检查androidmanifest.xml文件中的应用程序标记。您应该在android:name属性中正确定义类名。


1
2
MyHelper.Setting.saveBoolean("auto_start", true);
MyHelper.Setting.grabBoolean("auto_start");

以下方法的键应为"auto-start"。如果不是,则将引发空指针异常。

1
2
3
4
5
6
 public static boolean grabBoolean(String key) {
            return preferences.getBoolean(key, false);
        }
        public static void saveBoolean(String key, boolean value) {
            return preferences.putBoolean(key, value);
        }

以下是我的应用程序中正在运行的示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static final String PREF_USER_NAME="USER_NAME";
public static SharedPreferences getSharedPreferences(Context ctx) {
        return PreferenceManager.getDefaultSharedPreferences(ctx);
    }

public static void setUserName(Context ctx, String userid) {
        Editor editor = getSharedPreferences(ctx).edit();
        editor.putString(PREF_USER_NAME, userid);
        editor.commit();
    }

    public static String getUserName(Context ctx) {
        return getSharedPreferences(ctx).getString(PREF_USER_NAME,"");
    }


检查应用程序清单文件,在该文件中,在应用程序标记中使用或不使用应用程序类名,建议不要将自定义应用程序类作为其他类的内部类。