2016-04-15 2 views
1

Я использую android. Недавно я кодировал данные пересылки. , но произошел незаконный запуск. Таймер был отменен.Как я могу обработать таймер была отменена ошибка?

Это мой LogCat:

java.lang.RuntimeException: Unable to start receiver kr.co.iosystem.blackeyeonandroid.util.NetworkChangeReceiver: java.lang.IllegalStateException: Timer was canceled 
                at android.app.ActivityThread.handleReceiver(ActivityThread.java:2414) 
                at android.app.ActivityThread.access$1700(ActivityThread.java:135) 
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1272) 
                at android.os.Handler.dispatchMessage(Handler.java:102) 
                at android.os.Looper.loop(Looper.java:136) 
                at android.app.ActivityThread.main(ActivityThread.java:5001) 
                at java.lang.reflect.Method.invokeNative(Native Method) 
                at java.lang.reflect.Method.invoke(Method.java:515) 
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
                at dalvik.system.NativeStart.main(Native Method) 
                Caused by: java.lang.IllegalStateException: Timer was canceled 
                at java.util.Timer.scheduleImpl(Timer.java:561) 
                at java.util.Timer.schedule(Timer.java:459) 
                at kr.co.iosystem.blackeyeonandroid.sender.DataSender.sendPicData(DataSender.java:251) 
                at kr.co.iosystem.blackeyeonandroid.sender.DataSender.restart(DataSender.java:425) 
                at kr.co.iosystem.blackeyeonandroid.sender.DataSender.update(DataSender.java:337) 
                at java.util.Observable.notifyObservers(Observable.java:138) 
                at kr.co.iosystem.blackeyeonandroid.util.AutoObservable.notifyObservers(AutoObservable.java:13) 
                at kr.co.iosystem.blackeyeonandroid.main.Agency.notifyMessage(Agency.java:88) 
                at kr.co.iosystem.blackeyeonandroid.util.NetworkChangeReceiver.onReceive(NetworkChangeReceiver.java:200) 
                at android.app.ActivityThread.handleReceiver(ActivityThread.java:2407) 
                at android.app.ActivityThread.access$1700(ActivityThread.java:135)  
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1272)  
                at android.os.Handler.dispatchMessage(Handler.java:102)  
                at android.os.Looper.loop(Looper.java:136)  
                at android.app.ActivityThread.main(ActivityThread.java:5001)  
                at java.lang.reflect.Method.invokeNative(Native Method)  
                at java.lang.reflect.Method.invoke(Method.java:515)  

Я думаю, что это та часть, где исключение встречающийся

private Timer mTimer = null; //global variable 

@Override 
public void run() { 
mTimer = new Timer(); 
... 
} 
@Override 
public void update(){ 
if (this.senderState == SenderState.STOPPED) { 
      this.mTimer.cancel(); 
    this.restart(); //Timer exception ... 
     } 

Могу ли я знать, где я буду неправильно?

+0

Вы не можете перезапустить отмененный таймер. Вам нужно создать новый. –

+0

@GabeSechan ваш совет не использовать отмену, перезапуск в том же методе? –

+0

Вы можете использовать перезапуск на своем объекте DataSender. Но вам нужно создать новый объект Timer, а не просто запустить тот же самый. –

ответ

1

Я лично не люблю использовать класс java.util.Timer. Это происходит главным образом из-за того, что его нельзя перезапустить, когда вы его cancel().

Обычно я бы использовал javax.swing.Timer, но я не думаю, что вы можете использовать его в android. В Android, я думаю, вы должны создать свой собственный класс таймера, который инкапсулирует класс android.os.Handler.

Это, как вы могли бы сделать это:

Handler класс содержит метод, называемый postDelayed. Он запустит Runnable с задержкой.

Предположим, вы хотите создать таймер, который запускает что-то каждые 1000 мс, вы можете создать обработчик и вызвать postDelayed(someRunnable, 1000).

Тогда вот интересная деталь. someRunnable выше должен также позвонить postDelayed после того, как вы выполнили все, что захотите. Таким образом, формируется «цикл».

«Но как я могу остановить обработчик и как изменить интервал после его запуска?» Ты спрашивал.

Чтобы добавить метод паузы в класс таймера, просто создайте поле с именем paused и проверьте его значение перед вызовом postDelayed в runnable. Затем вы можете добавить сеттеры и геттеры, которые устанавливают и получают значение paused.

Чтобы изменить интервал при запуске таймера, просто создайте другое поле с именем interval и реализуйте его аналогичным образом.

TL; DR

Я очень хороший, я знаю. Вот код для копирования:

import android.os.Handler; 

public class Timer { 
    private Handler handler; 
    private boolean paused; 

    private int interval; 

    private Runnable task = new Runnable() { 
     @Override 
     public void run() { 
      if (!paused) { 
       Timer.this.runnable.run(); 
       Timer.this.handler.postDelayed (this, interval); 
      } 
     } 
    }; 

    private Runnable runnable; 

    public int getInterval() { 
     return interval; 
    } 

    public void setInterval(int interval) { 
     this.interval = interval; 
    } 

    public void startTimer() { 
     paused = false; 
     handler.postDelayed (task, interval); 
    } 

    public void stopTimer() { 
     paused = true; 
    } 

    public Timer (Runnable runnable, int interval, boolean started) { 
     handler = new Handler(); 
     this.runnable = runnable; 
     this.interval = interval; 
     if (started) 
      startTimer(); 
    } 
} 
Смежные вопросы