SharedPreferences检查导致布尔值的Null Pointer Exception

时间:2019-01-13 11:49:10

标签: android

我正在尝试为我们的SharedPreferences设置一个标志,以在我的应用程序中启用“开发模式”。我创建了一个布尔并将其设置为false,然后输入正确的命令后,应用程序会将其设置为true。

但是,每次尝试读取此新的SharedPreference时,都会得到一个空指针异常,即使通过日志记录表明它按预期返回了false。

我的splashScreen活动充当我的主要角色:

public class splashScreen extends AppCompatActivity {

    public static String jsonURL="https://www.tourofhonor.com/BonusData.json";
    public static String jsonDevURL="https://www.tommyc.net/BonusData.json";

    SharedPreferences sharedpreferences;
    public static final String tohPreferences = "Tour of Honor Preferences";
    public static final String riderNum = "RiderNumber";
    public static final String pillionNum = "PillionNumber";
    public static final String devModeStatus = "DevModeStatus";

    public static String riderNumToH;
    public static String pillionNumToH;
    public static boolean devModeOn = false;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e("splashScreen","Creating Splash Screen");
        setContentView(R.layout.activity_splash_screen);

        sharedpreferences = getSharedPreferences(tohPreferences,
                Context.MODE_PRIVATE);
        if (sharedpreferences.contains(riderNum)) {
            Log.e("splashScreen","riderNum set to " + riderNum);
            riderNumToH = sharedpreferences.getString(riderNum,"000");
        } else {
            Log.e("splashScreen","riderNum Failed");
        }
        if (sharedpreferences.contains(pillionNum)) {
            Log.e("splashScreen","pillionNum set to " + pillionNum);
            pillionNumToH = sharedpreferences.getString(pillionNum,"000");
        } else {
            Log.e("splashScreen","pillionNum Failed");
        }
        if (sharedpreferences.contains(devModeStatus)) {
            Log.e("splashScreen","Dev Mode set to " + devModeStatus + devModeOn);
            devModeOn = sharedpreferences.getBoolean(devModeStatus,false);
        } else {
            Log.e("splashScreen","devModeStatus Failed " +devModeStatus + devModeOn);
        }
    }

    public void goToBonusDetail (View View) {
        Log.e("splashScreen","Gong to Bonus Detail");
        Intent goToBonusDetail = new Intent(this, captureBonus.class);
        startActivity(goToBonusDetail);
    }

    public void goToBonusList (View View) {
        Log.e("splashScreen","Going to Bonus List");
        Intent goToBonusList = new Intent(this,bonusListing.class);
        startActivity(goToBonusList);
    }
}

splashScreen页面已加载,但是我的日志记录显示它使用了我的else语句来表示布尔值(对于SharedPreferences的另外两个调用来说,它是正确的一面)。

三个SharedPreferences调用的Logcat输出:

E/splashScreen: riderNum set to RiderNumber
E/splashScreen: pillionNum set to PillionNumber
E/splashScreen: devModeStatus Failed DevModeStatusfalse

但是当我进入我的BonusListing页面时,我立即获得了NPE,它指向第35行:

devModeOn = sharedpreferences.getBoolean(devModeStatus,false); 

这是bonusListing类:

public class bonusListing extends AppCompatActivity {

    SharedPreferences sharedpreferences;
    ArrayList<jsonBonuses> dataModels;
    ListView listView;
    private static jsonToListViewAdapter adapter;

    ListView lv;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bonus_listing);
        Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(myToolbar);
        devModeOn = sharedpreferences.getBoolean(devModeStatus,false);

        if (!devModeOn) {
            jsonURL = "https://www.tourofhonor.com/BonusData.json";
        } else if (devModeOn) {
            jsonURL = "https://www.tommyc.net/BonusData.json";
        } else {
            Log.e("bonusListing", "Invalid Dev Mode Setting");
            return;
        }

        listView = (ListView) findViewById(R.id.lvBonusData);
        new jsonDownloader(bonusListing.this,jsonURL, lv).execute();

        // Populate the DataModel with some false data for testing purposes
        dataModels= new ArrayList<>();

        // dataModels.add(new jsonBonuses("BC1", "category1", "name1",1,"address1","city1","state1","GPS1","access1","flavor1","madeInAmerica1","imageName"));
        // dataModels.add(new jsonBonuses("BC2", "category2", "name2",2,"address2","city2","state2","GPS2","access2","flavor2","madeInAmerica2","imageName"));

        adapter= new jsonToListViewAdapter(dataModels,getApplicationContext());
        if(adapter != null) {
            Log.e("onCreate","entered adapter code");
            listView.setAdapter(adapter);
        } else {
            Log.e("onCreate","adapter has no data");
        }

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                jsonBonuses dataModel= dataModels.get(position);

                Log.e("onClick for Data Row","Tapped on row");
            }
            });
    }
  ... // Omitted code that isn't related to the above for brevity.
}

编辑:这是堆栈跟踪:

java.lang.RuntimeException: Unable to start activity ComponentInfo{net.tommyc.android.tourofhonor/net.tommyc.android.tourofhonor.bonusListing}: java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.content.SharedPreferences.getBoolean(java.lang.String, boolean)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3194)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302)
        at android.app.ActivityThread.-wrap12(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891)
        at android.os.Handler.dispatchMessage(Handler.java:108)
        at android.os.Looper.loop(Looper.java:166)
        at android.app.ActivityThread.main(ActivityThread.java:7425)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
     Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.content.SharedPreferences.getBoolean(java.lang.String, boolean)' on a null object reference
        at net.tommyc.android.tourofhonor.bonusListing.onCreate(bonusListing.java:35)
        at android.app.Activity.performCreate(Activity.java:7372)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3147)

为什么我要在这里得到NPE?我在创建时将其设置为false,并且在两个调用中都将false用作默认值,所以我很茫然。

1 个答案:

答案 0 :(得分:1)

将此行放在bonusListing活动中的setConentViewMethod之后

 sharedpreferences = getSharedPreferences(tohPreferences,
                    Context.MODE_PRIVATE);

因为您使用了共享首选项对象而没有初始化

和此字符串

public static final String tohPreferences = "Tour of Honor Preferences";

在奖金列表活动开始时