Android:通过SharedPreferences跨Activity获取CheckBox值时触发空指针异常
我尝试通过SharedPreferences从MainActivity获取MainActivity2中CheckBox的状态值,因为要持久化保存CheckBox状态,所以使用了SharedPreferences。在MainActivity2内部调用getBooleanFromPref(key)方法能正常返回正确结果,但在MainActivity中调用该方法时却抛出NullPointerException。
代码示例
MainActivity代码
public class MainActivity extends AppCompatActivity { private Button buttonResult, buttonActivity2; private TextView tv_cb; private MainActivity2 mainActivity2 = new MainActivity2(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonResult = findViewById(R.id.btn_result); buttonActivity2 = findViewById(R.id.btn_goToAct2); tv_cb = findViewById(R.id.tv_cb); buttonActivity2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(getApplicationContext(), MainActivity2.class)); } }); buttonResult.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { tv_cb.setText(String.valueOf(mainActivity2.getBooleanFromPref("checkedCB"))); } }); } }
MainActivity2代码
public class MainActivity2 extends AppCompatActivity { private CheckBox checkBox; private SharedPreferences preferences; private SharedPreferences.Editor editor; private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); checkBox = findViewById(R.id.checkBox); button = findViewById(R.id.btn_back); //--------------------------------------Shared Prefs----------------------------------------------- preferences = PreferenceManager.getDefaultSharedPreferences(this); editor = preferences.edit(); //--------------------------------------Shared Prefs for Checkbox---------------------------------------------------------- if (preferences.contains("checkedCB") && preferences.getBoolean("checkedCB", false) == true) { checkBox.setChecked(true); } else { checkBox.setChecked(false); } checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { if (checkBox.isChecked()) { editor.putBoolean("checkedCB", true); editor.apply(); checkBox.setChecked(true); } else { editor.putBoolean("checkedCB", false); editor.apply(); checkBox.setChecked(false); } } }); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(MainActivity2.this, "Checkbox-Status: " + String.valueOf(getBooleanFromPref("checkedCB")), Toast.LENGTH_SHORT).show(); startActivity(new Intent(getApplicationContext(), MainActivity.class)); } }); } public boolean getBooleanFromPref(String key){ return preferences.getBoolean(key, false); } }
注:getBooleanFromPref方法在MainActivity2内部可正常工作。我还尝试过其他方式获取值:给CheckBox写getter方法、用Intent传递,都没解决问题;也修改过Manifest中的android:allowBackup属性为false,同样无效。
报错信息
java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.content.SharedPreferences.getBoolean(java.lang.String, boolean)' on a null object reference at com.example.checkbox_test.MainActivity2.getBooleanFromPref(MainActivity2.java:66) at com.example.checkbox_test.MainActivity$2.onClick(MainActivity.java:38) at android.view.View.performClick(View.java:7441) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1211)
空指针异常原因
- 手动实例化Activity违反生命周期规则:你在MainActivity里直接用
new MainActivity2()创建了Activity实例,而Android的Activity必须由系统通过startActivity()等方式创建,手动new的实例不会触发onCreate()方法,导致preferences变量从未被初始化,一直是null。 - 调用未初始化的变量:当你调用
mainActivity2.getBooleanFromPref("checkedCB")时,方法内部尝试访问null的preferences对象,自然抛出空指针异常。
正确解决方案
SharedPreferences是应用级别的持久化存储,任何组件都可以直接读取,不需要依赖其他Activity实例。直接在MainActivity里读取即可:
修改MainActivity中buttonResult的点击事件:
buttonResult.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 直接在MainActivity中获取SharedPreferences并读取值 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); boolean isChecked = preferences.getBoolean("checkedCB", false); tv_cb.setText(String.valueOf(isChecked)); } });
同时注意:
- 永远不要手动实例化Activity,所有Activity的创建都交给系统处理。
- SharedPreferences的读写操作不需要通过其他Activity中转,直接在需要的组件中操作即可。
内容的提问来源于stack exchange,提问作者Mc_Android
相关产品推荐
相关产品推荐

