今天给app新增一个小功能:在Fragment里面实现定时向服务器及本地数据库存储信息。先后用了三套方案才实现,可谓波折不断。
第一套方案是Timer+TimerTask方案,这两个东东我不多说,想必大家也很清楚怎么用,按理说实现前面的功能应该是轻车熟路轻而易举的。事实上也确实如此。很轻松的实现了功能。
不过在测试的时候,发现,当从当前界面跳转到任意其他界面再返回的时候,App意外的Crash了。报异常:Timer已经cancel了。事实上即便我不在onDestroy()方法里面调用Timer和TimerTask的cancel方法,一样的会崩溃。无奈,时间紧,没工夫找原因。立马换个方案,RxJava2的Timer功能,但这回更悲剧,在这个Fragment里面,原来的作者引用了java.util.Observable和java.util.Observer对象。没法再调用RxJava2的这两个对象。真TM的苦逼。
然后再换方案:Handler+Runnable来实现循环定时。这次终于报喜了。具体实现如下:
在Activity或者Fragment的onResume()方法里面
@Override
public void onResume() {
super.onResume();
// 每隔2分钟保存一次
mHandler.postDelayed(runnable, 10 * 1000);
}
Runnable runnable = new Runnable() {
@Override
public void run() {
//TODO:延时要干的其他事情
//循环定时最关键的一行代码:onResume方法里面调用mHandler.postDelayed后,程序开始延时操作,执行完后,又在这里调用了自己给自己发一条延时消息这样在线程里面就形成一个循环(死循环)
mHandler.postDelayed(runnable, 10 * 1000);
}
};
可以在需要的地方执行下面的代码,取消死循环的持续进行:
mHandler.removeCallbacks(runnable);
就这样实现Timer+TimerTask的功能,而且更简单。
经过探索,Timer+TimerTask方案崩溃的解决方案:
1、崩溃原因:
Timer or TimerTask is cancel or scheduled
2、解决方案:动态的创建TimerTask 对象:
Timer timer = null;
@Override
public void onResume() {
super.onResume();
// 每隔2分钟保存一次
if ( null == timer){
timer = new Timer();
}
timer.schedule(new TimerTask() {
@Override
public void run() {
Log.i("mHandler", "run: mHandler====timerTask");
//TODO:向服务器发送缓存数据
}
}, 5 * 1000, 5 * 1000);
}
先判断timer是否为空,然后再动态创建TimerTask,就不会再报cancel or scheduled的异常了。