屏幕轮换和通知后,Android应用程序强制关闭(片段)

时间:2015-07-27 06:44:57

标签: java android android-fragments android-intent notifications

所以我的应用程序有一个带有内置runnable计时器的片段,一旦时间到达0,就会在设备上创建一个通知。但是,在屏幕方向后,app force关闭,logcat生成 “尝试在空对象引用上调用虚方法'java.lang.String android.content.Context.getPackageName()'”

这是完整的logcat:

     java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
        at android.content.ComponentName.<init>(ComponentName.java:77)
        at android.content.Intent.<init>(Intent.java:4160)
        at com.example.android.courtcounter.tabs.TimerFragment.createNotification(TimerFragment.java:178)
        at com.example.android.courtcounter.tabs.TimerFragment$1.run(TimerFragment.java:52)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        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:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

错误发生在这里:

           //Creates the notification from the Main Activity class
public void createNotification() {
    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(getActivity())
                    .setSmallIcon(R.drawable.ic_launcher)
                    .setContentTitle("Score Counter and Timer")
                    .setContentText("Time's up!");
    // Creates an explicit intent for an Activity in your app
    Intent resultIntent = new Intent(this.getActivity(), TimerFragment.class);

    // The stack builder object will contain an artificial back stack for the
    // started Activity.
    // This ensures that navigating backward from the Activity leads out of
    // your application to the Home screen.
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(getActivity());
    // Adds the Intent that starts the Activity to the top of the stack
    stackBuilder.addNextIntent(resultIntent);
    PendingIntent resultPendingIntent =
            stackBuilder.getPendingIntent(
                    0,
                    PendingIntent.FLAG_UPDATE_CURRENT
            );
    int mID = 001;
    mBuilder.setContentIntent(resultPendingIntent);
    NotificationManager mNotificationManager =
            (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
    // mId allows you to update the notification later on.
    mNotificationManager.notify(mID,mBuilder.build());
}

显然在方向更改后通知将导致它“尝试在空对象引用上调用方法”问题。

这是我调用我创建的通知方法的地方:

    private Runnable timerRunnable = new Runnable() {
    @Override
    public void run() {
        if (timeLeft > 501) {
            timerTextViewSetUp();
            timerHandler.postDelayed(this, 500);
            timeLeft = timeLeft - 500;
            //Log.v(TimerFragment.class.getSimpleName(), "The timer has been set");
        } else if (timeLeft<501 && timeLeft>0) {
            timeLeft = 0;
            timerTextView.setText("0:00");
            timerHandler.removeCallbacks(this);
            vibrate();
            createNotification();
            setPauseButtonToStartButton();
        }

我不知道这是否与它有关,但这是我的onSavedInstanceState代码:

    @Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    //Save state information
    savedInstanceState.putLong(TIME_LEFT_KEY, timeLeft);

}

,这是在onCreateView:

    if (savedInstanceState != null) {
        timeLeft = savedInstanceState.getLong(TIME_LEFT_KEY);
        timerHandler.postDelayed(timerRunnable, 0);
        //Log.v(TimerFragment.class.getSimpleName(), Long.toString(timeLeft));
    }

非常感谢帮助,谢谢!

1 个答案:

答案 0 :(得分:0)

方向更改会导致重新创建活动。使用removeCallbacks(Runnable r)删除runnable,以便在旧活动被销毁后不会被调用。创建新活动后,您可以重新创建runnable和handler。