如何让Asynctask以不同的方式更新UI

发布于 2024-11-01 15:16:56 字数 893 浏览 2 评论 0原文

这是我在使用 Asyntask 时经常遇到的问题。联系UI线程的方式是调用publishProgress() &此方法接受仅一种类型参数的数组。

在后台运行的执行复杂计算的线程可能需要使用不同类型的对象在不同点更新 UI。

让我用一个例子来说明:

...do some processing...
// Send UI thread the integer values of the width & height of the image 
...do some more processing...
// Send UI thread a String with custom message.
...do some more processing...
// Send UI thread an instance of MyObject so it can extract & display certain values 
...do some cleanup job & finish...

但是,onProgressUpdate() 只接受一种类型的数组。

那么我是否将其设为包罗万象的 Object 类型?我怎么知道如何向下转换它,因为这个方法可以从第 1、2 或 3 行调用,那么现在是哪个时间呢?

当然一定有一个好的方法来实现这一目标吗?

编辑:如果在 Android 中可能的话,我真正希望看到的是定义 publishProgress1(用户定义的 args1)publishProgress2(用户定义的 args2)< /em>, publishProgress3(用户定义的args3) ...

This is a problem that I keep running into often with using Asyntask. The way to contact the UI thread is to call publishProgress() & this method accepts an array of only one TYPE of parameter.

A thread running in the background doing complicated computations might need to update the UI at different points using different types of object.

Let me illustrate with an example:

...do some processing...
// Send UI thread the integer values of the width & height of the image 
...do some more processing...
// Send UI thread a String with custom message.
...do some more processing...
// Send UI thread an instance of MyObject so it can extract & display certain values 
...do some cleanup job & finish...

However, onProgressUpdate() accepts an array of only one type.

So do I make that an all encompassing Object type? How do I know how to downcast it since this method can be called from line 1, 2 or 3 so which time is it?

Surely there must be a good way to achieve this?

EDIT: What I'd really love to see, if it were possible in Android, would be some way of defining publishProgress1(user-defined args1), publishProgress2(user-defined args2), publishProgress3(user-defined args3) ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

怂人 2024-11-08 15:16:56

在你的第三种情况...

// 向 UI 线程发送 MyObject 的实例

...有一个参数表明您将在 onPostExecute() 中执行此操作,尽管这取决于您在插图中的含义。

您可以按照您的建议轻松地传递一个无所不包的对象。该对象可以具有各种字段(整数、字符串、对象)以及用于描述哪些字段有效且需要处理的“操作”。

您可以简单地传递一个 int 枚举,例如 PROCESS_INT_WIDTH_AND_HEIGHTPROCESS_STRING_MESSAGEPROCESS_OBJECT 等。没有什么可以阻止您这样做......

private static class MyAsyncTask extends AsyncTask<String, int, Void> {
    private int width;
    private int height;
    private String customMessage;
    private MyObject myObject;

    @Override
    protected Void doInBackground(String... params) {

        width = 10;
        height = 10;
        publishProgress(PROCESS_INT_WIDTH_AND_HEIGHT);
    }

    protected void onProgressUpdate(int... progress) {
        if (progress == PROCESS_INT_WIDTH_AND_HEIGHT)
            // Process width and height
    }
}

换句话说, onProgressUpdate() 方法只是响应“命令”并相应地处理相关的私有字段。

In your 3rd case...

// Send UI thread an instance of MyObject

...there's an argument to say you would do this in onPostExecute() although that depends on what you meant from your illustration.

You could easily do as you suggest in passing an all encompassing object. The object could have various fields (integer, string, object) plus an 'action' to take describing which of those fields are valid and need to be processed.

You could simply pass an int enum such as PROCESS_INT_WIDTH_AND_HEIGHT, PROCESS_STRING_MESSAGE, PROCESS_OBJECT etc. There's nothing to stop you doing this...

private static class MyAsyncTask extends AsyncTask<String, int, Void> {
    private int width;
    private int height;
    private String customMessage;
    private MyObject myObject;

    @Override
    protected Void doInBackground(String... params) {

        width = 10;
        height = 10;
        publishProgress(PROCESS_INT_WIDTH_AND_HEIGHT);
    }

    protected void onProgressUpdate(int... progress) {
        if (progress == PROCESS_INT_WIDTH_AND_HEIGHT)
            // Process width and height
    }
}

In other words, the onProgressUpdate() method simply responds to a 'command' and processes the relevant private fields accordingly.

白云不回头 2024-11-08 15:16:56

如果您想坚持使用 AsyncTask,另一个选择是使用不同的类在不同的时间,并使用instanceof测试类型。

然而,这听起来像是一个相对复杂的任务,所以我建议考虑使用 Handler 并从常规发布 [Runnable]s2 线程,或使用 runOnUiThread

您可能还想阅读 Painless Threading

希望这会有所帮助,

Phil Lello

If you want to stick with AsyncTask, another option is use a different class at different times, and test the type with instanceof.

However, this sounds like a relatively complex task, so I'd suggest looking at using Handler and posting it [Runnable]s2 from a regular Thread, or using runOnUiThread.

You might also want to read Painless Threading

Hope this helps,

Phil Lello

欲拥i 2024-11-08 15:16:56

我认为没有其他方法可以做到这一点。使用 getType 方法创建一个基类,然后使用它作为您的类型进行适当的转换。

I don't think there is any other way of doing this. Create a base class with a getType method and then use this as your type for appropriate casting.

偷得浮生 2024-11-08 15:16:56

泛型类型在这种情况下可以工作吗?您可以根据需要对值进行类型转换。示例 AsyncTask 原型:

new AsyncTask<String, Object, List<?>>(){ 
...

我还记得读到过 AsyncTask 最适合短任务。考虑用于复杂且长时间运行的操作的其他线程模型。

Would a generic type work in this scenario? You could typecast the values as needed. Example AsyncTask prototype:

new AsyncTask<String, Object, List<?>>(){ 
...

I also recall reading that AsyncTask is most suited only for short tasks. Consider the other thread models for complex and long-running operations.

娇纵 2024-11-08 15:16:56

如果您返回的值在 AsyncTask 处理中具有相应的状态,您可以在 AsyncTask 内为您需要的每个数据/类型创建一个私有成员,然后分配一个将整数赋给每个状态,并在 onProgressUpdate(Integer...) 中放置一个 switch(state),该开关根据从 publishProgress(州)

(这可能不是我给出的最明确的答案)

If the values you're returning have a corresponding state in the AsyncTask processing, you could create a private member inside the AsyncTask for each datum/type you need, then assign an integer to each state and in onProgressUpdate(Integer...) put a switch(state) that does the job based on the int state it gets from publishProgress(state).

(this might not be the clearest answer I gave)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文