因此,如果我有5个异步任务正在运行并且取消了它们,则UI会冻结一些,但是如果我做了20个asyncTasks并取消了它们,则UI会冻结一段时间。我的问题是,asyncTask.cancel(true)方法是否昂贵?这样我的用户界面会冻结吗?我注意到,当我不打电话取消时,我的UI不会冻结。无论如何,我可以防止UI冻结吗?我尝试将.cancel(true)方法放入自己的线程中,但这没有帮助。
这里有一些代码。
//could be as little as 1 or could be 20
for( AsyncTask asyncTask : asyncTasks )
{
if ( asyncTask != null )
{
//seems to block UI for a bit if there are a lot of calls
asyncTask.cancel( true );
}
}
最佳答案
您的任务是否检查isCancelled()
函数中的doInBackground()
?AsyncTask
的目的是在后台快速运行(即计算上很短的任务),并将结果发布到UI线程。这意味着,当您调用asyncTask.cancel(true);
时,不是在UI线程上调用 onPostExecute
,而是在UI线程上调用onCancelled
。
由于“取消”是在UI线程上调用的,因此,如果您的线程处于紧密循环中,并且不对任何全局变量进行任何检查或取消请求(例如检查isCancelled
),则可能要花费一些时间对于底层API来清理线程(正确结束/取消线程而线程本身不会结束),“时间”就是您遇到的UI“暂停”。
为了减轻这种情况,只需在doInBackground
函数中检查isCancelled
函数:
// simple example function:
protected Void doInBackground (Void... params) {
for(int i=0; i < 65535; ++i) {
if (isCancelled()) { break; } // exit loop on cancel request
}
return null;
}
在此
AsyncTask
中,如果我们再调用asyncTask.cancel(true);
,则循环将在下次检查isCancelled
时中断,并且UI线程可以继续与等待循环完成其迭代(因此“暂停” UI直到线程已完成)。希望能对您有所帮助。