2

Я использую AsyncTask (1) в другом AsyncTask (2). AsyncTask 1 извлекает онлайн-данные пользователя, подсчитывает количество записей в ответе и для каждой записи, в onPostExecute отображает имя пользователя и запускает новую AsyncTask (2), чтобы получить изображение с сервера и загрузить его в ImageView. Все это происходит в onPostExecute. Это работает безупречно, пользовательские данные извлекаются и отображаются, а изображения отображаются по одному для каждой записи.Вложенные AsyncTask и onPostExecute

Однако itteration через массив и обновление TextView в AsyncTask 1-х onPostExecute происходит настолько быстро, что в основном показывает только имя последнего пользователя в массиве, остальные загружаются, но невозможно обнаружить с человеком eye :)

Между тем, AsyncTask 2 все еще извлекает изображения из Интернета и показывает изображения профилей для неправильных пользователей. Проблема, которую я имею здесь, очевидно, состоит в том, что эти 2 должны быть синхронизированы. Так что я думал, что просто дождался выхода в AsyncTask 2 с помощью метода get(), но теперь ничего не обновляется вообще, нет TextView ... это неожиданное поведение для меня.

Итак, вопрос в том, как синхронизировать 2 AsyncTask s?

бит кода для уточнения, если это все-таки необходимо

//instantiate first AsyncTask 
    new AsyncRequest().execute(bundle); 

    private class AsyncRequest extends AsyncTask<Bundle, Void, String> { 
    protected String doInBackground(Bundle... bundle) { 
     String data = null; 
     try { 
      data = request(null, bundle[0]); //request the data 
      return data; 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return data; 
    }// end method 

    protected void onPostExecute(String response) { 
     JSONArray data = null; 
     try { 
      JSONObject response2 = Util.parseJson(response); 
      data  = response2.optJSONArray("data"); 
      int amount = data.length(); 
      TextView s1 = (TextView) findViewById(R.id.some_id); 
      s1.setText("" + amount); //displays number of items 

      //display the data 
      for(int i=0; i<amount; i++){ 
       String email  = ""; 
       String id   = ""; 
       JSONObject json_obj = data.getJSONObject(i); 
       Log.d("JSONObject ", ""+json_obj); 
       String name   = json_obj.getString("name"); 
       if (json_obj.has("email")){ 
        email   = json_obj.getString("email"); 
       } 
       if (json_obj.has("id")){ 
        id   = json_obj.getString("id"); 
       } 
       String picture = "http://www.domain.com/"+id+"/picture"; 
       TextView s2  = (TextView) findViewById(R.id.name_placeholder); 
       s2.setText(name); 
       //here we do a new AsynTask for each entry and wait until the data is fetched 
       new DownloadProfileImageTask().execute(picture, name).get(); 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      e.printStackTrace(); 
     } 
    }// end method 

ответ

7

Это не совсем понятно, почему вы звоните setText единого TextView с именем несколько имен. Как вы уже упоминали, хотя у вас было setText всех имен, вы видите только одно имя. Может быть, вам нужно использовать ListView или что-то в этом роде.

Теперь о вашем вопросе: возможно, вам не нужны два AsyncTask. Вы можете сделать все в одном AsyncTask. Код будет выглядеть примерно так:

//Create a Holder class as a data holder. 
//For simplicity, public attributes are used 
class Holder{ 
    public String name; 
    public String email; 
    public String id; 
    public BitmapDrawable imageDrawable; 
} 

//instantiate the AsyncTask 
new AsyncRequest().execute(bundle); 

private class AsyncRequest extends AsyncTask<Bundle, Holder, Integer> { 
protected Integer doInBackground(Bundle... bundle) { 
    int amount = 0; 
    try { 
     data = request(null, bundle[0]); //request the data 

     JSONArray data = null; 
     JSONObject response2 = Util.parseJson(response); 
     data  = response2.optJSONArray("data"); 
     amount = data.length(); 

     //display the data 
     for(int i=0; i<amount; i++){ 
      Holder holder = new Holder(); 
      holder.email  = ""; 
      holder.id   = ""; 
      JSONObject json_obj = data.getJSONObject(i); 
      Log.d("JSONObject ", ""+json_obj); 
      holder.name   = json_obj.getString("name"); 
      if (json_obj.has("email")){ 
       holder.email   = json_obj.getString("email"); 
      } 
      if (json_obj.has("id")){ 
       holder.id   = json_obj.getString("id"); 
      } 
      String picture = "http://www.domain.com/"+id+"/picture"; 

      //Fetch the image and create a Drawable from it - Synchronously 
      holder.imageDrawable = getImageDrawable(picture, name); 

      publishProgress(holder); 

     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return amount; 
}// end method 

protected void onProgressUpdate(Holder... holder) { 
    //Update the user name and image 
    TextView s2  = (TextView) findViewById(R.id.name_placeholder); 
    s2.setText(holder[0].name); 

    ImageView imgView = (ImageView) findViewById(R.id.imageViewId); 
    imgView.setImageDrawable(holder[0].imageDrawable); 

} 

protected void onPostExecute(Integer amount) { 
    TextView s1 = (TextView) findViewById(R.id.some_id); 
    s1.setText(amount.toString()); //displays number of items 
}// end method 
+0

Вау, почему я не подумал об этом? Очень простое решение на самом деле. Большое спасибо за то, что нашли время, чтобы изменить мой код и опубликовать его как ответ! Мне нужно было сделать несколько небольших изменений, чтобы он работал, и соответственно обновил ваш ответ. Еще раз спасибо. – slinden77

+1

PS: Я обновляю один TextView, потому что хочу показать информацию о пользователе для профилей, найденных в запросе. Все это делается на одной странице/Activity. Конечно, позже я действительно сделаю что-то полезное с Activity;) – slinden77

Смежные вопросы