【问题标题】:What is a good way to interrupt an AsyncTask if it clearly isn't finishing execution?如果显然没有完成执行,那么中断 AsyncTask 的好方法是什么?
【发布时间】:2014-06-19 16:08:24
【问题描述】:

我有一个AsyncTask,我用它来创建一个Socket 连接。在我的doInBackground() 方法中,我有:

Socket socket = new Socket(HOST_NAME, PORT_NUMBER);

就我而言,当我尝试通过蜂窝网络连接时,这行代码会挂起。它永远不会完成执行,最终应用程序崩溃。因为来自Server 的信息对我来说是必要的,所以我做了这样的事情:

AttemptConnection attemptConnection = new AttemptConnection(); // this is the AsyncTask
attemptConnection.execute().get();

现在我意识到这很糟糕,因为AsyncTask 的目的是与主线程并行运行,这会暂停主线程上的处理。但是,在获取来自服务器的信息之前,我的应用程序无法真正去任何地方,所以我有点需要这个 AsyncTask 来完成。

由于Socket 连接失败并挂起一些时间,在某些情况下这会导致我的设备冻结并最终导致我的应用程序崩溃。所以我想要更好的东西。我想出的解决方案是:

attemptConnection.execute();
try {
    Thread.sleep(3000);
} catch (Exception e) {
}
attemptConnection.cancel(); 

但我想知道这是否更好?我无法在内部取消该过程,因为永远无法到达应该捕获Socket 连接错误的try / catch。代码挂在那里,没有发现任何错误。但是上面的想法似乎也是一种非常老套的方法。我想知道这种方法是否像我的直觉告诉我的那样糟糕,如果是,有什么更好的方法来处理这个问题?

【问题讨论】:

    标签: android multithreading sockets android-asynctask


    【解决方案1】:

    通常,您必须对 ASyncTask 进行编码,使其不能无限期挂起。

    在您的特定情况下,您可以通过在创建 Socket 时指定超时(也许是几秒钟)来实现这一点。如果无法在合理的时间内建立 Socket 连接,这将强制引发异常。有关如何执行此操作的指导,请参阅 Setting a timeout for socket operations

    当然,无论连接成功还是失败,你都不应该阻塞你的主线程等待结果。您应该通过通常的方式从 doInBackground() 返回结果,从 ASyncTask 发送结果。

    【讨论】:

    • 我想知道,我知道这是不好的做法,但是由于 AsyncTask 无论如何都在我的主线程的末尾,并且所有需要做的就是 Socket 的东西,它仍然是不好的做法如果我基本上知道 AsyncTask 的运行时间不可能超过几秒钟,那么用这个超时设置阻止主线程的执行?有更好的选择吗?
    • 是的,这仍然是不好的做法。事实上,真正可怕的做法。您无法知道它位于主线程的“末尾”;系统可以随时调用您应用的生命周期方法。更好的选择是让后台任务通过适当的机制与主线程通信,在这种情况下是从doInBackground()返回结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 2010-11-04
    • 2019-02-23
    相关资源
    最近更新 更多