gpt4 book ai didi

android - 我的 AsyncTask 类中有其他线程。在执行以下方法之前,我如何等待它及其所有线程完成?

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:57:43 25 4
gpt4 key购买 nike

AsyncTask 类启动了许多其他线程,因为我使用的是第三方库。我不确定库打开了多少个线程,但我想等待它们全部完成,然后再用它们获取的数据填充我的 ListView 。

目前我正在休眠 10000 毫秒,但这不切实际,因为我不知道它有多大。

这个问题的正确解决方案是什么?

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

}

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);

}
});
}

最佳答案

首先,我会将电话转到 populateList进入onPostExecute你的方法AsyncTask .我也会重写 populateList删除 sleep 并假设它在 UI 线程上运行(消除 runOnUiThread 调用并将 run 方法的主体直接移动到 populateList 中)。

现在要防止 AsyncTask从完成 doInBackground直到 AppDataManager完成它的工作。首先定义一个完成标志和一个可以同步的锁对象:

private class mTask extends AsyncTask<List<ApplicationInfo>, Void, Void> {
boolean complete;
static Object LOCK = new Object();
. . .
}

然后修改AppDataManager类以在工作完成时提供对另一个对象的回调。定义一个字段 callback并更新您的 API 和方法:

public void work(List<ApplicationInfo> appsList, Runnable callback) {
this.callback = callback; // define a field named "callback"
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);
if (callback != null) {
callback.run();
}
}
});
}

现在修改你的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;
}

这应该可以完成工作。但是,您可能应该对此进行详细说明以处理各种错误(例如,为 AppDataManager 提供错误通知机制)。

更新 我终于注意到您在 AppDataManager 中进行了五次网络交易。 .因此,不是立即在 ajax() 的回调方法中运行回调。 ,递减一个计数器,并且只在计数器达到 0 时回调。在 work() 中将计数器初始化为 5在进入调用 getHtml() 的循环之前.由于计数器将被单独的线程修改,因此对它的访问需要同步。 (或者,您可以使用 AtomicInteger 作为计数器。

关于android - 我的 AsyncTask 类中有其他线程。在执行以下方法之前,我如何等待它及其所有线程完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13362510/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com