【问题标题】:Why Android thread gets terminated before it finishes to execute it?为什么Android线程在完成执行之前就被终止了?
【发布时间】:2012-10-08 22:24:17
【问题描述】:

我有一个线程可以从 Internet 获取一些数据。它表明它被正确执行并检索到数据。但是,如果我调用一个应该返回数据的方法,它会给我留下空值。由此我得出一个结论,即线程在结束之前不知何故停止了。

代码如下:

private class getHash extends AsyncTask<String, Void, String>{
    @Override
    protected String doInBackground(String... params) {
        String str = null;
        try {
            // Create a URL for the desired page
            URL url = new URL(params[0]);

            // Read all the text returned by the server
            InputStream is =  url.openStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader in = new BufferedReader(isr);
            str = in.readLine();
            is.close();
            isr.close();
            in.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        hash = str; //If I set a global variable here it gets passed without a hitch
        return str;
    }
    @Override
    protected void onPostExecute(String result) {
        hash = result; // If I comment the line above and live this one I left with a null
    }
}

编辑: 根据要求添加调用线程的代码:

            getHash hashThread =  new getHash();
            hashThread.execute(new String[] {"http://www.full.path/to/the/file.hash"});


            if(hash != null && !hash.equals(localHash)){
....

【问题讨论】:

  • "从那我得出一个结论,线程在结翅之前不知何故停止了。" -- 或者,你有一个例外。
  • 您如何检索该值以证明它确实在完成之前停止。
  • 没有@CommonsWare 我真的得出了一个结论,我没有看到任何例外。 GregGiacovelli 如果你可以将注意力集中在我给出的代码示例上。最后你会发现两行上面有一些解释性的 cmets。
  • 您能否发布更多代码,特别是围绕对这些方法的调用?我的猜测是时间问题,IE 你正在异步调用这个服务,但也许你试图在它完成之前得到结果?
  • 嗯,这不是这样的。 if (hash != null) ... 永远不应该像那样可靠地工作。它异步发生。因此,您对 execute() 的调用不会立即返回。事实上,它不能按照您想要的方式工作,因为您必须等待执行的任何方法完成,因为它是 UI 线程上的当前任务。结果只能在 UI 线程中的下一个事件上发布。您可以通过调用 hashThread.get() 来检索该哈希来阻止您的 UI 线程,但您可能会得到 ANR。通常 onPostExecute() 会在你的代码上调用一个函数来表示它已经完成。

标签: java android multithreading android-asynctask


【解决方案1】:

无论什么启动了 AsyncTask

{
 ....
 getHash hashThread =  new getHash(this);
 hashThread.execute(new String[] {"http://www.full.path/to/the/file.hash"});
 return; // ok now we just have to wait for it to finish ... can't read it until then
}

// Separate callback method
public void onHashComplete(String hash) {

   if(hash != null && !hash.equals(localHash)) {
      ....
   }
   ....
 }

现在在您的 GetHash 类中

public String doInBackground(String[] params) {
    .... // don't set hash here ... it will work but you will probably read it at the wrong time.
    return str;
}

public void onPostExecute(String str) {
    onHashComplete(str); // or just do all the work in here since it is a private inner class
}

....

希望这会有所帮助。请记住 doInBackground() 发生在 AsyncTask 线程上,onPostExecute() 在主线程上执行。任何称为execute() 的线程也应该是主线程。由于主线程的工作方式,您不能指望onPostCreate() 发生,直到它首先用于调用execute() 的任何回调完成。所以这就是我添加回报的原因。

【讨论】:

  • 感谢您解决这个问题。在阅读有关线程并匆忙进行开发时,我一定错过了那部分。
猜你喜欢
  • 1970-01-01
  • 2016-10-09
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-02
  • 2015-12-12
  • 1970-01-01
相关资源
最近更新 更多