1

I read in AsyncTask document , Threading rules section that execute(Params...) must be invoked on the UI thread. But when I check this demo , it works fine . Can anyone help me to figure out what I am missing here ?

public class MainActivity extends AppCompatActivity { public static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { new Thread(new Runnable() { @Override public void run() { new PublicTask().execute(); } }).start(); } }); } public class PublicTask extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); Log.i(TAG, "onPreExecute called"); } @Override protected Void doInBackground(Void... voids) { Log.i(TAG, "doInBackground called"); return null; } } } 

This is the Log I am getting. No crash. I wonder , why?

12-17 00:28:41.317 18152-18193/? I/MainActivity: onPreExecute called 12-17 00:28:41.340 18152-18194/? I/MainActivity: doInBackground called 
1
  • I would say is because you are not doing any changes in the UI. Try changing something of the UI and mostly sure will crash. I'm not testing it right now, but in top of my head I assume AsyncTask is taking form granted that the looper used when called is the main looper. Commented Dec 16, 2016 at 19:19

2 Answers 2

2

It's not crashing because you aren't trying to update the UI from onPreExecute(). Try changing something in the UI from onPreExecute() and your app should crash nicely.

Sign up to request clarification or add additional context in comments.

2 Comments

This is not correct. It will work fine even if you call AsyncTask from the Background thread,and onPostExecute will still run on the UI thread
@HasifSeyd - Are you sure about that? The docs clearly state that the AsyncTask instance must be created on the UI thread. The only thing that changed as of JellyBean is that the AsyncTask class itself is automatically loaded on the UI thread (also a requirement). I guess the only clear answer is to test it (which, admittedly, I haven't done recently). But if your answer is right, it's odd that the docs still list those requirements.
0

Before JellyBean version, Whenever you create an AsyncTask object, there is an Handler called InternalHandler that would get instantiated on the thread where the Asynctask object is created(This Handler is responsible to pass the result from the background thread to Main thread in AsyncTask) and as we know that Handler object can only be instantiated on the thread that has Looper, so it was necessary to instantiate the AsyncTask in Main thread.

From JellyBean version onward,you don't have to worry about it, because InternalHandler is automatically instantiated by passing the Main thread looper by the android system as shown in the source code

 public InternalHandler() { super(Looper.getMainLooper()); } 

So even if you create the AsyncTask object in the background thread , it will not give any exceptions, and onPostExecute and onPreExecute will run fine on the Main thread and can update the UI safefly

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.