共享首选项在切换片段时导致空指针异常
Shared Preferences causing null pointer exception when switching fragments
我正在开发基于片段的 Android 应用程序。在此应用程序中,它从网站上抓取一些信息并将其存储在 SharedPreferences
中以比较用户想要显示的内容。因此,用户输入他们正在寻找的一些地图,应用程序每 12 秒抓取一次网络,如果它与用户的输入匹配,它会发送通知。现在这适用于作为处理程序的计时器,当您切换片段时,它会在 12 秒后停止并给出空指针异常。
如果片段处于活动状态时它可以正常工作,为什么要这样做?这是一些代码。
关于创建方法
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.fragment_map, container, false);
textView = (AutoCompleteTextView) v.findViewById(R.id.map_list);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_dropdown_item_1line, Maps1);
textView.setThreshold(3);
textView.setAdapter(adapter);
mButton1 = (Button) v.findViewById(R.id.MapButton1);
mButton2 = (Button) v.findViewById(R.id.MapButton2);
mButton3 = (Button) v.findViewById(R.id.MapButton3);
mButton1.setOnClickListener(onClick());
mButton2.setOnClickListener(onClick());
mButton3.setOnClickListener(onClick());
dButton1 = (Button) v.findViewById(R.id.DeleMap1);
dButton2 = (Button) v.findViewById(R.id.DeleMap2);
dButton3 = (Button) v.findViewById(R.id.DeleMap3);
dButton1.setOnClickListener(onClick());
dButton2.setOnClickListener(onClick());
dButton3.setOnClickListener(onClick());
MapTV1 = (TextView) v.findViewById(R.id.topText1);
MapTV2 = (TextView) v.findViewById(R.id.topText2);
MapTV3 = (TextView) v.findViewById(R.id.topText3);
LowTV1 = (TextView) v.findViewById(R.id.belowText1);
LowTV2 = (TextView) v.findViewById(R.id.belowText2);
LowTV3 = (TextView) v.findViewById(R.id.belowText3);
LowTV4 = (TextView) v.findViewById(R.id.testView);
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
@SuppressWarnings("unchecked")
public void run() {
try {
//new Description().execute();
startTimer(120000);
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 120000);
//Notification area again *****************************************************************
userNotification = new NotificationCompat.Builder(getActivity());
userNotification.setAutoCancel(true);
// Done ***********************************************************************************
// Set user preferred maps on build *******************************************************
SharedPreferences spFirstWanted = getActivity().getSharedPreferences("first_map", 17);
String FirstWanted = spFirstWanted.getString("Firstwantedmap", "");
MapTV1.setText(FirstWanted);
SharedPreferences spSecondWanted = getActivity().getSharedPreferences("second_map", 18);
String SecondWanted = spSecondWanted.getString("Secondwantedmap", "");
MapTV2.setText(SecondWanted);
SharedPreferences spThirdWanted = getActivity().getSharedPreferences("third_map", 19);
String ThirdWanted = spThirdWanted.getString("Thirdwantedmap", "");
MapTV3.setText(ThirdWanted);
return v;
}
抛出空指针异常的Asynctask之一
class Medium extends AsyncTask<String, String, String> {
String desc;
protected String doInBackground(String... params) {
try {
Document document = Jsoup.connect(mediumURL).get();
Element table = document.select("table").get(0); //select the first table.
Elements rows = table.select("tr:eq(6) > td.infodata > a ");
for (Element td : rows) {
System.out.println("TD" + td.text());
return (td.text());
}
//return (td.text());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(final String result3) {
if (!result3.equals(null)) {
new CountDownTimer(6000, 1000) {
public void onTick(long millisUntilFinished) {
}
public final void onFinish() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
//SharedPreferences sp = getActivity().getSharedPreferences("medium", 23);
SharedPreferences.Editor sedt = sp.edit();
sedt.putString("MediumMap", result3);
sedt.commit();
}
}.start();
LowTV4.setText(result3);
} else if (result3.equals(null)) {
MapTV3.setText("Choose a map");
} else if (result3.equals("")) {
MapTV3.setText("Choose a new map");
}
}
}
定时器
private void startTimer(long milliseconds) {
CountDownTimer counter = new CountDownTimer(milliseconds, 1200000){
public void onTick(long millisUntilDone) {
}
public void onFinish() {
new Description().execute(url);
new Map2().execute(url2);
new EasyTwo().execute(easyTwoURL);
new Medium().execute(mediumURL);
SharedPreferences spFirstWanted = PreferenceManager.getDefaultSharedPreferences(getActivity());
String FirstWanted = spFirstWanted.getString("Firstwantedmap", "");
SharedPreferences spSecondWanted = getActivity().getSharedPreferences("second_map", 18);
String SecondWanted = spSecondWanted.getString("Secondwantedmap", "");
SharedPreferences spThirdWanted = getActivity().getSharedPreferences("third_map", 19);
String ThirdWanted = spThirdWanted.getString("Thirdwantedmap", "");
MapTV3.setText(FirstWanted);
SharedPreferences beginnerSP = getActivity().getSharedPreferences("beginner", 20);
String BeginnerValue = beginnerSP.getString("BeginnerMap", "");
SharedPreferences easySP = getActivity().getSharedPreferences("easy", 21);
String EasyValue = easySP.getString("EasyMap", "");
SharedPreferences easyTwoSP = getActivity().getSharedPreferences("easyTwo", 22);
String EasyTwoValue = easyTwoSP.getString("EasyTwoMap", "");
SharedPreferences mediumSP = getActivity().getSharedPreferences("medium", 23);
String mediumValue = mediumSP.getString("MediumMap", "");
//Toast.makeText(getActivity(),/*"beginner " + prefs2 + " and easy " + prefs3 + " and easy2 " + prefs4 +*/ " medium " + mediumValue,Toast.LENGTH_LONG).show();
if (BeginnerValue.equals(FirstWanted)) {
setUserNotification(BeginnerValue, "Beginner");
} else if(EasyValue.equals(FirstWanted)) {
setUserNotification(EasyValue, "Easy");
} else if(EasyTwoValue.equals(FirstWanted)) {
setUserNotification(EasyTwoValue, "Easy Two");
} else if(mediumValue.equals(FirstWanted)) {
setUserNotification(mediumValue, "Medium");
} else {
System.out.print("They Don't Match!");
LowTV3.setText("They don't match!");
}
}
};
counter.start();
}
有些东西现在只是将测试内容打印到屏幕上,以确保 SharedPreferences
正常工作,感谢您的帮助。
错误日志
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.preference.PreferenceManager.getDefaultSharedPreferencesName(PreferenceManager.java:376)
at android.preference.PreferenceManager.getDefaultSharedPreferences(PreferenceManager.java:371)
at com.horizonservers.horizon.MapFragment$Medium.onFinish(MapFragment.java:658)
at android.os.CountDownTimer.handleMessage(CountDownTimer.java:127)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
好像删除了片段后的getActivity()
returnnull
因此您应该先入库 getActivity()
或 getActivity().getApplicationContext()
的价值。 (在 Runnable 实例和 Medium 实例中)
然后使用该值代替 getActivity()
。
那是因为SharedPreferences context
在切换fragment的时候被销毁了,所以它现在指向一个之前被销毁的空对象
使用 WeakReference 或使用 Singleton 作为首选项实用程序。
对于单例首选项实用程序,您可以查看Prefs.java from Pixplicity EasyPreferences。
我正在开发基于片段的 Android 应用程序。在此应用程序中,它从网站上抓取一些信息并将其存储在 SharedPreferences
中以比较用户想要显示的内容。因此,用户输入他们正在寻找的一些地图,应用程序每 12 秒抓取一次网络,如果它与用户的输入匹配,它会发送通知。现在这适用于作为处理程序的计时器,当您切换片段时,它会在 12 秒后停止并给出空指针异常。
如果片段处于活动状态时它可以正常工作,为什么要这样做?这是一些代码。
关于创建方法
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.fragment_map, container, false);
textView = (AutoCompleteTextView) v.findViewById(R.id.map_list);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_dropdown_item_1line, Maps1);
textView.setThreshold(3);
textView.setAdapter(adapter);
mButton1 = (Button) v.findViewById(R.id.MapButton1);
mButton2 = (Button) v.findViewById(R.id.MapButton2);
mButton3 = (Button) v.findViewById(R.id.MapButton3);
mButton1.setOnClickListener(onClick());
mButton2.setOnClickListener(onClick());
mButton3.setOnClickListener(onClick());
dButton1 = (Button) v.findViewById(R.id.DeleMap1);
dButton2 = (Button) v.findViewById(R.id.DeleMap2);
dButton3 = (Button) v.findViewById(R.id.DeleMap3);
dButton1.setOnClickListener(onClick());
dButton2.setOnClickListener(onClick());
dButton3.setOnClickListener(onClick());
MapTV1 = (TextView) v.findViewById(R.id.topText1);
MapTV2 = (TextView) v.findViewById(R.id.topText2);
MapTV3 = (TextView) v.findViewById(R.id.topText3);
LowTV1 = (TextView) v.findViewById(R.id.belowText1);
LowTV2 = (TextView) v.findViewById(R.id.belowText2);
LowTV3 = (TextView) v.findViewById(R.id.belowText3);
LowTV4 = (TextView) v.findViewById(R.id.testView);
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
@SuppressWarnings("unchecked")
public void run() {
try {
//new Description().execute();
startTimer(120000);
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 120000);
//Notification area again *****************************************************************
userNotification = new NotificationCompat.Builder(getActivity());
userNotification.setAutoCancel(true);
// Done ***********************************************************************************
// Set user preferred maps on build *******************************************************
SharedPreferences spFirstWanted = getActivity().getSharedPreferences("first_map", 17);
String FirstWanted = spFirstWanted.getString("Firstwantedmap", "");
MapTV1.setText(FirstWanted);
SharedPreferences spSecondWanted = getActivity().getSharedPreferences("second_map", 18);
String SecondWanted = spSecondWanted.getString("Secondwantedmap", "");
MapTV2.setText(SecondWanted);
SharedPreferences spThirdWanted = getActivity().getSharedPreferences("third_map", 19);
String ThirdWanted = spThirdWanted.getString("Thirdwantedmap", "");
MapTV3.setText(ThirdWanted);
return v;
}
抛出空指针异常的Asynctask之一
class Medium extends AsyncTask<String, String, String> {
String desc;
protected String doInBackground(String... params) {
try {
Document document = Jsoup.connect(mediumURL).get();
Element table = document.select("table").get(0); //select the first table.
Elements rows = table.select("tr:eq(6) > td.infodata > a ");
for (Element td : rows) {
System.out.println("TD" + td.text());
return (td.text());
}
//return (td.text());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(final String result3) {
if (!result3.equals(null)) {
new CountDownTimer(6000, 1000) {
public void onTick(long millisUntilFinished) {
}
public final void onFinish() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
//SharedPreferences sp = getActivity().getSharedPreferences("medium", 23);
SharedPreferences.Editor sedt = sp.edit();
sedt.putString("MediumMap", result3);
sedt.commit();
}
}.start();
LowTV4.setText(result3);
} else if (result3.equals(null)) {
MapTV3.setText("Choose a map");
} else if (result3.equals("")) {
MapTV3.setText("Choose a new map");
}
}
}
定时器
private void startTimer(long milliseconds) {
CountDownTimer counter = new CountDownTimer(milliseconds, 1200000){
public void onTick(long millisUntilDone) {
}
public void onFinish() {
new Description().execute(url);
new Map2().execute(url2);
new EasyTwo().execute(easyTwoURL);
new Medium().execute(mediumURL);
SharedPreferences spFirstWanted = PreferenceManager.getDefaultSharedPreferences(getActivity());
String FirstWanted = spFirstWanted.getString("Firstwantedmap", "");
SharedPreferences spSecondWanted = getActivity().getSharedPreferences("second_map", 18);
String SecondWanted = spSecondWanted.getString("Secondwantedmap", "");
SharedPreferences spThirdWanted = getActivity().getSharedPreferences("third_map", 19);
String ThirdWanted = spThirdWanted.getString("Thirdwantedmap", "");
MapTV3.setText(FirstWanted);
SharedPreferences beginnerSP = getActivity().getSharedPreferences("beginner", 20);
String BeginnerValue = beginnerSP.getString("BeginnerMap", "");
SharedPreferences easySP = getActivity().getSharedPreferences("easy", 21);
String EasyValue = easySP.getString("EasyMap", "");
SharedPreferences easyTwoSP = getActivity().getSharedPreferences("easyTwo", 22);
String EasyTwoValue = easyTwoSP.getString("EasyTwoMap", "");
SharedPreferences mediumSP = getActivity().getSharedPreferences("medium", 23);
String mediumValue = mediumSP.getString("MediumMap", "");
//Toast.makeText(getActivity(),/*"beginner " + prefs2 + " and easy " + prefs3 + " and easy2 " + prefs4 +*/ " medium " + mediumValue,Toast.LENGTH_LONG).show();
if (BeginnerValue.equals(FirstWanted)) {
setUserNotification(BeginnerValue, "Beginner");
} else if(EasyValue.equals(FirstWanted)) {
setUserNotification(EasyValue, "Easy");
} else if(EasyTwoValue.equals(FirstWanted)) {
setUserNotification(EasyTwoValue, "Easy Two");
} else if(mediumValue.equals(FirstWanted)) {
setUserNotification(mediumValue, "Medium");
} else {
System.out.print("They Don't Match!");
LowTV3.setText("They don't match!");
}
}
};
counter.start();
}
有些东西现在只是将测试内容打印到屏幕上,以确保 SharedPreferences
正常工作,感谢您的帮助。
错误日志
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.preference.PreferenceManager.getDefaultSharedPreferencesName(PreferenceManager.java:376)
at android.preference.PreferenceManager.getDefaultSharedPreferences(PreferenceManager.java:371)
at com.horizonservers.horizon.MapFragment$Medium.onFinish(MapFragment.java:658)
at android.os.CountDownTimer.handleMessage(CountDownTimer.java:127)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
好像删除了片段后的getActivity()
returnnull
因此您应该先入库 getActivity()
或 getActivity().getApplicationContext()
的价值。 (在 Runnable 实例和 Medium 实例中)
然后使用该值代替 getActivity()
。
那是因为SharedPreferences context
在切换fragment的时候被销毁了,所以它现在指向一个之前被销毁的空对象
使用 WeakReference 或使用 Singleton 作为首选项实用程序。
对于单例首选项实用程序,您可以查看Prefs.java from Pixplicity EasyPreferences。