2

我知道有人在 AsyncTask 中使用 runOnUiThread 听起来很疯狂。不知何故,它对我有用,但我想知道它是否是一种可接受且稳健的方法。这是场景:

我有一个应用程序,在成功登录后,用户被呈现到下一个屏幕。在这个新屏幕中,3 种不同的方法从 Web 服务器加载不同类型的数据。这些方法是:

  • getMembersForList():它加载社区成员列表并将其显示在列表视图中。

  • getProfileData():它加载登录用户的个人资料并在屏幕上显示他的姓名、图像等。

  • getNotificationCounts:它为用户加载新通知的计数。

我为此应用了 3 种不同的方法:

(1)在 onCreate 中简单地调用所有 3 个方法,即没有独占线程用于任何方法。在这种情况下,从登录屏幕到此屏幕的转换变得非常缓慢,并且在此活动出现之前会出现一段时间的黑屏。

(2)在 UI 线程上调用 getMembersForList(),在独占线程上调用其他 2 个方法。在这种情况下,转换变得快速并且列表快速显示,但通知计数和用户名等不会显示,因为发生 WrongThreadException 表示该线程无法触及其他线程的视图(用户名的 TextViews、通知计数等,它们是全局声明的) . 当我从 AsyncTask 启动这些线程时也会发生同样的事情。

(3)在 UI 线程上调用 getMembersForList(),然后在 doInBackground() 方法内的“runOnUiThread”中调用其他 2 个方法的 AsyncTask。这解决了上述两个问题。现在屏幕转换更快了,也没有出现 WrongThread 异常。

到目前为止,方法-(3)对我来说效果很好,但我不确定这是否是正确的方法,因为 runOnUiThread 和 AsyncTask 是两个完全相反的东西。谁能消除我对这种情况的怀疑。提前谢谢。

4

2 回答 2

2

我建议在 asyncTask 中运行所有 3 个调用,并在后台任务完成后更新 AsyncTask 的 postExecute() 中的 UI,postExecute 在 UIthread 上运行,因此您无需调用任何显式的内容即可在 UIthread 上运行它们。

于 2012-09-07T11:09:59.640 回答
2

runOnUiThread()是的,像这样的用例是该方法首先存在的一个重要原因。这个想法是你允许你的后台线程/AsyncTask实例在后台运行你的冗长操作,然后提供一个简单的钩子,当他们有结果时(或以任意间隔,随着结果的不同部分变得可用)。

只要这就是您正在做的事情,那么您的使用就可以了。您要避免做的是在主线程上执行冗长的操作,直接或间接地通过从后台线程传入一些冗长的操作。

当然,如果您不想这样做,则不必这样做。你可以postExecute()改用。或者您可以将结果存储在某处,然后使用任何类型的消息传递 API 来通知主线程结果已准备好,依此类推。

于 2012-09-07T11:13:17.967 回答