我有一个按钮,当用户点击它时,它将更新整个UI(文本视图,图形)。 UI的内容来自SQLite数据库,我将更新函数命名为loading()。你可以想象,在loading()内部,有很多数据库操作和UI更新。 当数据大小变大时,此loading()的完成时间会更长,因此按钮将保持按下状态较长时间。
我尝试使用 asynctask 来处理这种情况,以便进行progressdialog而不是冻结按钮,但我不能将load()方法放在的doinbackground()上asynctask 因为doinbackground()无法触及从其活动的onCreate()方法声明的UI组件。
我不想重写loading()函数。
还有其他方法吗?请帮助,如果可以的话,请提供一些例子,我很感激。
答案 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线程上运行。您还可以使用Thread
和Handler
的组合。
答案 4 :(得分:-2)
我目前正在学习Handler
,根据文档,它们是目前推荐的访问数据的方式,因为一方面,它们会为您进行异步加载。正如您所说,您无法从UI线程以外的其他线程访问UI组件。这意味着无论您使用Handler
还是使用AsyncTask
滚动自己的代码,都需要将更新UI的代码与加载数据的代码分开。