TuGordoBello
TuGordoBello

Reputation: 4509

Is it possible to run the "AsyncTask" method inside another method "AsyncTask"?

I have an activity that when started makes a call to a "json" for get data categories of songs, after that I make a call to the method "AsyncTask" for the list of songs that category from another "JSON "the problem is that when I start the activity, this is locked , after 2 seconds, the activity opens the layout and I can see the categories on the action bar and not because the songs are looking for in the background.

main activity (onCreate):

    java.io.InputStream source = null;
    source = retrieveStream(UrlApi.URL_BASE + UrlApi.URL_STORE + _bundle.getString("_id") + UrlApi.CATEGORY_SONG);
    Log.i("URL - KARAOKE", UrlApi.URL_BASE + UrlApi.URL_STORE + _bundle.getString("_id") + UrlApi.CATEGORY_SONG);
    Reader reader = new InputStreamReader(source);
    Type happyCollection = new TypeToken<Collection<String>>() {}.getType();
    _karaoke_category_response =  new Gson().fromJson(reader, happyCollection);
    if(_karaoke_category_response.size() < 1){
        finish();
        Toast.makeText(getApplicationContext(), "Local sin karaokes", Toast.LENGTH_SHORT).show();
    }else{
        Log.i("Category - response", _karaoke_category_response.toString());
        _karaoke_category_adapter = new ArrayAdapter<String>(getSupportActionBar().getThemedContext(), R.layout.spinner_item,_karaoke_category_response);
        getSupportActionBar().setListNavigationCallbacks(_karaoke_category_adapter,  this);
    }

The follow code is of search the songs of that categori and set it

    class AsyncKaraoke extends AsyncTask<Void, Void, Void> {
    String category;

    public AsyncKaraoke(String category) {
        this.category = category;
    }

    protected void onPreExecute(){
        super.onPreExecute();
        setSupportProgressBarIndeterminateVisibility(true);
    }

    @Override
    protected Void doInBackground(Void... params) {
        java.io.InputStream source = null;

        try {
            source = retrieveStream(UrlApi.URL_BASE + UrlApi.URL_STORE + _bundle.getString("_id") + UrlApi.KARAOKE_URL + UrlApi.FILTER_CATEGORY + URLEncoder.encode(category, "UTF-8"));
            Log.i("URL - KARAOKE", UrlApi.URL_BASE + UrlApi.URL_STORE + _bundle.getString("_id") + UrlApi.KARAOKE_URL + UrlApi.FILTER_CATEGORY + URLEncoder.encode(category, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Reader reader = new InputStreamReader(source);
        Type karaokeCollection = new TypeToken<Collection<KaraokeModel>>() {}.getType();
        _response = new Gson().fromJson(reader, karaokeCollection);
        Log.i("Response - KaraokeCategory" , _karaoke_category_response.toString());
        return null;
    }
    protected void onPostExecute(Void Void){
        super.onPostExecute(Void);
        setSupportProgressBarIndeterminateVisibility(false);
        _karaoke_adapter = new KaraokeAdapter(KaraokeActivity.this,  _bundle.getString("_id"), _response);
        if(_response.size() == 0){
            Toast.makeText(getApplicationContext(), "Categoria sin karaoke", Toast.LENGTH_SHORT).show();
        }
        _list_view.setAdapter(_karaoke_adapter);
        _karaoke_adapter.notifyDataSetChanged();
    }


}

How should I do to call 2 times to "AsyncTask" method and prevent the activity is engaged by a few seconds?

Upvotes: 0

Views: 384

Answers (4)

DeeV
DeeV

Reputation: 36045

The primary rule of AsyncTask is that it must always be create and run on the main thread. You will get an exception if you start another AsyncTask inside the doInBackground() method. Your options are to start the next AsyncTask in one of the callbacks. Generally, some people will chain AsyncTask in the onPostExecute() method, but you can also start them in onPreExecute() and onProgressUpdate().

EDIT:

Additionally, you can run AsyncTask in sequence of each other using AsyncTask#executeOnExecutor(). From HoneyComb on, you don't need to do this. All AsyncTask run in a serial thread pool in the order they are executed. Though it may be easier to understand that the code is running serially if you use it. You do need to chain if using Android Android 1.6 - 2.3.x though.

Upvotes: 3

Sami Eltamawy
Sami Eltamawy

Reputation: 10009

Generally, we use AsyncTask to perform an action in another thread than the UI thread to prevent the user from being halt while performing some actions. SO, it does not make any sense to create an additional AsyncTask inside the outer one. Try to manage your code to do it all the those method soInBackground(), onPreExecution() and onPostExecution() and make use of their order of execution

Upvotes: 1

Nicolas Defranoux
Nicolas Defranoux

Reputation: 2676

You should build the URL in the main activity, then run an AsyncTask to download the content and finally process the result back in your activity.

The syntax to run an AsyncTask is:

String category = "...";
new AsyncKaraoke().execute(category);

You can also remove the onPostExecute() method from your AsyncKaraoke class and put it in the activity:

String category = "...";
new AsyncKaraoke() {
  @Override
  protected void onPostExecute(Void Void){
    // do stuff (and moving the third type of the AsyncKaraoke to something else
    // than Void will allow you to get the result here.
}.execute(category);

Upvotes: 1

Looking Forward
Looking Forward

Reputation: 3585

int count = 0;

protected void onPostExecute(Void Void){
        super.onPostExecute(Void);

        // call same asynctask
          if (count == 0)
            {     
                execute asynctask
                count++;
            }
}

Upvotes: 0

Related Questions