Android:Thread.sleep 没有结束

Posted

技术标签:

【中文标题】Android:Thread.sleep 没有结束【英文标题】:Android: Thread.sleep doesn't end 【发布时间】:2012-09-20 02:20:10 【问题描述】:

我有一个带有 httprequest 的应用程序。我想为该请求设置一个超时,并且由于我无法控制 de DNS 超时,*** 中的用户建议创建一个带有计时器的线程,以便在一定时间后取消请求,这就是我正在做的事情。

在我的新线程中,我使用 Thread.sleep 等待 30 秒,当该时间结束时,如果请求尚未结束,则取消请求,但我的线程永远不会唤醒。这是我的代码:

private Thread timeout_request = new Thread(new Runnable() 
    public void run() 
        try
            Log.d(TAG, "Thread start");
            Thread.sleep(30000);
            Log.d(TAG, "Thread awake");
            if(!httprequest_finished)
                request_aborted = true;
                mHttpClient.getConnectionManager().shutdown();
            
        catch(Exception e)
            e.printStackTrace();
        
    
);

public String sendData(String token)
    ...
    timeout_request.start();
    Log.i(TAG, "Sending request");
    final HttpResponse resp = httpClient.execute(post);
    Log.i(TAG, "Execute finished");
    if(request_aborted) return null;
    httprequest_finished = true;
    ...

如果我在没有互联网连接的情况下执行 sendData 函数,日志会显示“发送请求”和“线程启动”,但不会显示“线程唤醒”或“执行完成”(我已经等了 5 分钟)。这是为什么呢?

----- 编辑 ------

顺便说一句,我不知道这是否重要,但我在连接中使用了 ThreadSafeClientConnManager。

我已经测试了一些东西:

1- 将 HttpResponse resp = httpClient.execute(post) 替换为 while(!request_aborted)。线程唤醒(它工作)。

2- 使用 mHandler.postDelayed(r, 30000) 而不是线程。我仍在执行 httpClient.execute(post)。结果:Runnable 没有启动。

private Handler mHandler = new Handler();
private Runnable r = new Runnable() 
    public void run() 
        Log.d(TAG, "Runnable()");
        if(!httprequest_finished)
            request_aborted = true;
            mHttpClient.getConnectionManager().shutdown();
        
    
;

3- 使用 mHandler.postDelayed(r, 30000) 而不是线程。将 HttpResponse resp = httpClient.execute(post) 替换为 while(!request_aborted)。结果:Runnable 没有启动。

所以如果我不执行 http 请求,线程就可以工作,但处理程序永远不会工作。我在日志中注意到以下几行:

threadid=3: reacting to signal 3
Wrote stack traces to '/data/anr/traces.txt'
threadid=3: reacting to signal 3
Wrote stack traces to '/data/anr/traces.txt'

这在执行线程或设置处理程序后 6 或 7 秒出现。我试过用:

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() 
        public void uncaughtException(Thread paramThread, Throwable paramThrowable) 
            Log.e("Alert","Lets See if it Works !!!");
        
    );

但是日志从不显示“让我们看看它是否有效!!!”。我查看了 traces.txt 文件,但我不明白它在说什么-.-

【问题讨论】:

不能使用:"HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 10000); //超时限制" 这不适用于 DNS 解析。 ***.com/questions/12627001/… 【参考方案1】:

我已经测试了以下代码:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication1;

/**
 *
 * @author paro
 */
public class JavaApplication1 

    public boolean req_aborted = false;
    public Thread timeout_request = new Thread(new Runnable() 
    public void run() 
        try
            System.out.println("start");
            Thread.sleep(30000);
            System.out.println("awake");
            if(req_aborted ==false)
            
                req_aborted = true;
                System.out.println("flag change");
            
        catch(Exception e)
            e.printStackTrace();
        
    
);
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) 
        // TODO code application logic here
        JavaApplication1 jap = new JavaApplication1();
        jap.timeout_request.start();
        System.out.println("requset started");
        if(jap.req_aborted)
        
            System.out.println("flag is true now");
        
    

输出是

requset started
start
awake
flag change

您的代码中与线程相关的部分似乎没有问题。

并且您的代码逻辑表明它应该打印“唤醒”。看来你对下面的说法有问题

final HttpResponse resp = httpClient.execute(post);

【讨论】:

我唯一能想到的就是请求(httpClient.execute(post))使用了所有的CPU并且我的线程没有被执行,但这意味着android的设计真的很糟糕(除非有一个选项可以改变它)。 我认为 POST 请求不太可能耗尽所有 CPU,但也许这只是我,Android HHTP 确实很糟糕。 是的,我觉得这不太可能......我会继续尝试。【参考方案2】:

我认为您应该使用Handler.postDelayed,而不是使用Thread.sleep。看看documentation。

类似:

Handler mHandler = new Handler();
...
mhandler.postDelayed(new Runnable() 
    public void run() 
        if(!httprequest_finished)
            request_aborted = true;
            mHttpClient.getConnectionManager().shutdown();
        
    
, 30000);

这将在指定延迟后执行传入的Runnable

【讨论】:

以上是关于Android:Thread.sleep 没有结束的主要内容,如果未能解决你的问题,请参考以下文章

java Thread.sleep卡死问题

Thread.sleep 不会使我的应用程序崩溃[关闭]

当我进行异步调用时,是不是有必要在 iOS 和 Android 的 while 循环中使用 Thread.Sleep(1)?

Thread.sleep() 和 GUI

Thread.sleep 没有抛出 InterruptedException

Thread.sleep(x) 没有做它必须做的事情[重复]