【问题标题】:Is chaining AsyncTasks considered bad practice? [duplicate]链接 AsyncTasks 是否被认为是不好的做法? [复制]
【发布时间】:2015-07-24 08:22:47
【问题描述】:
我正在编写一个执行以下操作的应用程序:
- 解析网页并从中提取图片网址
- 将它们解码为
Bitmap 并在ImageView 中显示它们
我不希望这些在 UI 线程上运行,显然如果没有完成第 1 点,就无法执行第 2 点。
我可以链接 AsyncTasks 来实现这个吗?我的意思是从第一个的 onPostExecute() 方法开始第二个。
这被认为是不好的做法吗?如果是这样,我该怎么做?
(这是一个理论问题,我不是要代码)
【问题讨论】:
标签:
java
android
multithreading
android-asynctask
【解决方案1】:
你绝对可以这样做,如果你真的需要,链接多个 AsyncTasks 并没有错。我想强调:只有当你真的需要时。
AsyncTasks 会带来一定的开销。如果你链接两个AsyncTasks,你会得到两倍的开销。你不想要那个。您应该尽可能少地使用AsyncTasks。
在您的情况下,解决方案实际上看起来很简单:只需一个 AsyncTask 即可完成所有工作。问问自己:真的需要两个独立的AsyncTasks吗?从你的描述来看,确实不像。如果您只使用一个AsyncTask,您的代码将比使用两个更有效地运行。
请注意,AsyncTasks 只能用于需要几秒钟且响应用户操作而启动的短操作。如果您需要在后台执行一些长时间运行的操作,那么AsyncTask 可能不是最好的解决方案。从您的描述中我无法真正判断您想要做的事情是否适合AsyncTask,但如果您所做的工作不符合我上面描述的标准,您可能会更好替代解决方案。
【解决方案2】:
我可以链接 AsyncTasks 来实现这个吗?我的意思是开始第二个
从第一个的 onPostExecute() 方法
唯一的限制是AsyncTask 必须在 UI 线程上实例化。只要您在 UI 线程上实例化它,您就应该是安全的。所以答案是肯定的,你可以做到。
如果是这样,我该怎么做?
解决同一个问题有不同的方法。例如,您可以使用 ExecutorService 和委托/侦听器、观察者或广播接收器来通知任务的完整性
【解决方案3】:
这个here 有一个很好的答案,但既然你在理论上问,我会在它的末尾标记一个意见。
来自 AsyncTask 文档:
AsyncTasks 最好用于短时间的操作(最多几秒钟)。如果您需要保持线程长时间运行,强烈建议您使用 java.util.concurrent 提供的各种 API Executor、ThreadPoolExecutor、FutureTask等包。
Futures(或 Promises)的链接是一种完全正常的异步实践。 Future A 做某事并返回一个值;然后这个值可以被另一个异步代码块使用,依此类推,形成一个逻辑处理链。
在伪代码中是这样的:
Future( calculate and return x).map( consume x and return y)
.map ( consume y and so on)
【解决方案4】:
当然可以。从理论上讲,你上面说的这个逻辑不会错。但是,您必须了解:onPreExecute 和onPostExecute 在主线程即 UI 线程上调用,而 doInBackground 在另一个非主线程上调用。同时,如果你在第一个的doInBackground 上执行了第二个AsyncTask,则第二个伤口的onPreExecute 和onPostExecute 不会在主线程上运行。请注意这一点。
【解决方案5】:
嗯,我不认为这是不好的做法。我能看到的唯一缺点是代码变得有点难以阅读,特别是如果你最终链接了很多回调。