如何停止处理程序线程中的通知

how to stop notification thats in handler thread

我有一个包含四个 RemoteView TextView 的自定义通知。当调用 onPause() 时,我想 post 通知,然后在屏幕打开时每秒更新一次。当调用 onResume() 时,我想取消通知。到目前为止,我已经设置好它,以便我有一个易失性布尔值,它在调用 onPause() 时设置为 true,在调用 onResume() 时设置为 false。我有一个启动 HandlerThread 然后检查 volatile 布尔值的方法。如果布尔值是 true,它应该更新通知,如果它是 false,它应该取消通知并关闭 HandlerThread。

就启动通知和每秒更新一次而言,一切似乎都运行良好。但是,当调用 onResume() 时,它不会停止通知。

我还没有编码内容的屏幕,因为我在继续之前试图弄清楚如何关闭通知和 HandlerThread。

到目前为止,这是我的代码:

void setUpTimerNotif() {

    handlerThread = new HandlerThread("TimerNotificationHandler", Process.THREAD_PRIORITY_BACKGROUND);

    handlerThread.start();

    timerNotificationHandler = new Handler(handlerThread.getLooper());

    timerNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    Intent timerNotifIntent = new Intent(MainActivity.this, MainActivity.class);
    timerNotifIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

    final PendingIntent pendingTimerNotifIntent = PendingIntent.getActivity(MainActivity.this,
            1234, timerNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    final RemoteViews remoteTimerViews = new RemoteViews(getPackageName(), R.layout.timer_notification);

    final NotificationCompat.Builder timerNotificationBuilder = new NotificationCompat.Builder(MainActivity.this);

    if (timerNotificationRunning) {
        timerNotificationHandler.postDelayed(
                new Runnable() {
                    @Override
                    public void run() {

                        long timerNotifTimeOne = wakeUpTime - System.currentTimeMillis();
                        long timerNotifTimeTwo = wakeUpTimeTwo - System.currentTimeMillis();
                        long timerNotifTimeThree = wakeUpTimeThree - System.currentTimeMillis();
                        long timerNotifTimeFour = wakeUpTimeFour - System.currentTimeMillis();

                        String timeOne = timerFormat(timerNotifTimeOne);
                        String timeTwo = timerFormat(timerNotifTimeTwo);
                        String timeThree = timerFormat(timerNotifTimeThree);
                        String timeFour = timerFormat(timerNotifTimeFour);

                        String hmsOne = ("Timer 1: " + timeOne);
                        String hmsTwo = ("Timer 2: " + timeTwo);
                        String hmsThree = ("Timer 3: " + timeThree);
                        String hmsfour = ("Timer 4: " + timeFour);

                        remoteTimerViews.setTextViewText(R.id.timer_one_notification_view, hmsOne);

                        remoteTimerViews.setTextViewText(R.id.timer_two_notification_view, hmsTwo);

                        remoteTimerViews.setTextViewText(R.id.timer_three_notification_view, hmsThree);

                        remoteTimerViews.setTextViewText(R.id.timer_four_notification_view, hmsfour);

                        timerNotificationBuilder.setPriority(Notification.PRIORITY_HIGH)
                                .setAutoCancel(false)
                                .setOngoing(true)
                                .setOnlyAlertOnce(true)
                                .setSmallIcon(R.mipmap.ic_launcher)
                                .setContentIntent(pendingTimerNotifIntent)
                                .setCustomBigContentView(remoteTimerViews)
                                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);

                        timerNotificationManager.notify(1234, timerNotificationBuilder.build());

                        timerNotificationHandler.post(this);

                    }
                }, 1000
        );
    } else {
        timerNotificationManager.cancelAll();

        if (timerNotificationHandler != null) {
            timerNotificationHandler.removeCallbacksAndMessages(null);
        }

        timerNotificationHandler.getLooper().quit();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            handlerThread.quitSafely();
        } else {
            handlerThread.quit();

            /*try {
                handlerThread.join();
                handlerThread = null;
                timerNotificationHandler = null;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
        }

        Log.v(TAG, "Timer Notification Cancelled");
    }

}

最"android" 的方法是使用后台服务。

https://developer.android.com/guide/components/services.html

当您的应用进入后台 (onPause) 时,您要么启动服务,要么 post 一条消息说明这一点,而 onResume 则相反。

(您当前解决方案的问题是您的 Activity 可能随时被杀死 onStop/onDestroy 但您仍然需要进行中的通知更新)


请注意,您使用 MainThreads Looper 创建了 HandlerThread:

 timerNotificationHandler = new Handler(handlerThread.getLooper());

但是在你的 else 语句中你告诉这个 looper 退出:

 timerNotificationHandler.getLooper().quit();

我不太确定这会导致什么行为!但我觉得这是错误的 - 你不想阻止主线程循环器循环,这意味着你的 activity 不会按预期工作(并且可能是你的问题)。

https://developer.android.com/reference/android/os/Looper.html#quit()


在您的 else 语句中,您可能还想取消通知:

https://developer.android.com/reference/android/app/NotificationManager.html#cancel(int)

timerNotificationManager.cancel(1234);