Android AsyncTask确保已加载所有数据

时间:2012-06-11 15:34:28

标签: java android multithreading android-asynctask

您好我正在尝试创建一个运行两个函数的Asynctask,当它们完成加载后,然后用数据填充UI。在某种程度上它只是用一个函数中的数据填充UI,其中任何一个函数首先完成加载。

例如

我有两个函数LoadNewsFeed()和LoadResultsFeed()目前loadResultsFeed()显示数据而不是来自loadNews()的任何内容但是如果我注释掉LoadResultsFeed(),来自loadNews的数据填充UI但不会来自loadResultsFeed < / p>

有没有办法可以设置它,如果那个完成加载,加载另一个而不是执行FillData()函数?

继承人到目前为止我所拥有的

public class PostTask扩展了AsyncTask {

    @Override
    protected Boolean doInBackground(Void... params) {
        boolean result = false;

        loadNewsFeed();

        publishProgress("method1");
        loadResultsFeed();
        publishProgress("method2");
        return result;
    }


    protected void onProgressUpdate(String... progress) {
        StringBuilder str = new StringBuilder();
            for (int i = 1; i < progress.length; i++) {
                str.append(progress[i] + " ");

            }
    }

        @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        Log.v("BGThread", "begin fillin data");
         FillData();
    }
}

继承我的FillData()函数

public void FillData(){ 


     if (ChosenMethod.equals("Team")) {




        arrayAdapter = new ArrayAdapter<String>(this, R.layout.single_item, newsList);

         String[] mStrings = (String[]) imageList.toArray(new String[imageList.size()]);
         String[] news = (String[]) newsList3.toArray(new String[newsList3.size()]);

         arrayAdapter3 = new LazyAdapter(this, mStrings, news);


            ListView list = getListView();
               list.setTextFilterEnabled(true);

               LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE );
                View header = inflater.inflate( R.layout.homeheader, list, false);
                View header2 = inflater.inflate( R.layout.homeheader2, list, false);
                View header3 = inflater.inflate( R.layout.homeheader3, list, false);


        //setListAdapter (arrayAdapter);

                 resultsView = LayoutInflater.from(getBaseContext()).inflate(R.layout.resultscell,
                         null);

               TextView homeTeam = (TextView) resultsView.findViewById(R.id.HomeTeam);
               homeTeam.setText(HomeTeam);

               TextView awayTeam = (TextView) resultsView.findViewById(R.id.AwayTeam);
               awayTeam.setText(AwayTeam);

               TextView homeScore = (TextView) resultsView.findViewById(R.id.HomeScore);
               homeScore.setText(HomeScore);

               TextView awayScore = (TextView) resultsView.findViewById(R.id.AwayScore);
               awayScore.setText(AwayScore);

               TextView attendance = (TextView) resultsView.findViewById(R.id.Attendence);
               attendance.setText("Att:" + Attendance);

               TextView division = (TextView) resultsView.findViewById(R.id.Division);
               division.setText(Division);

               Log.v("BGThread", "Filled results");

            adapter = new MergeAdapter();
            adapter.addView(header);
            adapter.addAdapter(arrayAdapter);
            adapter.addView(header2);
            adapter.addView(resultsView);
            adapter.addView(header3);
            adapter.addAdapter(arrayAdapter3);
            setListAdapter(adapter);

            Log.v("BGThread", "Filled Merge Adapter Team");

     } else {

         arrayAdapter = new ArrayAdapter<String>(this, R.layout.single_item, newsList);
            arrayAdapter2 = new ArrayAdapter<String>(this, R.layout.single_item, newsList2);
            //arrayAdapter3 = new ArrayAdapter(this, R.layout.complex_item, newsList3);

             String[] mStrings = (String[]) imageList.toArray(new String[imageList.size()]);
             String[] news = (String[]) newsList3.toArray(new String[newsList3.size()]);


             arrayAdapter3 = new LazyAdapter(this, mStrings, news);


                ListView list = getListView();
                   list.setTextFilterEnabled(true);

                   LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE );
                    View header3 = inflater.inflate( R.layout.homeheader3, list, false);


            //setListAdapter (arrayAdapter);


                adapter = new MergeAdapter();
                adapter.addView(header3);
                adapter.addAdapter(arrayAdapter3);
                setListAdapter(adapter);

                Log.v("BGThread", "Filled Merge Adapter League");
         } 
}

2 个答案:

答案 0 :(得分:0)

一种快速简便的方法是在类中添加一个布尔字段,该字段最初为真:

private boolean bothFeedsLoaded = true;

然后在onPostExecute中切换它的值:

bothFeedsLoaded = !bothFieldsLoaded;

在你的FillData方法中:

if (!bothFeedsLoaded){return;}

由于两个FeedLoaded最初都为true,因此第一次回调onPostExecute(在先加载任何一个Feed之后)会将其更改为false。因此,您的fillData方法将返回而不执行任何操作。当第二个Feed完成加载时,onPostEexcute会将其更改为true,而fillData将执行此操作。

或者(可能在6个月内更容易阅读)是使用整数:

private int feedsLoaded = 0;

.....

feedsLoaded ++;

.....

if (feedsLoaded != 2) {return;}

有更好的方法,例如为每个加载任务创建单独的类,然后在各自的onPostExecute回调中同步两个信号量,但这应该有效。

答案 1 :(得分:0)

如果使用AsyncTask并不重要,我建议使用Thread类和Handler,

  1. 您可以使用join,具有这两种方法的类,让它implement Runnable接口,然后您可以创建该类的对象并将其传递给Thread构造函数。然后在线程上使用join,这意味着除非线程死亡,否则不会执行下面的行,并且在连接之后,使用这些行将数据放在UI上。

  2. 您也可以从CountDownLatch包中java.util.Concurrent,等待特定工作完成,然后再执行。