如何从 Android AsyncTask 更改活动 UI?
Posted
技术标签:
【中文标题】如何从 Android AsyncTask 更改活动 UI?【英文标题】:How to make activity UI changes from an Android AsyncTask? 【发布时间】:2011-06-17 17:27:39 【问题描述】:在我的 UI 将从单独的线程(使用 AsyncTask)更新的场景中,我可以将 AsyncTask 定义为 Activity 的内部类,但这有两个缺点,我发现有问题:
-
它使源文件非常大,降低了管理代码的效率
很难重用线程类
什么是好的解决方案?使用内部类,但将它所做的一切抽象到其他类?将对 Activity 的引用传递给 AsyncTask?总是将 AsyncTask 类定义为内部类,只接受源文件会很大吗?
【问题讨论】:
【参考方案1】:首先:当使用AsyncTask
时,您不得在doInBackground()
内进行 UI 活动。
你可以做的是 - 如果你想,例如长时间运行的后台作业的更新状态是从 doInBackground() 到 publishProgress(values)
。
然后,运行时将针对这些值调用您的 onProgressUpdate(values)
回调,该回调在 UI 线程中运行,您可以从中更新 UI。
看看例如https://github.com/pilhuhn/ZwitscherA/blob/master/src/de/bsd/zwitscher/TweetListActivity.java#L336 看例子。
AsyncTask 可以在自己的类文件中实现。
【讨论】:
doInBackground() 方法无法访问 UI,如果尝试,框架会抛出异常。但我的问题更多地与 AsyncTask 子类实际访问 UI 的方式有关。 @Olli 这就是我所说的:doInBackgrround() 不能访问 UI。在 onPre|PostExecute() 之前或之后执行此操作,或者通过发布进度在两者之间执行。允许这三个回调方法访问 UI【参考方案2】:我见过的很多例子只是将Context
传递给AsyncTask
的构造函数。
public class BackgroundStuff extends AsyncTask<Void, Void, Void>
...
Context mContext;
...
BackgroundStuff(Context context)
super();
this.mContext = context;
...
我很想知道是否有其他人使用任何其他方法。
【讨论】:
给类传递上下文是我目前所做的,看起来比较乱,但也许没有更好的方法。【参考方案3】:我对 AsyncTasks 的 POV 有点奇怪,因为我通常更喜欢使用普通线程,但本质上我执行后台任务和更新 UI 的方式是在 onCreate() 方法的末尾创建一个处理程序,然后我会覆盖handleMessage(Message msg) 方法。
然后在我的线程中,我会将 Handler 作为参数传入,然后当我希望进行更新时,我会从线程向 Handler 发送消息,现在它的作用是从新背景进行通信线程到 UI 线程来处理 UI 上的工作。
现在我想 AsyncTasks 执行类似的任务,但不需要实现覆盖处理程序的 handleMessage 方法。
更多地了解这两种方法之间的任何优点/缺点会很有趣。
【讨论】:
我最初使用了 Handler,但我只是没有适应它,尽管这完全是主观的看法。我喜欢 AsyncTask 的清晰性,我通常将它们分解为单独的类(而不是内部类),这有助于我使用它,并使 Activity 子类更易于管理。以上是关于如何从 Android AsyncTask 更改活动 UI?的主要内容,如果未能解决你的问题,请参考以下文章
在 Android 的 AsyncTask 期间更改活动是不是被认为是不好的做法?
如何从 android 中的 AsyncTask 获取 UI 参考