1

执行以下代码时,用户的手机出现错误,我正在检查用户当前是否正在通话,然后再运行AsyncTaskWeb 服务调用。我这样做的原因是因为有些人在通话时失去了互联网连接,所以我每 5 秒检查一次,看看他们是否在通话。如果不是,则调用 AsyncTask

do{
        Handler handler = new Handler();
        handler.postDelayed(new Runnable(){

            @Override
            public void run() {

                 onCall = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
                        .getCallState() != TelephonyManager.CALL_STATE_IDLE;
                 if(!onCall){
                     new CallRegWS().execute();
                 }  
            }
        },5000);
    }while(onCall);

我没有完整的堆栈跟踪,只有这向我显示了错误

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

显然不是太有帮助,但这就是我所要做的。他们不断收到该错误,因此它必须在我创建处理程序时发生。

所有这一切都是在main thread所以我不知道问题是什么,关于如何解决这个问题的任何见解?

更新 这是从服务调用的,并且该方法位于单独的类中

4

3 回答 3

7

尝试Handler handler = new Handler(Looper.getMainLooper());

另外,请参阅有关此错误的帖子:http: //levinotik.com/loopers-handlers-runtimeexceptions-explained/

于 2012-06-14T20:29:01.300 回答
2

首先,您必须知道,处理程序会自动附加到文档中指定的创建线程:

处理程序类概述

Handler 允许您发送和处理与线程的 MessageQueue 关联的 Message 和 Runnable 对象。每个 Handler 实例都与单个线程和该线程的消息队列相关联。当您创建一个新的处理程序时,它会绑定到创建它的线程的线程/消息队列——从那时起,它会将消息和可运行对象传递到该消息队列并在它们从消息中出来时执行它们队列。处理程序 | 安卓开发者

现在,考虑到这一点,并且由于当前线程没有消息队列,为了正常工作,线程需要一个实际的“队列”,这正是系统通过调用 Looper.prepare 告诉你要做的事情() 您正在创建的线程中创建消息循环器,因为默认情况下线程没有文档中提到的消息循环器:

Looper 类概述

用于为线程运行消息循环的类。默认情况下,线程没有与之关联的消息循环;要创建一个,请在要运行循环的线程中调用 prepare(),然后 loop() 让它处理消息,直到循环停止。活套 | 安卓开发者

换句话说,以简单的方式,主 UI 确实已经准备好消息队列,这就是为什么在“onCreate、onStart、onResume 等...”中调用 new Handler() 时看不到该错误的原因,但是对于创建的任何工作线程,系统需要一个队列来在使用处理程序时将消息发送到,尽管代码没有显示它,但我敢打赌,代码正在工作线程中执行,无论是普通线程还是 AsyncTask 的 doInBackground 方法,这就是是什么导致了错误,为了避免它记得总是在从工作线程创建处理程序之前调用 Looper.prepare。

希望这可以帮助。

问候!

于 2013-03-18T23:11:17.650 回答
1

你怎么知道这是在主线程上运行的?何时何地调用它?不要在使用之前创建处理程序,而是在 Activity 或 Service 的 onCreate 方法中创建它(取决于它是什么)。然后在你的 onDestroy 中将值设为空。

于 2012-06-14T20:17:47.513 回答