Benjamin Owen
Benjamin Owen

Reputation: 617

Why does runOnUiThread() not work inside Service?

I am creating an application that needs to update values every minute even if the app isn't running.

Of course, I have set up a simple Service to do that. I have debug messages set up to tell me when the Service starts, when it updates (every minute), and when it closes. I also have a message telling me when the values update inside a runOnUiThread() method. All of my messages activate except for the one in the runOnUiThread(). Is there something I'm doing wrong (of course there is)? What do I need to change?

Code:

@Override
public void handleMessage(Message message) {

    try {

        if (!serviceStarted) {

            serviceStarted = true;
            serviceTest = true;

            while (serviceStarted) {

                new MainActivity().runOnUiThread(new Runnable() {

                    public void run() {

                            OverviewFragment.refresh(getApplicationContext());
                            System.out.println("yay");

                         }
                });

                Thread.sleep(((1 /* minutes */) * 60 * 1000));
                System.out.println("Updated values through service.");

            }
        }


    } catch (InterruptedException e) {

        Thread.currentThread().interrupt();
        e.printStackTrace();

    }

    stopSelf(message.arg1);
}

Upvotes: 12

Views: 14737

Answers (4)

William
William

Reputation: 141

Try using a handler or LocalBroadcastManager to send a message to the activity.

Upvotes: 2

user4774371
user4774371

Reputation:

So there's no need to do that, unless you're creating a Thread inside of it

Gabe Sechan's answer is correct.

But if you are using a separate thread then instead of following code:

new MainActivity().runOnUiThread(new Runnable() {
       public void run() {
            OverviewFragment.refresh(getApplicationContext());
                 System.out.println("yay");

       }
});

Try, this code:

new Handler(Looper.getMainLooper()).post(new Runnable() {
       public void run() {
            OverviewFragment.refresh(getApplicationContext());
                 System.out.println("yay");
       }
});

As per Android docs

Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise).

Upvotes: 21

drhr
drhr

Reputation: 2281

See this question: Accessing UI thread handler from a service

You can use Looper.getMainLooper() within a Handler to post a Runnable that executes whatever you're trying to execute.

A good alternative though, like jinghong mentioned, is to use broadcasts - in other words, use a different pattern.

Upvotes: 0

Gabe Sechan
Gabe Sechan

Reputation: 93726

You can't create an Activity by calling new. It doesn't initialize properly that way.

Also, Services by default run on the UI thread. So there's no need to do that, unless you're creating a Thread inside of it. If you are- runOnUIThread is just syntactic sugar for posting a runnable to a handler. So you can just do that instead.

Upvotes: 3

Related Questions