Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了android – 我的AsyncTask类中还有其他线程.在执行以下方法之前,我如何等待它及其所有线程完成?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
AsyncTask类启动了许多其他线程,因为我使用的是第三方库.我不确定该库打开了多少个线程,但是我想等待它们全部完成,然后使用它们获取的数据填充我的列表视图.

目前我正在睡觉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");
         }
         });

    }@H_450_7@ 
 

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

        }
    });
}@H_450_7@

解决方法

首先,我将把PopulateList的调用移动到AsyncTask的onPostExecute方法中.我还会重写populateList以删除睡眠并假设它在UI线程上运行(消除runOnUiThread调用并将run方法的主体直接移动到populateList中).

现在,为了防止AsyncTask完成doInBACkground,直到ApPDAtaManager完成其工作.首先定义一个完成标志和一个可以同步的锁定对象:

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

然后修改ApPDAtaManager类,以在完成工作时提供对另一个对象的回调.定义字段回调并更新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);
            if (callBACk != null) {
                callBACk.run();
            }
        }
    });
}@H_450_7@ 
 

现在修改doInBACkground方法以等待设置标志:

protected Void doInBACkground(List<ApplicationInfo>... params) {
    apPDAtaManager = new ApPDAtaManager(MainActivity.this,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;
}@H_450_7@ 
 

这应该做的工作.但是,您可能应该详细说明这一点以处理各种错误(例如,为ApPDAtaManager提供错误通知机制).

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

大佬总结

以上是大佬教程为你收集整理的android – 我的AsyncTask类中还有其他线程.在执行以下方法之前,我如何等待它及其所有线程完成?全部内容,希望文章能够帮你解决android – 我的AsyncTask类中还有其他线程.在执行以下方法之前,我如何等待它及其所有线程完成?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。