android - 可以从工作线程调用 NotificationManager.notify() 吗?

标签 android multithreading notifications android-notifications

我的问题更多的是关于什么是好的做法,而不是什么是可能的:

  • 从工作线程调用 NoticationManager.notify() 是不是一件好事?
  • 系统是否在 UI 线程中执行它?

我始终牢记关于 UI 的内容应该在 UI 线程中执行,其余的在工作线程中执行,正如 Android 文档中关于 Processes And Threads 的建议。 :

Additionally, the Andoid UI toolkit is not thread-safe. So, you must not manipulate your UI from a worker thread—you must do all manipulation to your user interface from the UI thread. Thus, there are simply two rules to Android's single thread model:

  • Do not block the UI thread
  • Do not access the Android UI toolkit from outside the UI thread

但是,我对 Android 文档本身 (about showing progress in Notifications) 给出的示例感到惊讶,其中直接从工作线程更新正在进行的通知进度:

mNotifyManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Picture Download")
    .setContentText("Download in progress")
    .setSmallIcon(R.drawable.ic_notification);
// Start a lengthy operation in a background thread
new Thread(
    new Runnable() {
        @Override
        public void run() {
            int incr;
            // Do the "lengthy" operation 20 times
            for (incr = 0; incr <= 100; incr+=5) {
                    // Sets the progress indicator to a max value, the
                    // current completion percentage, and "determinate"
                    // state
                    mBuilder.setProgress(100, incr, false);
                    // Displays the progress bar for the first time.
                    mNotifyManager.notify(0, mBuilder.build());
                        // Sleeps the thread, simulating an operation
                        // that takes time
                        try {
                            // Sleep for 5 seconds
                            Thread.sleep(5*1000);
                        } catch (InterruptedException e) {
                            Log.d(TAG, "sleep failure");
                        }
            }
            // When the loop is finished, updates the notification
            mBuilder.setContentText("Download complete")
            // Removes the progress bar
                    .setProgress(0,0,false);
            mNotifyManager.notify(ID, mBuilder.build());
        }
    }
// Starts the thread by calling the run() method in its Runnable
).start();

这就是为什么我想知道是否真的有必要在主线程上运行它,或者系统是否会处理它。

感谢您的帮助!

最佳答案

从工作线程更新 Notification 是可以接受的,因为 Notification 并不存在于您的应用程序进程中,因此您不会直接更新其 UI。 Notification 在系统进程中维护,Notification 的 UI 通过 RemoteViews ( doc ) 进行更新,这允许操作维护的 View 层次结构通过您自己以外的过程。如果您查看 Notification.Builder here 的源代码你可以看到它最终是在构建一个RemoteViews

如果您查看 RemoteViews here 的源代码您会看到,当您操作 View 时,实际上只是创建了一个 Action ( source ) 对象并将其添加到要处理的队列中。 Action 是一个 Parcelable,它最终通过 IPC 发送到拥有 Notification View 的进程,在那里它可以解包值和按照指示更新 View ...在它自己的 UI 线程上。

我希望澄清为什么可以从应用程序中的工作线程更新 Notification

关于android - 可以从工作线程调用 NotificationManager.notify() 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15530293/

相关文章:

android - 是否可以添加一个外部维护的项目库而不进行复制?

android - Robolectric 测试 Activity 创建,包括 Intent 附加功能

c++ - 使用多线程用值填充数组

Python 共享库

c++ - 我在这里没有看到比赛条件?

android - 我可以将android中的默认推送通知图标从应用程序图标覆盖到自定义图标吗?

android Lollipop 通知背景颜色

android - 从 github 导入克隆到 Eclipse 并构建路径错误

android - 服务定时器通知

从后台恢复后Android应用程序崩溃