可以NoticationManager.notify()从一个工人线程调用? [英] Can NoticationManager.notify() be called from a worker thread?

查看:248
本文介绍了可以NoticationManager.notify()从一个工人线程调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是更多关于什么是比什么是可能的一个很好的做法:

My question is more about what is a good practice than what is possible:

  • 这是个好东西叫 NoticationManager.notify()从工作线程?
  • 系统是否在UI线程中执行它无论如何还是不?
  • Is it a good thing to call NoticationManager.notify() from a worker thread?
  • Does the system execute it in the UI thread anyway or not?

我总是尽量记住有关UI应该在UI线程,其余的工作线程执行的东西,所建议的对的Processes和线程

I always try to keep in mind that stuff concerning the UI should be executed in the UI thread and the rest in worker threads, as suggested by the Android doc about Processes And Threads:

此外,在Andoid的UI工具包是不是线程安全的。所以,你必须   没有从操纵一个工人的UI线程,你必须做的一切   中使从UI线程的用户界面。因此,存在   只是两个规则Android的单线程模型:

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:

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

不过,我是由Android的文档本身(给出关于展示一个例子惊讶在通知正在进行中),其中一个正在进行的通知进度直接从工作线程更新:

HOWEVER, I was surprised by an example given by the Android doc itself (about showing progress in Notifications), where an ongoing notification progress was updated directly from a worker thread:

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();

这就是为什么我想知道如果它实际上是要在主线程上运行它,或者如果系统需要照顾它。

That's why I'm wondering if it is actually necessary to run it on the main thread, or if the system takes care of it.

感谢您的帮助!

推荐答案

这是可以接受的更新通知从工作线程,因为通知不生活在你的应用程序的进程,因此你不能直接更新它的用户界面。该通知保持在一个系统的过程,而通知的用户界面是通过 RemoteViews doc ),它允许由一个过程不是您自己保持一个视图层次的操作。如果你看一下源代码 Notification.Builder <一个href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/app/Notification.java#L1420">here你可以看到,它是最终建立一个 RemoteViews

It is acceptable to update a Notification from a worker thread because the Notification does not live in your application's process and hence you are not updating its UI directly. The Notification is maintained in a system process, and the Notification's UI is updated through RemoteViews (doc), which allows the manipulation of a view hierarchy that is maintained by a process other than your own. If you look at the source for Notification.Builder here you can see that it is ultimately building a RemoteViews.

如果你看看源代码 RemoteViews <一个href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/RemoteViews.java">here你会看到,当你操纵视图它实际上只是创建一个动作(<一href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/RemoteViews.java#L193">source)对象并将其添加到队列中进行处理。一个动作 Parcelable 的最终通过工控机发送流程拥有该通知的观点,在那里可以解压的价值和更新指示......在它自己的UI线程的观点。

And if you look at the source for RemoteViews here you'll see that when you manipulate a view it is really just creating an Action (source) object and adding it to a queue to be processed. An Action is a Parcelable that is ultimately sent via IPC to the process that owns the Notification's view, where it can unpack the values and update the view as indicated... on it's own UI thread.

我希望澄清为什么它是确定在您的应用程序更新通知从工作线程。

I hope that clarifies why it is OK to update a Notification from a worker thread in your application.

这篇关于可以NoticationManager.notify()从一个工人线程调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆