Reputation: 10203
I use AsyncTask to change text of TextView like this:
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
response += url;
}
return response;
}
@Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
Everything will fine if I call it in OnClick event:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textView = (TextView) findViewById(R.id.txt);
Button button = (Button)this.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new LongOperation().execute(new String[]{"Hello"});
}
});
}
But the problem when I called it in my thread, the program forced close
this.closeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Thread t= new Thread(){
@Override
public void run(){
try{
//Do something
//Then call AsyncTask
new LongOperation().execute(new String[]{"Hello"});
}catch(Exception e){}
}
};
t.start();
}
});
Where am I wrong? I dont' understand how difference call AsyncTask in thread or not.
Upvotes: 1
Views: 5014
Reputation: 16914
Adding to what the others have said: I think you can use AsyncTask to launch off a task in another thread, even if you start the AsyncTask from a different thread than the UI already.
But in that case, the only way you'll only be able to modify the UI indirectly, for example: pass the handler of the current Activity somehow to this AsyncTask instance, and send messages to it (handler messages get processed on the UI thread). Or use broadcast intents that the Activity catches and updates the UI accordingly, etc. These solutions seem to be overkills though.
Upvotes: 1
Reputation: 8639
I recommend you consult the AsyncTask documentation and Processes and Threads for a better understanding of how it works. Essentially, you should create your AsyncTask subclass on the main thread.
When you call AsyncTask.execute(), your provided, AsyncTask.onPreExecute is called on the main thread, so you can do UI setup.
Next AsyncTask.doInBackground method is called, and runs in its own thread.
Finally, when your AsyncTask.doInBackground method completes, a call is made to AsyncTask.onPostExecute on the main thread, and you can do any UI cleanup.
If you need to update the UI from within your AsyncTask.doInBackground method, call AsyncTask.publishProgress, which will invoke onProgressUpdate in the main thread.
Upvotes: 8
Reputation: 81349
When you call it from the UI thread, the associated Context
is the running Activity
. When you call it from a regular thread, there is no valid Context
associated with that thread. AsyncTask
executes in its own thread, you shouldn't be creating its own thread. If that is actual code, then you have missunderstood the point of AsyncTask
. Search for tutorials on how to use it.
Upvotes: 2