所以我有一个名为PredictionEngine(int)
的方法,我希望在每次运行之间运行一定时间并保持一定的时间延迟。方法如下:
private void PredictionEngine(int delay) throws Exception {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
enableStrictMode();
String val = null;
try {
if (tHighPass == 0 && tLowPass == 0 && tKalman == 1) {
//Magic
} else {
//Magic
}
} catch (Exception e) {
e.printStackTrace();
}
enableStrictMode();
new DropboxTask(side_output, "Result", val).execute();
}
}, delay);
}
很明显,我在主线程中运行网络操作,因为这是一个研究应用程序,没有客户端会使用它。
我希望这个整个功能以一定的延迟运行100次,比如2秒。最初的想法是这样做:
for(loop 100 times){
PredictionEngine(int)
Thread.sleep(2000); //sorry for StackOverflow programming.
}
但是,当我在那里读取一些传感器数据时,我不想阻止主线程。任何相同的想法都会非常有用!
感谢。
答案 0 :(得分:1)
在创建Handler时,你可以提供一个looper作为构造函数参数之一,它基于不同的线程,然后是主线程:
HandlerThread thread = new HandlerThread("Thread name", android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
Looper looper = thread.getLooper();
Handler handler = new MyHandler(looper);
MyHandler接收的消息将在一个单独的线程上处理,从而保持UI线程免受干扰。
要定期循环任务,请使用以下内容:
for (int i=0; i<100; i++){
handler.postDelayed(new Runnable(){
...
...
...
}, i*delay);
}
这样,如果您决定需要取消定期任务,您将始终可以调用:
handler.removeCallbacksAndMessages(null);
答案 1 :(得分:1)
解决此问题的最佳方法是使用rxJava库,因为它允许创建,修改和使用事件流。您可以在几行代码中实现所有内容并对其进行修改,以便在后台执行操作。
Observable.interval(1, TimeUnit.SECONDS)
.take(100)
// switch execution into main thread
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(t -> {
doSomethingOnMainThread();
});
另一方面,还有另一种解决方案 - 您可以使用Handler,它通常用于线程通信。它有方法.postDelayed()允许你推迟执行任务。 Handler可以方便地与HandlerThread一起使用。但是,rxJava是解决问题的更方便和简单的方法。
答案 2 :(得分:0)
我试图在不阻塞主线程的情况下解决问题如下 我创建了工作线程进行循环并仍然在主线程上运行 predictionEngine()
MyThread t = new MyThread(2000, 3000); // delay and sleep
t.startExecution();
工作线程类如下所示
class MyThread extends Thread{
private int delay;
long sleep;
MyThread(int delay, long sleep){
this.delay = delay;
this.sleep = sleep;
}
@Override
public void run() {
for(int i = 0; i < 100; i++){
try {
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
predictEngine(delay);
}
});
Log.i("Mtali","About to pause loop before next predict");
sleep(sleep);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void startExecution(){
start();
}
}
跳这个有帮助!