V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
XhstormR
V2EX  ›  Android

请问 AsyncTask 中的 cancel(true) 和 cancel(false) 的区别体现在哪里?

  •  
  •   XhstormR · 2016-10-02 16:44:08 +08:00 · 10795 次点击
    这是一个创建于 3003 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我自己写了个测试,在执行 cancel(true) 和 cancel(false) 后:

    • 都不会调用 onPostExecute ,而会调用 onCancelled 。
    • 在 doInBackground 方法中调用 isCancel 都会返回 true 。

    那么区别体现在哪里呢?

    12 条回复    2016-10-03 18:03:04 +08:00
    zhaohui318
        1
    zhaohui318  
       2016-10-02 17:39:47 +08:00
    https://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)

    boolean cancel (boolean mayInterruptIfRunning)

    mayInterruptIfRunning : true if the thread executing this task should be interrupted; otherwise, in-progress tasks are allowed to complete.
    XhstormR
        2
    XhstormR  
    OP
       2016-10-02 17:55:01 +08:00
    @zhaohui318
    这个文档我看了,他的意思是在 doInBackground 中通过 isCancel 来判断我传入的 mayInterruptIfRunning 值。

    但是 cancel(true) 和 cancel(false) 的 isCancel 都返回 true ,我找不出他们的区别。
    iyeatse
        3
    iyeatse  
       2016-10-02 17:55:35 +08:00
    mayInterruptIfRunning 为 true 时会调用 Thread.interrupt() 方法
    iyeatse
        4
    iyeatse  
       2016-10-02 17:57:19 +08:00   ❤️ 1
    http://blog.danlew.net/2014/06/21/the-hidden-pitfalls-of-asynctask/

    > As for mayInterruptIfRunning – all it does is send an interrupt() to the running Thread. In the case that your Thread is uninterruptible, then it won ’ t stop the Thread at all.
    kaedea
        5
    kaedea  
       2016-10-02 18:30:24 +08:00
    突然也想不清楚了,看了一下笔记:

    AsyncTask 的 cancel 方法需要一个布尔值的参数,参数名为 mayInterruptIfRunning,意思是如果正在执行是否可以打断,如果这个值设置为 true ,表示这个任务可以被打断,否则,正在执行的程序会继续执行直到完成。如果在 doInBackground()方法中有一个循环操作,我们应该在循环中使用 isCancelled()来判断,如果返回为 true ,我们应该避免执行后续无用的循环操作。

    也就是说,如果你没做好 isCancelled()判断的话,你的 doInBackground()就无法被取消了,哪怕你调用了 AysncTask.cancel(true)!这又是一个陷阱。
    XhstormR
        6
    XhstormR  
    OP
       2016-10-02 20:08:46 +08:00
    @kaedea
    无论是 cancel(true),还是 cancel(false),调用之后 isCancelled() 都返回 true 。

    所以 cancel 的这个 mayInterruptIfRunning 参数,说实话我是感觉没啥区别。
    ilumer
        7
    ilumer  
       2016-10-03 00:41:25 +08:00
    弱弱的说一句会不会是你调用了 cancel 这个方法以后你的 iscancel 都会返回 true 。因为 cancel 方法中的 mCancelled.set(true);默认都是 set(ture)。同时 iscancelled 又是返回 mCancelled.get().都会返回相同的结果吧。
    true 或者 false 的具体不同应该是影响的 cancel 方法的返回值以及线程的是否线程是否中断。
    ddou
        8
    ddou  
       2016-10-03 08:04:04 +08:00 via Android
    不做 android 开发,但是看文档应该是: true 的情况下,就算任务已经在执行,也会被打断,彻底取消任务。 false 时只能取消等待执行的任务,已经开始的任务不受影响。
    kaedea
        9
    kaedea  
       2016-10-03 16:40:14 +08:00
    @XhstormR cancel(false)是无法打断已经开始运行的任务了
    XhstormR
        10
    XhstormR  
    OP
       2016-10-03 17:08:38 +08:00
    @kaedea 无论 true or false ,都无法中断正在执行中的 doInBackground 方法。

    我的例子是在 doInBackground 方法中循环 10 次 +1 ,都正常执行完毕了。
    kaedea
        11
    kaedea  
       2016-10-03 17:26:36 +08:00
    @XhstormR 你需要在循环体内做 isCancelled 判断
    AsyncTask 说白了就是 Executor + Handler
    XhstormR
        12
    XhstormR  
    OP
       2016-10-03 18:03:04 +08:00
    @kaedea 嗯,这个我知道,就是纠结 cancel(false) 和 cancel(true)。

    算了,本来就没多大问题,就不纠结了,就都写 cancel(true)。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   893 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 22:20 · PVG 06:20 · LAX 14:20 · JFK 17:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.