[英]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類,
您可以使用具有這兩種方法的類join
,讓它implement Runnable
接口,然后可以創建該類的對象並將其傳遞給Thread構造函數。 然后在線程上使用join,這意味着直到線程線程死掉為止,除非線程死亡,否則將不執行以下行,並且在連接之后,使用這些行將數據放置在UI上。
您也可以從java.util.Concurrent
包中進行CountDownLatch
,它將等待特定的工作完成,然后進一步執行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.