首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以从工作线程调用NoticationManager.notify()吗?

可以从工作线程调用NoticationManager.notify()吗?
EN

Stack Overflow用户
提问于 2013-03-20 17:13:50
回答 1查看 10.7K关注 0票数 52

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

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

我总是试图记住,有关UI的内容应该在UI线程中执行,其余的应该在工作线程中执行,正如Android关于Processes And Threads的建议。

此外,Andoid工具包并不是线程安全的。因此,您不能从工作线程操作UI -必须从UI线程对用户界面进行所有操作。因此,Android的单线程模型有两个简单的规则:

  • 不要阻塞UI线程
  • 不要从UI线程外部访问Android工具包。

然而,我对Android (about showing progress in Notifications)给出的一个例子感到惊讶,在这个例子中,一个正在进行的通知过程直接从一个工作线程中更新:

代码语言:javascript
复制
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();

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

谢谢你的帮忙!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-04 06:09:29

从工作线程更新Notification是可以接受的,因为Notification不存在于应用程序的进程中,因此不能直接更新其UI。通知是在系统进程中维护的,Notification的UI是通过RemoteViews (doc)更新的,它允许操作由非您的进程维护的视图层次结构。如果您查看Notification.Builder here的源代码,就会发现它最终正在构建一个RemoteViews

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

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

票数 95
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15530293

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档