运行一定时间的方法

时间:2016-10-03 19:42:31

标签: android

所以我有一个名为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.
}

但是,当我在那里读取一些传感器数据时,我不想阻止主线程。任何相同的想法都会非常有用!

感谢。

3 个答案:

答案 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();
    }
}

跳这个有帮助!