在我的AsyncTask
上工作我想知道为什么我应该使用onPostExecute()
的参数,当我可以在AsyncTask
类中使用类级别实例变量来共享{ {1}}和doInBackground()
。
两者都有效,但是每种方法都有专业人士和对手吗?
编辑:当我说'实例变量'时,我在谈论onPostExecute()
扩展类中的私有实例变量。当类死亡时,实例变量也会消失。
答案 0 :(得分:5)
好吧,它可能会降低内存泄漏的可能性,因为你没有在类级别持有对象的引用,只有那些AsyncTask方法。
它还将消除同步问题,如@nico_ekito所述
答案 1 :(得分:1)
我发现在AsyncTask中使用实例变量不是线程安全的。在我的例子中,如果我在doInBackground()中捕获和Exception,我会将它设置为我的AsyncTask的Exception实例变量。然后我在onPostExecute()中检查变量是否为null(我没有取消()因为我可能想在用户的例外中显示一条消息)。
无论如何,我不时会记录我在doInBackground中捕获了一个Exception,但是在onPostExecute中,实例变量将为null。文档确实说这些方法是同步调用的,所以我无法解释为什么会发生这种情况,但我看到它发生了好几次。
最后,我更改了我的“Result”类,以包含一个异常和我想传递给onPostExecute的原始结果。这很好用。
答案 2 :(得分:0)
以及发布的其他原因;如果在doInBackground()
中出现异常,您只需将表示错误的参数传递给onPostExecute()
并取消任何其他工作,而不是在您意识到所有变量都有没有得到适当的实例化。
答案 3 :(得分:0)
请允许我对接受的答案(和其他人)表示异议。
在使用AsyncTask中的实例字段将值从一个回调传递到另一个回调时,绝对没有线程安全问题。通常这意味着将值从doInBackground()
传递到onPostExecute()
。 AsyncTask中的回调保证永远不会同时执行,因此没有竞争条件,实例字段也无法丢失,如果在先前执行的回调中设置了null,则无效。现在回答。
onPostExecute()
参数的优点:
doInBackground()
的返回值,可确保doInBackground()
在返回时必须提供值,确保永远不会忘记doInBackground()
与以下回调之间明确建立的关系:onPostExecute()
和onCancelled()
,实例字段可用于多种可能目的 onPostExecute()
参数的缺点:
Pair
使用实例字段将值从doInBackground()
传递到onPostExecute()
的优缺点基本上与上述完全相反。