簡體   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