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

Android 我的AsyncTask类中有其他线程。在执行以下方法之前,如何等待它及其所有线程完成?,android,multithreading,Android,Multithreading,AsyncTask类启动许多其他线程,因为我使用的是第三方库。我不确定库打开了多少线程,但我想等待它们全部完成,然后用它们获取的数据填充我的listview 目前我正在睡眠10000毫秒,但这是不实际的,因为我不知道它的列表有多大 这个问题的正确解决方案是什么 task = new mTask(); task.execute(appsList); new Thread(new Runnable() { public void run() {

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

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