[英]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.