我使用此 BroadcastReceiver 每周使用新数据更新我的应用程序的 JSON 数据,它在大多数情况下都能正常运行,但是对于某些用户来说,它很容易崩溃的 的NullPointerException
我如何设置闹钟:
public static void setAlarm(int i, Context context){
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, UpdateReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
if (i == 0) {
alarmTime = 0;
//Toast.makeText(context, "Setting alarm for first time", Toast.LENGTH_LONG).show();
} else if (i == -2) {
alarmTime = new GregorianCalendar().getTimeInMillis()+24*60*60*1000; // a day
//Toast.makeText(context, "NO WIFI RESTARTING AFTER A DAY" + alarmTime, Toast.LENGTH_LONG).show();
}else {
alarmTime = UpdateReceiver.getAlermTimeInMillis();
//Toast.makeText(context, "Setting alarm for next tuesday", Toast.LENGTH_LONG).show();
}
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, alarmTime,
AlarmManager.INTERVAL_DAY, alarmIntent);
}
BrodcastReceiver:我的catch块中有代码,因为当设备关闭时,应用程序在尝试更新时崩溃,所以我抓住异常并重新调用代码,这是一个好习惯吗?
public class UpdateReceiver extends BroadcastReceiver {
private static long alarmTime = 0;
private static final String TAG = UpdateReceiver.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
alarmTime = NextTuesday.nextDayOfWeek(Calendar.TUESDAY).getTimeInMillis();
File file = context.getFileStreamPath("video_games.json");
if (!file.exists()) {
//Toast.makeText(context, "FIRST BOOT", Toast.LENGTH_LONG).show();
if (isConnectedToInternet(context)) {
UpcomingFragment.setAlarm(-1, context);
UpcomingFragment.getInstance().update();
} else {
//a day from now
UpcomingFragment.setAlarm(-2, context);
}
} else {
//Toast.makeText(context, "FILE EXISTS", Toast.LENGTH_LONG).show();
if (isConnectedToInternet(context)) {
try {
Intent intentUpcoming = new Intent(context, MainActivity.class);
intentUpcoming.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentUpcoming);
UpcomingFragment.setAlarm(-1, context);
UpcomingFragment fragment = (UpcomingFragment) MainActivity.allFragments.get(0);
fragment.update();
} catch (Exception e){
//Toast.makeText(context, e.getMessage() + "Crashed setAlarm(0) to update now and it won't crash this time", Toast.LENGTH_LONG).show();
UpcomingFragment.setAlarm(0, context);
}
} else {
//a day from now
UpcomingFragment.setAlarm(-2, context);
}
}
}
public static long getAlermTimeInMillis(){
return alarmTime;
}
private boolean isConnectedToInternet(Context context) {
ConnectivityManager connectivityManager
= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork= connectivityManager.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
}
Logcat:
java.lang.RuntimeException: Unable to start receiver domain.com.app.UpdateReceiver: java.lang.NullPointerException:
Attempt to invoke virtual method 'void domain.com.app.UpcomingFragment.update()' on a null object reference
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3029)
at android.app.ActivityThread.access$1800(ActivityThread.java:179)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1539)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5972)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void domain.com.app.UpcomingFragment.update()' on a null object reference
at domain.com.app.UpdateReceiver.onReceive(UpdateReceiver.java:39)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3022)
如果logcat是任何指示,我猜它是因为更新不是静态的,不幸的是我不能使它静态。
答案 0 :(得分:1)
似乎在调用更新时,您的Fragment不会保留任何实例。我建议更新您的数据库或SharedPreferrences。至少,他们没有生命周期,很难预测和管理。
所以onReceive()
SharedPreferences.Editor editor = getSharedPreferences().edit();
editor.putString("TOKEN", myJSON);
editor.apply();
Token是您要保存的JSON。在片段的某些方面,例如,onResume()调用
SharedPreferences sharedPreferences = getSharedPreferences();
String token = sharedPreferences.getString("TOKEN", null);