Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can NoticationManager.notify() be called from a worker thread?

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

  • 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?

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:

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

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.

Thanks for your help!

like image 505
Joffrey Avatar asked Mar 20 '13 17:03

Joffrey


People also ask

What is the use of Notificationmanager?

Notification Manager. Android allows to put notification into the titlebar of your application. The user can expand the notification bar and by selecting the notification the user can trigger another activity.

How do I get notification data on Android?

Open new activity on click of push notification. Display data coming from push notification of new activity. If the application is closed so after click on notification the app get started.


1 Answers

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.

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.

like image 170
Brett Duncavage Avatar answered Sep 25 '22 00:09

Brett Duncavage