【问题标题】:Android app crash.. intent flag?Android应用程序崩溃..意图标志?
【发布时间】:2016-10-25 00:15:28
【问题描述】:

我的应用最近发生了一些崩溃,我想知道这是否可能是由于意图上的标志造成的。

当崩溃发生时,我相信应用程序会在休息计时器期间关闭。打开一个片段,然后用户可以单击开始,这将启动一个 90 秒的倒计时。计时器结束时,用户会收到通知,单击该通知时应将用户带回打开的片段。该错误不会经常发生,我无法每次都重新创建它。

这是堆栈跟踪:

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:4913)
at com.bestworkouts.sheikoworkout.Workouts.Week1Mon.showNotification(Week1Mon.java:171)
at com.bestworkouts.sheikoworkout.Workouts.Week1Mon$1.onFinish(Week1Mon.java:147)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6938)
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:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

这是错误所在的通知(它说错误在 Intent intent = new Intent(getActivity(), MyWorkout.class):

public void showNotification() {
    NotificationCompat.Builder builder = new NotificationCompat.Builder(getContext());
    builder.setSmallIcon(R.drawable.sheikoicon);
    builder.setContentTitle("Sheiko Rest Timer");
    builder.setContentText("Rest timer is up, start your set!");
    builder.setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_VIBRATE);
    builder.setAutoCancel(true);
    Intent intent = new Intent(getActivity(), MyWorkout.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(getContext());
    stackBuilder.addParentStack(MyWorkout.class);
    stackBuilder.addNextIntent(intent);
    PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setContentIntent(pendingIntent);
    NotificationManager NM = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
    NM.notify(0, builder.build());
}

我在哪里启动倒数计时器并调用 showNotification:

private void start() {
    cancel();
    mCountDownTimer = new CountDownTimer(90000, 1000) {
        @Override
        public void onTick(long millisUntilFinished) {
            txtViewRest.setText(millisUntilFinished / 1000 + " Secs");
        }

        @Override
        public void onFinish() {
            txtViewRest.setText("Start!");
            showNotification();
        }
    }.start();
}

我想知道这是否与我的 FLAG_ACTIVITY_CLEAR_TOP 有关?

感谢您的帮助!

【问题讨论】:

  • 您的代码似乎在CountDownTimer 中运行,难道getActivity() 正在返回null,因为它是从另一个线程调用的?
  • 也许,我对 android 很陌生,但我添加了启动计时器并调用 showNotification 方法的代码(如果有帮助)
  • 就像@MohanadMohie 所说,您在CountDownTimer 的上下文中,因此在这种情况下getActivity() 将返回null。您应该将活动上下文传递给 showNotification() 方法
  • 我刚刚确认了。我可以通过打开包含FragmentActivity,然后在CountDownTimer 完成之前关闭它来重现错误。这样,getActivity() 总是返回 null

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


【解决方案1】:

由于您的代码在另一个线程上运行,如果在 CountDownTimer 完成时 Fragment 已因任何原因关闭,getActivity()getContext() 都将返回 null

您应该将上下文保存在FragmentonCreate 中:

private Context context;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    context= getContext();

    // Your code here

}

然后在 showNotification() 方法中使用它:

public void showNotification() {
    NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
    builder.setSmallIcon(R.drawable.sheikoicon);
    builder.setContentTitle("Sheiko Rest Timer");
    builder.setContentText("Rest timer is up, start your set!");
    builder.setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_VIBRATE);
    builder.setAutoCancel(true);
    Intent intent = new Intent(context, MyWorkout.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addParentStack(MyWorkout.class);
    stackBuilder.addNextIntent(intent);
    PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setContentIntent(pendingIntent);
    NotificationManager NM = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    NM.notify(0, builder.build());
}

【讨论】:

  • 感谢您的帮助。不幸的是,仍然发生崩溃。感谢您,我现在可以通过按后退按钮来重现它,这是巨大的帮助。我做了你所显示的无济于事。页面的主类检查传递给它的意图,根据意图,它创建一个具有不同页面的 viewpager。每个页面都有一个单独的类,用数据填充 viewpager。如果我点击后退按钮,如果我导航到应用程序中的其他地方,或者关闭它,它似乎只会崩溃,它可以正常工作
  • 我相信应用程序现在崩溃了,因为您试图在 Fragment 被破坏时调用 TextView.setText(),这是与前一个不同的错误。
  • 堆栈跟踪仍然显示 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on an null object reference
  • 我在计时器结束前关闭应用程序时尝试了几次代码,每次通知都显示没有错误。尝试确认context 在首次初始化时不为空,并且您没有忘记从代码中删除getContext()getActivity()。我建议用你的新代码更新问题。
  • 好的,谢谢,我明天下班后试试。再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2019-05-03
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多