Android 我的AsyncTask类中有其他线程。在执行以下方法之前,如何等待它及其所有线程完成?
AsyncTask类启动许多其他线程,因为我使用的是第三方库。我不确定库打开了多少线程,但我想等待它们全部完成,然后用它们获取的数据填充我的listview 目前我正在睡眠10000毫秒,但这是不实际的,因为我不知道它的列表有多大 这个问题的正确解决方案是什么Android 我的AsyncTask类中有其他线程。在执行以下方法之前,如何等待它及其所有线程完成?,android,multithreading,Android,Multithreading,AsyncTask类启动许多其他线程,因为我使用的是第三方库。我不确定库打开了多少线程,但我想等待它们全部完成,然后用它们获取的数据填充我的listview 目前我正在睡眠10000毫秒,但这是不实际的,因为我不知道它的列表有多大 这个问题的正确解决方案是什么 task = new mTask(); task.execute(appsList); new Thread(new Runnable() { public void run() {
task = new mTask();
task.execute(appsList);
new Thread(new Runnable() {
public void run() {
populateList();
}
}).start();
}
private class mTask extends AsyncTask<List<ApplicationInfo>, Void, Void> {
ProgressDialog progress;
@Override
protected void onPreExecute() {
progress = new ProgressDialog(MainActivity.this);
progress.setIndeterminate(true);
progress.show();
super.onPreExecute();
}
@SuppressWarnings("deprecation")
@Override
protected Void doInBackground(List<ApplicationInfo>... params) {
appDataManager = new AppDataManager(MainActivity.this,
mySQLiteAdapter, MainActivity.this);
appDataManager.work(params[0]);
return null;
}
@Override
protected void onPostExecute(Void result) {
mySQLiteAdapter.close();
progress.dismiss();
super.onPostExecute(result);
}
}
@SuppressWarnings("deprecation")
public void populateList() {
try {
Thread.sleep(10000)
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
Cursor cursor;
mySQLiteAdapter.openToRead();
cursor = mySQLiteAdapter.queueAll();
ArrayList<String> appsList = new ArrayList<String>();
if (cursor.moveToFirst()) {
do {
appsList.add(cursor.getString(1));
} while (cursor.moveToNext());
}
cursor.moveToFirst();
ArrayAdapter<String> adp = new ArrayAdapter<String>(
MainActivity.this, android.R.layout.simple_list_item_1,
appsList);
listContent.setAdapter(adp);
cursor.close();
mySQLiteAdapter.close();
Log.i("finished", "finished");
}
});
}
task=new mTask();
task.execute(appsList);
新线程(newrunnable()){
公开募捐{
大众主义者();
}
}).start();
}
私有类mTask扩展异步任务{
进程对话进程;
@凌驾
受保护的void onPreExecute(){
进度=新建进度对话框(MainActivity.this);
progress.setUndeterminate(true);
progress.show();
super.onPreExecute();
}
@抑制警告(“弃用”)
@凌驾
受保护的Void doInBackground(列表…参数){
appDataManager=新的appDataManager(MainActivity.this,
mySQLiteAdapter,MainActivity.this);
appDataManager.work(参数[0]);
返回null;
}
@凌驾
受保护的void onPostExecute(void结果){
mySQLiteAdapter.close();
进步。解散();
super.onPostExecute(结果);
}
}
@抑制警告(“弃用”)
公共无效公共列表(){
试一试{
线程。睡眠(10000)
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
runOnUiThread(新的Runnable(){
公开募捐{
光标;
mySQLiteAdapter.openToRead();
cursor=mySQLiteAdapter.queueAll();
ArrayList appsList=新的ArrayList();
if(cursor.moveToFirst()){
做{
appsList.add(cursor.getString(1));
}while(cursor.moveToNext());
}
cursor.moveToFirst();
ArrayAdapter adp=新的ArrayAdapter(
MainActivity.this,android.R.layout.simple\u list\u item\u 1,
应用列表);
setAdapter(adp);
cursor.close();
mySQLiteAdapter.close();
Log.i(“完成”、“完成”);
}
});
}
AppDataManager
public void work(List<ApplicationInfo> appsList) {
List<ApplicationInfo> appList = appsList;
mySQLiteAdapter.openToWrite();
mySQLiteAdapter.deleteAll();
mySQLiteAdapter.close();
for (int i = 0; i < 5; i++) {
String name = appList.get(i).name;
String pack = appList.get(i).packageName;
// TODO AsyncTask
getHtml(pack, name);
}
}
public void getHtml(final String pack, final String name) {
String url = MARKET_URL + pack;
//AndroidQuery library. fetch html
aq.ajax(url, String.class, 1000, new AjaxCallback<String>() {
@Override
public void callback(String url, String htm, AjaxStatus status) {
Log.i("status", status.getMessage());
parseHtml(htm, pack, name);
}
});
}
公共作废工作(列表应用列表){
列表应用列表=应用列表;
mySQLiteAdapter.openToWrite();
mySQLiteAdapter.deleteAll();
mySQLiteAdapter.close();
对于(int i=0;i<5;i++){
String name=appList.get(i).name;
stringpack=appList.get(i).packageName;
//TODO异步任务
getHtml(包、名称);
}
}
public void getHtml(最终字符串包、最终字符串名){
字符串url=MARKET\u url+pack;
//AndroidQuery库。获取html
ajax(url,String.class,1000,新的AjaxCallback(){
@凌驾
公共无效回调(字符串url、字符串htm、AjaxStatus状态){
Log.i(“status”,status.getMessage());
解析HTML(htm、pack、name);
}
});
}
如果您正在等待线程到达一个公共点,那么它似乎是一个解决方案
另外,我不需要创建一个线程来调用
populatelist()
,这是创建线程runOnUiThread
,而是首先查看,我会将对populatelist
的调用移动到异步任务的onPostExecute
方法中。我还将重写populateList
,以删除睡眠,并假设它正在UI线程上运行(消除runOnUiThread
调用,并将run
方法的主体直接移动到populateList
)
现在阻止AsyncTask
完成doInBackground
,直到AppDataManager
完成其工作。首先定义一个完成标志和一个可以同步的锁对象:
private class mTask extends AsyncTask<List<ApplicationInfo>, Void, Void> {
boolean complete;
static Object LOCK = new Object();
. . .
}
现在修改doInBackground
方法以等待设置标志:
protected Void doInBackground(List<ApplicationInfo>... params) {
appDataManager = new AppDataManager(MainActivity.this,
mySQLiteAdapter, MainActivity.this);
appDataManager.work(params[0], new Runnable() {
public void run() {
synchronized (LOCK) {
complete = true;
LOCK.notifyAll();
}
}
});
// wait for appDataManager.work() to finish...
synchronized (LOCK) {
while (!complete) {
LOCK.wait();
}
}
return null;
}
protectedvoiddoinbackground(计数器列表。appDataManager做什么?@user1049280从Internet获取数据您的第三方库的API是否有回调机制来表示工作完成?appDataManager是否扩展线程?您能提供更多详细信息吗?@TedHopp我已将appManager的内容添加到我的问题中谢谢。我t只做了一点修改。因为getHtml()
在循环中被调用,complete
在第一次运行时被设置为true。我添加了一个标志,当循环最后一次执行时为true。这就解决了问题。
protected Void doInBackground(List<ApplicationInfo>... params) {
appDataManager = new AppDataManager(MainActivity.this,
mySQLiteAdapter, MainActivity.this);
appDataManager.work(params[0], new Runnable() {
public void run() {
synchronized (LOCK) {
complete = true;
LOCK.notifyAll();
}
}
});
// wait for appDataManager.work() to finish...
synchronized (LOCK) {
while (!complete) {
LOCK.wait();
}
}
return null;
}