是否可以在另一个方法“AsyncTask”中运行“AsyncTask”方法?

时间:2014-02-27 15:46:59

标签: java android json android-asynctask

我有一个活动,当启动时调用“json”获取歌曲的数据类别,然后我调用方法“AsyncTask”获取来自另一个“JSON”类别的歌曲列表问题是,当我开始活动时,它被锁定,2秒后,活动打开布局,我可以在操作栏上看到类别,而不是因为歌曲在后台寻找。

主要活动(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);
    }

以下代码用于搜索该分类的歌曲并进行设置

    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();
    }


}

我应该如何调用2次“AsyncTask”方法并阻止活动几秒钟?

4 个答案:

答案 0 :(得分:3)

AsyncTask的主要规则是必须始终在主线程上创建并运行它。如果您在AsyncTask方法中启动另一个doInBackground(),则会收到异常。您可以选择在其中一个回调中启动下一个AsyncTask。通常,有些人会在AsyncTask方法中链接onPostExecute(),但您也可以在onPreExecute()onProgressUpdate()中启动它们。

编辑:

此外,您可以使用AsyncTask#executeOnExecutor()按顺序运行AsyncTask。从HoneyComb开始,您不需要这样做。所有AsyncTask按照它们执行的顺序在串行线程池中运行。虽然如果使用它可能更容易理解代码是串行运行的。如果使用Android Android 1.6 - 2.3.x,你确实需要链接。

答案 1 :(得分:1)

您应该在主活动中构建URL,然后运行AsyncTask以下载内容,最后将结果处理回您的活动。

运行AsyncTask的语法是:

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

您还可以从AsyncKaraoke类中删除onPostExecute()方法并将其放入活动中:

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);

答案 2 :(得分:1)

通常,我们使用AsyncTaskthread以外的UI线程中执行操作,以防止用户在执行某些操作时停止操作。 SO,在外部内部创建额外的AsyncTask没有任何意义。尝试管理您的代码以执行所有这些方法soInBackground()onPreExecution()onPostExecution()并使用其执行顺序

答案 3 :(得分:0)

int count = 0;

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

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