我知道有人在AsyncTask中使用runOnUiThread听起来很疯狂。不知何故,它对我有用,但我想知道它是否是一种可接受且稳健的方法。这是场景:
我有一个应用程序,在成功登录后,用户将呈现到下一个屏幕。在这个新屏幕中,有3种不同的方法从Web服务器加载不同类型的数据。这些方法是:
getMembersForList():它会加载社区成员列表并在列表视图中显示。
getProfileData():它会加载登录用户的个人资料,并在屏幕上显示他的姓名,图片等。
我为它应用了3种不同的方法:
(1)简单地在onCreate中调用所有3种方法,即任何方法都没有使用独占线程。在这种情况下,从登录屏幕到此屏幕的转换变得非常缓慢,并且在此活动出现之前黑屏会显示一段时间。
(2)在UI线程上调用getMembersForList(),在独占线程上调用其他2个方法。在这种情况下,转换变得很快并且列表快速显示,但通知计数和用户名等不会显示,因为发生WrongThreadException表示此线程无法触及其他线程的视图(TextViews用于全局声明的用户名,通知计数等) )。当我从AsyncTask启动这些线程时也会发生同样的事情。
(3)在UI线程上调用getMembersForList()然后启动AsyncTask,其中在doInBackground()方法中的“runOnUiThread”中调用其他2个方法。这解决了上述两个问题。现在屏幕转换速度更快,并且WrongThread异常也没有发生。
到目前为止,方法 - (3)对我有用,但我不确定这是否是正确的方法,因为runOnUiThread和AsyncTask完全相反。任何人都可以清楚我对这种情况的疑虑。提前完成。
答案 0 :(得分:2)
我建议在asyncTask中运行所有3个调用,并在后台创建完成后更新AsyncTask的postExecute()中的UI,postExecute在UIthread上运行,这样你就不需要调用任何明确的东西来运行它们UIthread。
答案 1 :(得分:2)
是的,像这样的用例是runOnUiThread()
方法首先存在的一个重要原因。这个想法是允许你的后台线程/ AsyncTask
实例在后台运行你的冗长操作,然后提供一个简单的钩子,当它们有结果时它们可以用来更新界面(或以任意间隔,因为结果的不同部分变得可用)。
只要这就是你正在做的事情,那么你的用法就好了。你想要避免做的是在主线程上执行冗长的操作,直接或间接地通过从后台线程传递一些冗长的操作。
当然,如果你不愿意,你不必这样做。您可以使用postExecute()
代替。或者您可以将结果存储在某处,然后使用任何类型的消息传递API来通知主线程结果已准备好,依此类推。