【问题标题】:How to make activity UI changes from an Android AsyncTask?如何从 Android AsyncTask 更改活动 UI?
【发布时间】:2011-06-17 17:27:39
【问题描述】:

在我的 UI 将从单独的线程(使用 AsyncTask)更新的场景中,我可以将 AsyncTask 定义为 Activity 的内部类,但这有两个缺点,我发现有问题:

  1. 它使源文件非常大,降低了管理代码的效率
  2. 很难重用线程类

什么是好的解决方案?使用内部类,但将它所做的一切抽象到其他类?将对 Activity 的引用传递给 AsyncTask?总是将 AsyncTask 类定义为内部类,只接受源文件会很大吗?

【问题讨论】:

    标签: android oop android-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 子类更易于管理。
    猜你喜欢
    • 1970-01-01
    • 2013-08-06
    • 2018-09-10
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多