Android中Timer/CountDownTimer在onResume重复执行问题求助
问题根源分析
你遇到的问题很典型:每次进入onStop()都会新建并启动一个定时器,但没有在应用回到前台(onResume())时取消未执行的旧定时器,也没有做重复创建的判断。这就导致多次切换前后台后,会有多个定时器同时在后台运行,哪怕应用已经回到前台,之前的定时器到时间依然会触发断开服务器的操作。
解决方案(分两种定时器实现)
核心思路都是:给定时器加全局引用,在应用回到前台时取消未完成的任务,离开前台时确保只启动一个新定时器
一、修复Timer实现
步骤1:声明全局引用
在你的Activity类里先定义全局的Timer和TimerTask变量,不要每次在onStop()里临时创建:
private Timer desconexionTimer; private TimerTask desconexionTask;
步骤2:修改onStop()方法
先取消可能存在的旧定时器,再创建新的,避免重复启动:
@Override protected void onStop() { super.onStop(); // 先清理旧的定时器任务,防止重复 if (desconexionTimer != null) { desconexionTimer.cancel(); desconexionTimer = null; } if (desconexionTask != null) { desconexionTask.cancel(); desconexionTask = null; } // 创建并启动新的断开连接任务 desconexionTask = new TimerTask() { @Override public void run() { // 注意这里要传Activity的上下文,别用匿名类的this new ThreadDesconexion(YourActivityName.this).execute(); } }; desconexionTimer = new Timer(); desconexionTimer.schedule(desconexionTask, 30 * 1000); }
步骤3:在onResume()里取消定时器
应用回到前台时,立刻终止未执行的定时器,避免它后续触发断开操作:
@Override protected void onResume() { super.onResume(); // 取消后台跑的定时器 if (desconexionTimer != null) { desconexionTimer.cancel(); desconexionTimer = null; } if (desconexionTask != null) { desconexionTask.cancel(); desconexionTask = null; } if(!ConexionServer.threIsConexion()){ comeActivityLogin(); } }
二、修复CountDownTimer实现
CountDownTimer自带cancel()方法,处理起来更简洁:
步骤1:声明全局引用
在Activity类里定义全局的CountDownTimer变量:
private CountDownTimer desconexionCountDown;
步骤2:修改onStop()方法
先取消旧的倒计时,再启动新的:
@Override protected void onStop() { super.onStop(); // 清理旧的倒计时 if (desconexionCountDown != null) { desconexionCountDown.cancel(); desconexionCountDown = null; } // 启动新的30秒倒计时 desconexionCountDown = new CountDownTimer(30000, 1000) { public void onTick(long millisUntilFinished) { Log.d("INFO","HELLO"); } public void onFinish() { // 同样注意传递正确的Activity上下文 new ThreadDesconexion(YourActivityName.this).execute(); } }.start(); }
步骤3:在onResume()里取消倒计时
@Override protected void onResume() { super.onResume(); if (desconexionCountDown != null) { desconexionCountDown.cancel(); desconexionCountDown = null; } if(!ConexionServer.threIsConexion()){ comeActivityLogin(); } }
额外优化建议
为了避免内存泄漏,记得在Activity销毁时也清理定时器:
@Override protected void onDestroy() { super.onDestroy(); // 清理Timer相关 if (desconexionTimer != null) { desconexionTimer.cancel(); desconexionTimer = null; } if (desconexionTask != null) { desconexionTask.cancel(); desconexionTask = null; } // 清理CountDownTimer相关 if (desconexionCountDown != null) { desconexionCountDown.cancel(); desconexionCountDown = null; } }
内容的提问来源于stack exchange,提问作者Javier
相关产品推荐
相关产品推荐

