4

In Android, when I create a runnable inside a service and run it, while I realize it runs in its own thread, is this thread somehow part of the UI thread? In other words, if the runnable carried out a long process, would it affect the UI?

EDIT:

private class SomeRunnable implements Runnable
{
  @Override
  public void run()
  {
    try
    {

    }
  }
}

SomeRunnable runnable = new SomeRunnable();
(new Handler()).postDelayed(runnable, 1000);
Johann
  • 27,536
  • 39
  • 165
  • 279
  • depends how you run it. – njzk2 Feb 11 '13 at 08:51
  • 1
    Your assumption "...while I realize it runs in its own thread..." is not true. A `Runnable` can run anywhere, it depends on where you run it. For example, if you simply create a `Handler` in your `Service` and then post your `Runnable` using the `Handler`, it will run on the main (UI) thread. – David Wasser Feb 11 '13 at 09:30
  • Thanks for your edit. Using this code your `Runnable` is running on the main (UI) thread. If this `Runnable` takes a long time, you run the risk of having your app force-closed with an ANR (Application Not Responsing) error. – David Wasser Feb 11 '13 at 09:31
  • Would I be better off to run it in an AsyncTask or will I still end up with the same problem? – Johann Feb 11 '13 at 09:33
  • 1
    If all you want to do is run the `Runnable` in a separate Thread, you don't need `AsyncTask`. Just do: `new Thread(new SomeRunnable()).start();` – David Wasser Feb 11 '13 at 09:45

4 Answers4

11

Docs:

A services runs in the same process as the application in which it is declared and in the main thread of that application,

Different thread:

Thread t = new Thread(new MyRunnable());
t.start();

UI/Service Thread:

Handler h = new Handler();
h.post(new MyRunnable());
John61590
  • 1,106
  • 1
  • 13
  • 29
S.D.
  • 29,290
  • 3
  • 79
  • 130
  • But that refers to a service. My question is about launching a runnable from a service. – Johann Feb 11 '13 at 09:18
  • 2
    @AndroidDev The first piece of code launches a `Runnable` on a separate thread, **completely unrelated to UI thread**. The second piece of code runs the `Runnable` on **same thread** on which service is running, and it **will effect UI thread**. – S.D. Feb 11 '13 at 09:22
  • I am launching it with a Handler, so according to you, it must be running on the UI thread. – Johann Feb 11 '13 at 09:41
  • 2
    @AndroidDev In case of handler, it will run on thread which executed `new Handler()` like you created handler in `onBind()` of service, that handler points to service thread now. – S.D. Feb 11 '13 at 09:49
2

No it is not part of UI thread, I assume by Runnable you mean a new thread that you execute by calling start().

Regardless if you start a new Thread in a service or activity it will not be part of the UI thread (unless you call something like join())

Edit

Since you are running a Runnable object with Handler, so it depends on where you initialize your handler. Service runs in the main thread, so initializing the handler in a service or activity will make the code be posted to the UI thread

Note, you need a single Handler object per your thread; so avoid creating a new one with every time e.g. (new Handler()).postDelayed(runnable, 1000); should be avoided and instead handler.postDelayed(runnable, 1000); where handler is an instance variable initialized in your service/activity class

Jadeye
  • 3,551
  • 4
  • 47
  • 63
iTech
  • 18,192
  • 4
  • 57
  • 80
  • User117 seems to indicate otherwise. Are you sure? – Johann Feb 11 '13 at 09:19
  • Your question needs more clarification, what exactly you mean by `Runnable`. I mentioned it clearly if you start a new `Thread` by calling `start()`, it will be different from the `UI Thread` – iTech Feb 11 '13 at 09:22
  • See the code I added above in my original post. There is no start. – Johann Feb 11 '13 at 09:31
  • I have never heard of running a Runnable with start. I am only familiar with runOnUiThread and using a Handler. I am familiar with starting Threads with start() however. – Johann Feb 11 '13 at 09:39
  • I don't use (new Handler()). I only posted that to show I use a Handler. I do in fact only create the handler once and it's a private member. – Johann Feb 11 '13 at 09:43
0

By default services runs in UI thread. But it depends on service type and service properties and the way you post runnable. I think that you use default scheme and your runnable will be executed on UI thread and block it.

If you show code how you post runnable and create service I can give you exact answer.

You can check thread type from your runnable using following code:

if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
    // On UI thread.
} else {
    // Not on UI thread.
}

It is still not clear. If you execute "new Handler()" on UI thread than runnable will be executed on UI thread. If you execute "new Handler()" on another thread with looper than runnable will be executed on that thread. I think with probability 99% your runnable will be executed on UI thread. Why don't you place my code in runnable and check where it is executed?

Leonidos
  • 10,482
  • 2
  • 28
  • 37
  • I see conflicting responses posted here. Some seem to say yes and others say no. – Johann Feb 11 '13 at 09:20
  • @AndroidDev Yes, because there are different ways to "create a `Runnable`". If you will update your post with the code you use to "create a `Runnable`" then we can probably give you a better answer. – David Wasser Feb 11 '13 at 09:26
  • See my comment to your question. That `Runnable` runs on the main (UI) thread. – David Wasser Feb 11 '13 at 09:32
0

The runnable you submit to your handler will be always executed on the UI thread, since service are not spawn on a different process or threda, but thy are part of hte UI thread

Blackbelt
  • 156,034
  • 29
  • 297
  • 305