2016-04-15 66 views
1

我使用的是android。最近我編碼了一個重發數據。 但發生非法狀態異常定時器被取消。我該如何處理Timer被取消錯誤?

這是我的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對象,而不僅僅是啓動一個新的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之前檢查其值。然後,您可以添加setter和getters,設置並獲得值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(); 
    } 
} 
相關問題