我想用计时器每10秒调用一次我的函数,我的函数有一个处理程序,它显示错误:
java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序
我的功能:
public void startData(){
doBindService();
new Handler().post(mQueueCommands);
}
这个startData()有一个公共变量" btIsConnected" ,无论何时
btIsConnected== true
,我想停止调用它,否则前两分钟我想每10秒调用一次startData()
class startLiveDataTimerTask extends TimerTask{
public void run(){
startData();
}
}
private void tryConnectEveryTenSeconds() {
Timer timer = new Timer();
timer.schedule(new startLiveDataTimerTask(), 0, 10000);
}
onCreate()
中的:
long futureTimeInTwoMinute = System.currentTimeMillis() + 120000;
Intent i = new Intent(ObdConstants.StartLiveData.getValue()); sendBroadcast(i); // this broadcaster is used to call StartData() for the first time
if(System.currentTimeMillis()<futureTimeInTwoMinute){
// how do I make a time counter appropriately?
if(btIsConnected){
Log.d(TAG, "is connected!");
//do nothing
}else{
Log.d(TAG, "try to connect every ten seconds....");
tryConnectEveryTenSeconds();
}
}
答案 0 :(得分:2)
如果要使用Handler架构,则Timer对象将无用。
首先,获取处理程序。对于示例,我将使用主Looper
(UIThread),但您也可以创建自己的private void tryConnectEveryTenSeconds() {
Handler handler = new Handler(Looper.getMainLooper()); //This gets the UIThread Handler
handler.postDelayed(new startLiveDataTimerTask(), 10000); //This posts the task ONCE, with 10 sec delay
}
。
所以,让我们像这样启动循环任务:
public void startData(){
doBindService();
Handler handler = new Handler(Looper.getMainLooper());
handler.post(mQueueCommands); //I expect this is what you want. If not and you want a completely new Handler, you will need to create it on a new Thread
handler.postDelayed(new startLiveDataTimerTask(), 10000); //This posts the task AGAIN, with 10 seconds delay
}
现在执行任务:
Handler
请注意,所有方法都将在UIThread上调用。如果您希望mQueueCommands任务在新线程上的新long futureTimeInTwoMinute = System.currentTimeMillis() + 120000;
Intent i = new Intent(ObdConstants.StartLiveData.getValue()); sendBroadcast(i);
tryConnectEveryTenSeconds();
while(System.currentTimeMillis()<futureTimeInTwoMinute){
if(btIsConnected){
Log.d(TAG, "is connected!");
//do nothing
}else{
Log.d(TAG, "Not connected yet...");
}
}
上运行,则需要创建它。
修改强>
调用代码应如下所示:
raw_input
您不想多次触发循环方法: - )
答案 1 :(得分:1)
只能在Looper中的线程上创建处理程序。主UI线程位于Looper中,因此可以在那里创建Handlers。普通的Thread或AsyncTask不是,所以他们不能创建Handler。假设您要发布到UI线程,您需要在UI线程上创建Handler。
顺便说一下,看到代码创建一个像这样的新Handler是非常不寻常的。通常,模式是在构造函数中创建一个Handler并发布到它。像这样创建新的处理程序最多效率低,最坏的情况是错误。