共享首选项在切换片段时导致空指针异常

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