2016-10-03 3 views
0

Итак, у меня есть этот метод под названием 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

[Timer] (https://developer.android.com/reference/java/util/Timer.html) – Onik

ответ

1

Лучший способ решить это с помощью библиотеки rxJava, поскольку он позволяет создавать, изменять и потреблять потоки событий. Вы можете реализовать все в нескольких строках кода и изменить его, так что operatioin будет выполняться и в фоновом режиме.

Observable.interval(1, TimeUnit.SECONDS) 
       .take(100) 
       // switch execution into main thread 
       .subscribeOn(AndroidSchedulers.mainThread()) 
       .subscribe(t -> { 
        doSomethingOnMainThread(); 
       }); 

С другой стороны, существует другое решение - вы можете использовать Handler, который обычно используется для связи потоков. У него есть метод .postDelayed(), позволяющий отложить выполнение задачи. Обработчик можно удобно использовать вместе с HandlerThread. Но, rxJava - это более удобный и простой способ решить вашу проблему.

+0

В добавлена ​​библиотека и все, она говорит, что не может найти класс 'AndroidSchedulers'. Что мне не хватает? –

+1

для AndroidSchedulers вы также должны использовать rxAndroid: compile 'io.reactivex: rxjava: 1.0.13' compile 'io.reactivex: rxandroid: 0.25.0' –

+0

Спасибо, это решает! –

1

При создании обработчика, вы можете предоставить петлитель в качестве одного из параметров конструкторов, который основан на другом потоке, то основной поток:

HandlerThread thread = new HandlerThread("Thread name", android.os.Process.THREAD_PRIORITY_BACKGROUND); 
thread.start(); 
Looper looper = thread.getLooper(); 
Handler handler = new MyHandler(looper); 

Сообщение, полученное MyHandler будет обрабатываться на отдельный поток, оставляя поток пользовательского интерфейса свободным от помех.

Для цикла на задачу периодически, использовать что-то вроде:

for (int i=0; i<100; i++){ 
    handler.postDelayed(new Runnable(){ 
     ... 
     ... 
     ... 
    }, i*delay); 
} 

Таким образом, в случае, если вы решили, что периодические задачи должны быть отменены, вы всегда будете иметь возможность ссылаться:

handler.removeCallbacksAndMessages(null); 
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(); 
    } 
} 

Хлоп это помогает!

Смежные вопросы