我有一个自定义视图,我可以在其中绘制不同大小的单词和图像。因为我需要对各种用户操作执行所有类型的计算,并且它们可以持续3-4秒,所以我需要实现一种在用户等待时显示进度对话框的方法。
场景是这样的:用户添加了一些文本和图像,我需要调整它们的大小,直到它们适合可用的视图空间。这都是在我的自定义视图的方法上完成的。
在我的案例中,使用线程和不确定进度对话框的最佳方法是什么?
我是否应该使用asynctask并在每次进行操作时调用它?使用简单的线程?我从来没有在视图中使用任何线程
答案 0 :(得分:1)
你基本上有两种选择。判断哪个是最好的并不容易。
AsyncTask
当然是一个选择。好的部分是它为您构建与UI的同步。它将您的计算结果从doInBackground()
(并发运行)传递给onPostExecute()
(在UI线程上运行),这样您就可以安全地执行计算并更新UI。它还允许您通过publisProgress()
/ onProgressUpdate()
方法对在UI线程上指示后台处理进度。
但是:AsyncTask的行为在API 1和API 17之间已经发生了两次变化。根据设备运行的Android版本,默认情况下,几个AsyncTasks可以并行运行。如果这对您很重要,您必须使用executeOnExecutor()
;此调用是针对API 11引入的,这意味着如果要在11之前支持API,则必须处理反射。
您的第二个选择是拥有一个明确的工作人员Thread
。这种方法的吸引力在于,您有一个专门的线程用于在您的应用中经常出现并需要在后台完成的任务。但是,您必须自己处理所有UI同步问题。如果你受到纪律处分,这并不困难。如果您的线程知道需要修改的View
个对象,它可以使用View.post()
,View.postDelayed()
等方法来调度具有对视图的引用并将被执行的代码片段在UI线程上。
无论您选择哪种方法,您都会面临两种影响。
Android会以后台优先级运行您的Thread
和AsyncTask
,如果它们是CPU密集型的话,如果不这样做,将会导致执行时间延长十倍调整它。有关详细讨论,请参阅my answer to AsyncTask, must it take such a performance penalty hit…?。
您需要注意异步任务中的View引用。因为用户按 Back 或者由于配置更改而重新创建了Activity,所以View不再存在。设备旋转。这意味着你经常通过非常快速地离开并重新进入你的Activity来为用户提供启动许多线程的方法,添加越来越多的Threads来保存对View对象的引用,这些对象不再可见。如果你想要聪明并且你的计算需要很长时间,你可能(它真的取决于)想要将你的线程重新附加到新的Activity。如果你确保你的Thread以干净的方式结束并且如果你的Activity已经很久就会释放所有资源,那么现在可以安全地忽略它。