执行下面的代码时,用户在手机上收到错误,我在运行AsyncTask
进行Web服务调用之前,正在检查用户当前是否正在通话。我这样做的原因是因为有些人在通话时丢失了互联网连接,所以我每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
完成的,所以我不知道问题是什么,对如何解决这个问题的任何见解?
更新 这是从服务调用的,方法是在一个单独的类
中答案 0 :(得分:7)
尝试Handler handler = new Handler(Looper.getMainLooper());
此外,请参阅有关此错误的帖子:http://levinotik.com/loopers-handlers-runtimeexceptions-explained/
答案 1 :(得分:2)
首先,您必须知道,处理程序会自动附加到文档中指定的创建的线程:
处理程序类概述
Handler允许您发送和处理与线程的MessageQueue关联的Message和Runnable对象。每个Handler实例都与一个线程和该线程的消息队列相关联。当您创建一个新的Handler时,它被绑定到正在创建它的线程的线程/消息队列 - 从那时起,它将消息和runnables传递给该消息队列并在消息出来时执行它们队列。 Handler | Android Developers
现在,在计算时,由于当前线程没有消息队列,为了正常工作,线程需要一个实际的" Queue",而这正是系统告诉你做什么,通过调用Looper.prepare()你在你创建的线程中创建一个Message Looper,因为默认情况下Threads没有文档中提到的Message looper:
Looper课程概述
用于为线程运行消息循环的类。默认情况下,线程没有与之关联的消息循环;创建一个,在运行循环的线程中调用prepare(),然后循环()让它处理消息,直到循环停止。 Looper | Android Developers
换句话说,以简单的方式,主UI已经准备好了一个消息队列,这就是为什么你在"中调用新的Handler()时没有看到错误的原因。 onCreate,onStart,onResume等...",但对于创建的任何工作线程,系统需要一个队列来在使用处理程序时发送消息,虽然代码没有显示它,我打赌代码是在工作线程中执行AsyncTask的普通Thread或doInBackground方法以及导致错误的原因,以避免在从工作线程创建处理程序之前始终调用Looper.prepare。
希望这有助于。
问候!
答案 2 :(得分:1)
你怎么知道它在主线程上运行?什么时候和哪里被召唤?而不是在使用它之前创建处理程序,而是在Activity或服务的onCreate方法中创建它(取决于它是什么)。然后在onDestroy中将值清空。