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

时间:2011-04-14 20:53:22

标签: android design-patterns

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

在后台运行执行复杂计算的线程可能需要使用 不同类型 对象在不同点更新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) publishProgress3(用户定义的args3) ......

5 个答案:

答案 0 :(得分:4)

在你的第三种情况下......

  

//向UI线程发送MyObject实例

...有一个论点要说你会在onPostExecute()中这样做,尽管这取决于你在插图中的含义。

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

你可以简单地传递一个整数,例如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()方法只响应“命令”并相应地处理相关的私有字段。

答案 1 :(得分:2)

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

然而,这听起来像是一项相对复杂的任务,因此我建议您使用Handler并从常规2发布[Runnable] s Thread或使用{ {3}}

您可能还想阅读runOnUiThread

希望这有帮助,

Phil Lello

答案 2 :(得分:0)

我认为没有其他办法可以做到这一点。使用getType方法创建基类,然后将其用作适当强制转换的类型。

答案 3 :(得分:0)

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

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

我还记得读到AsyncTask最适合短期任务。考虑复杂和长期运行的其他线程模型。

答案 4 :(得分:0)

如果您返回的值在AsyncTask处理中具有相应的状态,您可以在AsyncTask内为您需要的每个数据/类型创建一个私有成员,然后为每个数据/类型分配一个整数state onProgressUpdate(Integer...)根据switch(state)获取的int状态放置publishProgress(state)作业。

(这可能不是我给出的最清晰的答案)