I have two AsyncTask Activities, whose sole responsibilties are to execute an AsyncTask on the UI Thread. One of them works great, displays the progressBar, and updates the ProgressBar message. This is for my SearchActivity, which is actually a search activity with the Google Search metadata for declaring a search activity. I created a clone of the AsyncTask, and only changed doInBackground code, and also clone the SearchActivity and called it browseActivity.
I start BrowseActivity for result in a class that extends listView when an item is clicked. What I intended to happen was for the onPreExecute code of the AsyncTask to display a progressBar as the SearchActivity does, between the ListView activity, and the ResultActivity that the ListView will start onActivityResult. The onPreExcute code is being called but the ProgressBar is never displayed. (I thought I ran it on the UI thread correctly?)
Here is BrowseActivity:
AsyncTask<String, String, ArrayList<SearchResult>> browseTask;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String genreExtra = getIntent().getStringExtra(Genre.BUNDLE_TAG);
if(genreExtra!=null){
genre = Genre.getgenreFromExtra(genreExtra);
}
String categoryExtra = getIntent().getStringExtra(Category.BUNDLE_TAG);
if(categoryExtra!=null){
this.category = Category.getCategoryFromExtra(categoryExtra);
}
final Connector connector = GlobalVars.getCurrentConnector();
Thread browseThread = new Thread(){
@Override
public void run() {
try {
browseTask = connector.browse(BrowseActivity.this, category, genre, 1);
browseTask.execute("");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
runOnUiThread(browseThread);
ArrayList<SearchResult> result = null;
try {
result = browseTask.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bundle queryBundle = new Bundle();
queryBundle.putSerializable(SERIALIZABLE_KEY, result);
Intent i = new Intent();
i.putExtra(BUNDLE_KEY, queryBundle); //Put in our browse results
i.putExtra(Category.BUNDLE_TAG, category.putExtra()); //put our category in return intent
i.putExtra(Genre.BUNDLE_TAG, genre.putExtra()); //put our genre in return intent
setResult(RESULT_OK, i);
finish();
}
Here is the CategoryActivity (extends ListActivity) activity where browseActivity is started:
@Override
protected void onListItemClick(ListView l, View v, final int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(CategorySelectionView.this, BrowseActivity.class);
final Category[] categories = Category.values();
i.putExtra(Category.BUNDLE_TAG, categories[position].putExtra());
i.putExtra(Genre.BUNDLE_TAG, genre.putExtra());
CategorySelectionView.this.startActivityForResult(i, BrowseActivity.RESULT_REQUEST_CODE);
}
// Listen for results.
protected void onActivityResult(int requestCode, int resultCode, Intent data){
// See which child activity is calling us back.
switch (requestCode) {
case BrowseActivity.RESULT_REQUEST_CODE:
// This is the standard resultCode that is sent back if the
// activity crashed or didn't doesn't supply an explicit result.
if (resultCode == RESULT_CANCELED){
}
else {
ArrayList<SearchResult> recentQueryResults = (ArrayList<SearchResult>)data.getBundleExtra(
BrowseActivity.BUNDLE_KEY).getSerializable(BrowseActivity.SERIALIZABLE_KEY);
GlobalVars.setRecentQueryResults(recentQueryResults);
Category category = Category.getCategoryFromExtra(data.getStringExtra(Category.BUNDLE_TAG));
Intent i = new Intent(CategorySelectionView.this, RomListView.class);
i.putExtra(Category.BUNDLE_TAG, category.putExtra());
i.putExtra(Genre.BUNDLE_TAG, genre.putExtra());
startActivity(i);
}
default:
break;
}
}
Firstly, you can’t run an AsyncTask on the main/UI Thread, that’s the whole point. When you call
browseTask.execute()its going to call its methods on the appropriate Thread (main vs background), regardless of callingrunOnUiThread(). By callingrunOnUiThread()all you are doing is wrapping the code that starts it in anotherRunnable. I think is not what you want since after callingrunOnUiThread()you try to get the result of the task, which hasn’t run yet. The code inonCreate()runs on the UI thread, so this has to finish before something else can run, namely theonPreExecute()of theAsyncTask.What you should be doing is to create the
AsyncTaskand put everything you currently have afterrunOnUiThread()inonPostExecute().