【问题标题】:nested AsyncTask and onPostExecute嵌套的 AsyncTask 和 onPostExecute
【发布时间】:2012-06-09 17:23:29
【问题描述】:

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

但是,数组的迭代和AsyncTask 1的onPostExecuteTextView的更新发生得太快了,它基本上只显示数组中的最后一个用户名,其他的都加载了,但不可能用人眼检测:)

与此同时,AsyncTask 2 仍在从网上获取图片,并显示错误用户的个人资料图片。 显然我在这里遇到的问题是这两个需要同步。 所以我想我只是用get() 方法等待AsyncTask 2 中的输出,但现在什么都没有更新了,没有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

【问题讨论】:

    标签: android android-asynctask android-imageview textview


    【解决方案1】:

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

    现在关于您的问题:可能您不需要两个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
    

    【讨论】:

    • 哇,我怎么没想到呢?实际上非常简单的解决方案。非常感谢您花时间修改我的代码并将其发布为答案!我需要对其进行一些小的修改才能使其正常工作,并相应地更新了您的答案。再次感谢。
    • PS:我正在更新单个 TextView,因为我想显示请求中找到的配置文件的用户信息。所有这些都在单个页面/活动上完成。当然,稍后我会用 Activity 做一些有用的事情;)
    猜你喜欢
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多