如何在长时间操作期间阻止UI?

时间:2012-10-02 15:29:28

标签: java android multithreading

我有一个按钮,当用户点击它时,它将更新整个UI(文本视图,图形)。 UI的内容来自SQLite数据库,我将更新函数命名为loading()。你可以想象,在loading()内部,有很多数据库操作和UI更新。 当数据大小变大时,此loading()的完成时间会更长,因此按钮将保持按下状态较长时间。

我尝试使用 asynctask 来处理这种情况,以便进行progressdialog而不是冻结按钮,但我不能将load()方法放在的doinbackground()上asynctask 因为doinbackground()无法触及从其活动的onCreate()方法声明的UI组件。

我不想重写loading()函数。

还有其他方法吗?请帮助,如果可以的话,请提供一些例子,我很感激。

5 个答案:

答案 0 :(得分:3)

如果您在主应用程序线程(a.k.a.,UI线程)上运行计时任务,您将无法响应用户界面并最终看到着名的Application Not Responding (ANR) dialog

推荐的方法是在AsyncTask中执行这些操作,并在publishProgress()中调用doInBackground()。将您的UI更新逻辑放在onProgressUpdate()的{​​{1}}中。致电AsyncTask后,{@ 1}}将在主应用程序主题上自动调用。

答案 1 :(得分:1)

为了在此实例中使用AsyncTask,您希望在doInBackGround()中加载数据,并使用结果填充某种数据结构或模型对象。然后作为doInBackground()的结果返回。

onPostExecute()确实在UI线程上运行,可以使用结果来填充和更新组件。

答案 2 :(得分:1)

我认为最佳选择是使用AsyncTask来完成这项工作。您可以从loadInBackground触发进度更新,以便在需要时进行一些UI更新(从任务后台线程调用publishProgress(),并在UI线程上调用方法onProgressUpdate()。)

其他选项:在单独的线程或后台服务中完成工作。然后,从您的UI,您可以使用处理程序每​​X毫秒触发一次刷新。

答案 3 :(得分:-1)

您可以使用runOnUiThread(Runnable)在UI线程上运行。您还可以使用ThreadHandler的组合。

答案 4 :(得分:-2)

我目前正在学习Handler,根据文档,它们是目前推荐的访问数据的方式,因为一方面,它们会为您进行异步加载。正如您所说,您无法从UI线程以外的其他线程访问UI组件。这意味着无论您使用Handler还是使用AsyncTask滚动自己的代码,都需要将更新UI的代码与加载数据的代码分开。