如何让Asynctask以不同的方式更新UI
这是我在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在你的第三种情况...
...有一个参数表明您将在 onPostExecute() 中执行此操作,尽管这取决于您在插图中的含义。
您可以按照您的建议轻松地传递一个无所不包的对象。该对象可以具有各种字段(整数、字符串、对象)以及用于描述哪些字段有效且需要处理的“操作”。
您可以简单地传递一个 int 枚举,例如
PROCESS_INT_WIDTH_AND_HEIGHT
、PROCESS_STRING_MESSAGE
、PROCESS_OBJECT
等。没有什么可以阻止您这样做......换句话说, onProgressUpdate() 方法只是响应“命令”并相应地处理相关的私有字段。
In your 3rd case...
...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...In other words, the onProgressUpdate() method simply responds to a 'command' and processes the relevant private fields accordingly.
如果您想坚持使用 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
我认为没有其他方法可以做到这一点。使用 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.
泛型类型在这种情况下可以工作吗?您可以根据需要对值进行类型转换。示例
AsyncTask
原型:我还记得读到过
AsyncTask
最适合短任务。考虑用于复杂且长时间运行的操作的其他线程模型。Would a generic type work in this scenario? You could typecast the values as needed. Example
AsyncTask
prototype:I also recall reading that
AsyncTask
is most suited only for short tasks. Consider the other thread models for complex and long-running operations.如果您返回的值在
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 theAsyncTask
for each datum/type you need, then assign an integer to each state and inonProgressUpdate(Integer...)
put aswitch(state)
that does the job based on the int state it gets frompublishProgress(state)
.(this might not be the clearest answer I gave)