14

in my application, I have a class for UI stuff, the name of which is "SettingActivity".

Then for doing some jobs in background, I bind this UI class(SettingActivity) to a Service. There are two predefined methods in that Service(defined in .aidl file), one is startTask(), the other one is stopTask().

Within startTask(), I made a call to an AsyncTask. But when I checked the name of the Looper of this AsyncTask. It is "main". In my opinion, an AsyncTask should start an another Thread other than the main Thread.

So does somebody know why this happens?

The codes are as follows:

@Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.d(TAG, "onPreExecute "+Looper.myLooper().getThread().getName());
    }

Then I will get main as the output.

Tash Pemhiwa
  • 7,590
  • 4
  • 45
  • 49
Mathieu
  • 1,491
  • 5
  • 17
  • 37

2 Answers2

27

An AsyncTask has several parts that you can override: a doInBackground method that does, in fact, run on a separate thread, and three methods—onPreExecute, onProgressUpdate, and onPostExecute—that run on the UI thread. (The default implementation of these methods do nothing and onProgressUpdate only runs if you call publishProgress, usually from within doInBackground.) The purpose of onPostExecute is to publish results (such as updating the view hierarchy, or setting text in a text view) that must be done on the UI thread. It also can post progress updates. In order for this to all work properly, the AsyncTask must be created, and the execute method called, on the UI thread.

You must not call UI actions from within doInBackground -- doing so will crash your application.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • For example if I want to make Toast on a separate thread, what should I do? – Behzad Feb 03 '13 at 22:29
  • 1
    @Behzad - If you have a reference to the activity, you can use `runOnUiThread` as described in [this answer](http://stackoverflow.com/a/3134720/535871). – Ted Hopp Feb 03 '13 at 23:15
  • @TedHopp - +1. It doesn't really separate the thread! I mean if I run a separated thread and inside it run a function that updates UI(with the runOnUitThread), it goes to the UI thread pool and run in a queue. Am I right? I want to make a toast and do something other(both update UI), simultaneously. Is that possible? – Behzad Feb 05 '13 at 21:03
  • @Behzad - If you are running a worker thread and pass a `Runnable` to `runOnUiThread`, then the `Runnable` will be queued to run on the UI thread at some future time (usually very soon) and the call to `runOnUiThread` will return immediately. You can then go on and do other things in the worker thread (including other calls to `runOnUiThread`) whether or not the UI thread has executed any of the `Runnables` you have passed as arguments. – Ted Hopp Feb 05 '13 at 21:11
  • I'm having similar problem. I am starting a service from `Application` class, I have `AsyncTask` in my service and I am downloading some items in `doInBackground()` method. Sometimes `doInBackground()` is in AsyncTask Thread, sometimes it is in Main thread. Any idea? – Gokhan Arik Feb 17 '15 at 19:50
  • @GokhanArik - `doInBackground()` should _never_ run on the UI thread if you are using `AsyncTask` properly. You should be starting the `AsyncTask` by calling `execute()` with the appropriate arguments. You should never call `doInBackground()` from your own code. – Ted Hopp Feb 17 '15 at 19:59
  • I am not calling it, I am calling `execute()` method of course. – Gokhan Arik Feb 17 '15 at 20:01
  • @GokhanArik - Without seeing your code, it's hard to know what's going on. How are you establishing that `doInBackground()` is running on the UI thread? – Ted Hopp Feb 17 '15 at 20:02
  • I am looking at Debug window of my IDE. It showes frames. Also, when I call getLoop method of Looper it shows that it is running on UI Thread. I will try to create a question and let you know – Gokhan Arik Feb 17 '15 at 20:05
10

In fact, I have checked the doc of android, onPreExecute(), onProgressUpdate(Progress...) and onPostExecute(Result) are all "invoked on the UI thread".

Only the doInBackground(Params...) method is "invoked on the background thread".

Mathieu
  • 1,491
  • 5
  • 17
  • 37