5

I am trying to update my UI in FirstActivity when I receive a notification but is confused by runOnUiThread , Runnable and Handler. Here is what I have: I am running FirstActivity and NotificationService. When NotificationService reeives a notification, it will update FirstActivity UI.

I also have another service AlarmService running. First Activity

@Override
public void onResume() {
      super.onResume();
      //some other code for alarm service
}

NotificationService

    //on receiving notification
    private void showNotification(String text) {

   //Get activity
   Class<?> activityClass = null;
     try {
         activityClass = Class.forName("com.pakage.FirstActivity");
         contextActivity = (Activity) activityClass.newInstance();

         //Update UI on FirstActivity not working
         contextActivity.runOnUiThread(new Runnable() {
             public void run()
             { 
               Looper.prepare();
               TextView tv = (TextView ) contextActivity.findViewById(R.id.notifyTest);
               Looper.loop();

             }
             });

     } catch (Exception e) {
         e.printStackTrace();
     }

            //Shows the notification
            Notification n = new Notification();    
            //... etc   
}

I keep getting looper.prepare error. Do I need to put extra codes in my FirstActivity?

newbie
  • 958
  • 4
  • 13
  • 25
  • can you show us the messages in your log from logcat? Also, how did you declare Looper? – Alan Moore Oct 29 '11 at 22:31
  • 1
    I am getting `Can't create handler inside thread that has not called Looper.prepare()` error. Looper is declared in the `showNotification` method above – newbie Oct 29 '11 at 22:37
  • You're getting that error because you're running your code on the UI thread, which already owns a Looper lifecycle. To avoid that error, you could just remove `Looper.prepare()`, but it makes a non-sense since `Looper.loop()' would block the whole thread and the UI of your app would neither work nor respond anymore! – Davide Cannizzo May 04 '18 at 16:12

3 Answers3

6

My 1st instinct is that you should instead have the Activity bind to your service and handle the UI update on its side instead of the Service directly modifying the Activity.

See more info here:
http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

And an example here:
Example: Communication between Activity and Service using Messaging

Community
  • 1
  • 1
TJB
  • 13,367
  • 4
  • 34
  • 46
5

I've always just had the service fire off a Broadcast and then in my Activity I have a BroadcastReciever listening for the Broadcast. It's an approach that is much simpler than the one you outlined above.

Kurtis Nusbaum
  • 30,445
  • 13
  • 78
  • 102
0

I have no idea why you are putting a Looper in

contextActivity.runOnUiThread(new Runnable() {
    public void run()
    { 
        Looper.prepare();
        TextView tv = (TextView ) contextActivity.findViewById(R.id.notifyTest);
        Looper.loop();

    }
});

because the UI (main) thread already has a Looper/Handler etc..

Even if it did work Looper.loop() is going to block and since you are running it on the UI thread, it will block the UI thread which is not what you want.

What you really want to do is

contextActivity.runOnUiThread(new Runnable() {
    public void run()
    { 
        TextView tv = (TextView ) contextActivity.findViewById(R.id.notifyTest);
        tv.setText("do something that must be on UI thread") // or whatever
    }
});

You don't really need to do all this fancy stuff to get the Activity

activityClass = Class.forName("com.pakage.FirstActivity");
contextActivity = (Activity) activityClass.newInstance();

assuming the Service and Activity are both running in the same process you can just save a reference to the Activity but be careful to update the reference when the Activity gets destroyed.

Jasoneer
  • 2,078
  • 2
  • 15
  • 20
  • Both the service and activity are running in the same process. What do you mean by saving a reference to the activity? I tried using `FirstActivity.runOnUiThread`. – newbie Oct 30 '11 at 07:29