3

AsyncTask在另一个AsyncTask(2) 中使用 (1)。AsyncTask 1 获取在线用户数据,计算响应中的条目数,对于每个条目,onPostExecute显示用户名并运行新的 AsyncTask (2) 从服务器获取图像并将其加载到ImageView. 这一切都发生在onPostExecute. 这是完美的工作,用户数据被获取并显示,并且图像为每个条目一张一张地显示。

然而,数组的迭代和TextViewin AsyncTask1的更新onPostExecute发生得如此之快,它基本上只显示数组中的最后一个用户名,其他的都被加载了,但肉眼无法检测到:)

同时,AsyncTask2 仍在从网上获取图片,并为错误的用户显示个人资料图片。显然我在这里遇到的问题是这两个需要同步。AsyncTask所以我以为我只是用该方法等待 2 中的输出get(),但现在什么都没有更新了,不TextView……这对我来说是意外的行为。

那么,问题是如何同步 2 AsyncTasks?

一些代码来澄清,如果它仍然需要

    //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
4

1 回答 1

8

目前还不太清楚为什么你用多个名字的名字来称呼一个人setTextTextView正如您所提到的,尽管您拥有setText所有名称,但您只看到一个名称。可能您需要使用 aListView或类似的东西。

现在关于您的问题:可能您不需要两个AsyncTasks. 您可以在一个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
于 2012-06-09T18:11:32.887 回答