如何处理Timer取消错误?

时间:2016-04-15 01:54:48

标签: android

我使用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 ...
        }

我可以知道我哪里出错吗?

1 个答案:

答案 0 :(得分:1)

我个人不喜欢使用java.util.Timer课程。这主要是因为当你cancel()时它无法重新启动。

通常我会使用javax.swing.Timer,但我不认为你可以在android中使用它。在Android中,我认为您应该创建自己的计时器类来封装android.os.Handler类。

这就是你要做的:

Handler类包含一个名为postDelayed的方法。它会延迟Runnable运行。

假设您想要创建一个每1000毫秒运行一次的计时器,您可以创建一个处理程序并调用postDelayed(someRunnable, 1000)

然后是有趣的部分。在执行您喜欢的任何内容后,上面的someRunnable 调用postDelayed。这样,一个"循环"成立了。

"但是如何停止处理程序?如何在开始后改变间隔?"你问。

要向计时器类添加暂停方法,只需创建一个名为paused的字段,并在runnable中调用postDelayed之前检查其值。然后,您可以添加设置和获取paused的值的setter和getter。

要更改计时器启动时的间隔,只需创建另一个名为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 ();
    }
}