Android -跟踪线程



我有一个活动,它在执行过程中启动了几个AsyncTask和几个Thread

如果这些继续当活动被销毁/重新创建,那么各种各样的错误发生,所以我的聪明的想法是让每个非UI线程注册自己,将自己添加到ArrayList<Thread>()ArrayList<AsyncTask>()意味着我可以,onDestroy(),通过这些数组列表迭代并销毁它们,像这样:

@Override
public void onDestroy() 
{
    for(AsyncTask task : tasks)
        task.cancel(true);*
    for(Thread thread : threads)
        thread.interrupt();
}

不幸的是,这会在用*标记的行上抛出java.util.ConcurrentModificationException。我尝试在synchronize块中包装每个for循环,以确保ArrayList s不会被任何其他Thread s修改。

AsyncTask s在完成时销毁自己(因此抛出上述错误)?

有谁知道在Android环境中控制线程的更好方法吗?

编辑

改变代码使用for(int i =0 : i < array.size() ; i++)似乎解决了这个问题,但我仍然想知道/为什么/它会发生:

    synchronized(tasks)
    {
        for(int i=0; i < tasks.size(); i++)
            tasks.get(i).cancel(true);
    }
    synchronized(threads)
    {
        for(int i=0; i < threads.size(); i++)
            threads.get(i).interrupt();
    }

这是一个非常古老的问题,但我还是会回答它,因为这是人们经常遇到的问题。

这里发生的是下面的代码

for(AsyncTask task : tasks)
    task.cancel(true);`

使用for-each循环,需要tasks对象在迭代时保持完整。我的猜测是,在您的任务的onPostExecute()中,您正在从此列表中删除它,这会修改它并导致异常。

据我所知,AsyncTasks消失,一旦他们运行onPostExecute,你已经设置实例为空,或类似的东西。你在线程中做什么,你不能在服务或AsyncTask中做?你做UI操作在你的线程(如,runonuthread或其他东西),这将导致这些线程错误时,应用程序不是在前台?

在服务中做事情的好处是,你可以广播你即将关闭应用程序,并停止服务中不再需要运行的任何操作,本质上是休眠服务,直到应用程序进入前台时再次启动它。

你不能阻止并发修改,除非应用程序中的所有修改都被synchronized包围;只在这里做是不够的。

尝试使用同步集合:

// create the empty list
List tasks = Collections.synchronized(new ArrayList<AsyncTask>());

当doInBackground完成时,AsyncTask确实会杀死自己。对于这个问题,java线程在run()完成时做同样的事情。cancel()的调用将只返回true或false,这取决于是否能够取消asyncTask。

当你试图修改线程中正在使用的东西时,ConcurrentModificationException会被抛出。据我所知,你的数组列表正在UI线程中用于取消asynctasks,它也在两个asynctasks中用于注册自己。我猜你在某个地方没有同步数组列表集合。 也许

:

synchronized(tasks){
    for(int i=0; i < tasks.size(); i++){
       tasks.get(i).cancel(true);
    }
}

将修复它。确保在所有asyncTasks中也同步了task。或者你可以让它挥发。

但是无论如何,当你在onDestroy时,你的asyncTasks可能已经完成了(或者应该完成),所以我不明白为什么你需要确保它们被取消。如果你不想让它们在用户离开应用程序时运行,那么你应该把它放在onPause()中。

最新更新