Android 使用处理程序每 10 秒调用一次方法
Android call method every 10 seconds with handler
我想每 10 秒用一个计时器调用我的函数,我的函数有一个处理程序,它显示错误:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
我的函数:
public void startData(){
doBindService();
new Handler().post(mQueueCommands);
}
这个 startData() 有一个 public 变量 "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();
}
}
只能在 Looper 中的线程上创建处理程序。 UI 主线程在 Looper 中,因此可以在那里创建处理程序。普通的 Thread 或 AsyncTask 不是,因此它们无法创建 Handlers。假设你想post到UI线程,你需要在UI线程上创建Handler。
顺便说一句,看到这样创建新处理程序的代码非常不寻常。通常,模式是在构造函数中创建一个 Handler 并向其 post 。像这样创建新的处理程序充其量是低效的,最坏的情况是错误。
如果要使用Handler架构,Timer对象就没有用了。
首先,获取Handler。对于示例,我将使用主 Handler
(UIThread),但您也可以使用新的 Looper
.
创建自己的
所以,让我们像这样开始循环任务:
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
}
请注意,所有方法都将在 UIThread 上调用。如果您希望 mQueueCommands 任务在新线程上的新 Handler
上 运行,则需要创建它。
编辑:
调用代码应如下所示:
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...");
}
}
您不想多次触发循环方法:-)
我想每 10 秒用一个计时器调用我的函数,我的函数有一个处理程序,它显示错误:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
我的函数:
public void startData(){
doBindService();
new Handler().post(mQueueCommands);
}
这个 startData() 有一个 public 变量 "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();
}
}
只能在 Looper 中的线程上创建处理程序。 UI 主线程在 Looper 中,因此可以在那里创建处理程序。普通的 Thread 或 AsyncTask 不是,因此它们无法创建 Handlers。假设你想post到UI线程,你需要在UI线程上创建Handler。
顺便说一句,看到这样创建新处理程序的代码非常不寻常。通常,模式是在构造函数中创建一个 Handler 并向其 post 。像这样创建新的处理程序充其量是低效的,最坏的情况是错误。
如果要使用Handler架构,Timer对象就没有用了。
首先,获取Handler。对于示例,我将使用主 Handler
(UIThread),但您也可以使用新的 Looper
.
所以,让我们像这样开始循环任务:
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
}
请注意,所有方法都将在 UIThread 上调用。如果您希望 mQueueCommands 任务在新线程上的新 Handler
上 运行,则需要创建它。
编辑:
调用代码应如下所示:
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...");
}
}
您不想多次触发循环方法:-)