如何从 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 期间更改活动是不是被认为是不好的做法?

替换现有项目中的 Asynctask 无需太多代码更改

如何从android中的AsyncTask类中获取数据?

如何从 android 中的 AsyncTask 获取 UI 参考

如何使用 asynctask 将图像从 android 上传到 php

如何将变量从 AsyncTask 返回到 Android 中的 Google Map 活动