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

时间:2013-12-04 07:03:07

标签: android nullpointerexception sharedpreferences

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

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

这是我的帮助班。

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...
    */
}

我在NullPointerException方法获得了preferences.getBoolean()。我假设preferences在静态调用方法时为空。

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

我已经阅读了Android开发人员的参考资料和其他几个问题,但没有一个能解决这个问题。任何有关此问题的指导,建议或确切解决方案都将受到高度赞赏。

更新:LOGCAT ERROR

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

这是我的Manifest的

<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>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            <action android:name="android.intent.action.REBOOT" />
        </intent-filter>
    </receiver>

    <service android:name=".InformerService" >
        <intent-filter>
            <action android:name="np.com.njs.statusinformer.InformerService" />
        </intent-filter>
    </service>

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

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

7 个答案:

答案 0 :(得分:2)

您的saveBoolean方法错误。纠正这一点。奇怪的是,方法返回类型是无效的,你从那里返回一些东西。

public static void saveBoolean(String key, boolean value) {
    updater.putBoolean(key, value);
     updater.commit();

}

您可以编写如下方式的辅助方法

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

    }

并用作

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

答案 1 :(得分:1)

在提出请求之后

执行此操作:)

prefs.edit().commit();

答案 2 :(得分:0)

检查您的应用程序清单文件,在应用程序标记中使用app类名称或不使用suggetion是不要将自定义应用程序类作为其他类的内部类

答案 3 :(得分:0)

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

以下方法的关键应该是“auto_start”。如果不是,则会引发空指针异常

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

以下是我的应用中的样本

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

您的偏好设为null,因为您使用的是 MyHelper 类对象来初始化它,而不是活动。您必须提供Activity实例来初始化您的首选项。设置值后,使用 commit()完成保存操作。

答案 6 :(得分:0)

通过清除所有shared_prefs(清除应用程序数据)解决了该问题。问题是由数据类型的差异引起的,例如。我正在访问一个字符串作为布尔值。