繁体   English   中英

Android AsyncTask确保所有数据均已加载

[英]Android AsyncTask making sure all data has been loaded

嗨,我正在尝试创建一个运行两个函数的Asynctask,当它们完成加载后,然后用数据填充UI。 目前,出于某种原因,它仅用一个函数中的数据填充UI,并且其中任何一个函数首先完成加载。

例如

当loadResultsFeed()显示数据而不显示loadNews()时,我有两个函数LoadNewsFeed()和LoadResultsFeed(),但是如果我注释掉LoadResultsFeed(),则来自loadNews的数据将填充UI,但不会填充来自UI的数据。

有没有一种方法可以将其设置为如果完成加载,再加载另一个而不执行FillData()函数?

这是我到目前为止的

公共类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");
         } 
}

一种快速简便的方法是将一个布尔字段添加到您的类中,这最初是正确的:

private boolean bothFeedsLoaded = true;

然后在onPostExecute中切换它的值:

bothFeedsLoaded = !bothFieldsLoaded;

在您的FillData方法中:

if (!bothFeedsLoaded){return;}

由于bothFeedsLoaded最初为true,因此onPostExecute的第一个回调(无论哪个feed首先加载)都将其更改为false。 因此,您的fillData方法将不执行任何操作而返回。 当第二个提要完成加载时,onPostEexcute会将其更改回true,然后fillData会执行此操作。

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

private int feedsLoaded = 0;

.....

feedsLoaded ++;

.....

if (feedsLoaded != 2) {return;}

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

如果使用AsyncTask不是很关键,我建议与Handler一起使用Thread类,

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

  2. 您也可以从java.util.Concurrent包中进行CountDownLatch ,它将等待特定的工作完成,然后进一步执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM