You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发中Activity停止时终止LiveData关联定时任务的正确方案

问题解答

一、是否存在内存泄漏风险?

存在明确的内存泄漏风险,问题根源如下:

  • 你在ViewModel构造方法中创建的Timer是局部变量,没有保留实例引用,无法主动终止定时器运行。Timer启动后会持有内部TimerTask的引用,而匿名内部类TimerTask默认持有外部ViewModel实例的引用,只要定时器还在调度运行,ViewModel就无法被GC回收,哪怕其关联的Activity已经销毁。
  • 你使用了static修饰的counter变量,所有ViewModel实例会共用这一个计数变量,多次启动Activity生成多个定时器时会出现计数混乱。
  • Activity正常销毁(非配置变更类销毁,如用户按返回键退出)后,旧定时器没有终止,重启Activity会创建新的ViewModel同时启动新定时器,就会出现多定时器同时运行的问题,也会进一步加剧内存泄漏。

二、停止任务的正确实现方式

核心逻辑是利用ViewModel的onCleared生命周期回调,在关联的页面真正销毁时主动终止定时器,修改方案如下:

  1. 将Timer改为ViewModel的成员变量,保留实例引用用于后续取消操作
  2. 去掉counter的static修饰符,改为实例成员变量,避免多实例共享计数
  3. 重写ViewModel的onCleared()方法,在回调中终止定时器并释放资源

修改后的MainActivityViewModel代码:

public class MainActivityViewModel extends ViewModel {

    private MutableLiveData<Integer> mutableLiveData = new MainActivityLiveData<>();
    private static final int BEGIN_AFTER = 1000, INTERVAL = 5000;
    // 改为实例成员,避免多实例共用
    private int counter = 0;
    // 保存Timer实例作为成员变量
    private Timer timer;

    public MainActivityViewModel() {
        startTimer();
    }

    private void startTimer() {
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                Log.d("mylog", timer.toString() + " " + ++counter);
                mutableLiveData.postValue(counter);
            }
        }, BEGIN_AFTER, INTERVAL);
    }

    public MutableLiveData<Integer> getLiveData() {
        return mutableLiveData;
    }

    // ViewModel销毁时回调,终止定时器
    @Override
    protected void onCleared() {
        super.onCleared();
        if (timer != null) {
            timer.cancel();
            timer.purge();
            timer = null;
        }
    }
}

补充说明

  • 如果你的定时器需求是不受页面生命周期影响、后台也要持续运行,不要在ViewModel中实现,应改用WorkManager或前台服务实现。
  • 上述修改后,配置变更(如屏幕旋转)导致的Activity重建不会触发ViewModel的onCleared,定时器会继续运行,计数不会中断,符合ViewModel的设计定位。

内容的提问来源于stack exchange,提问作者barabash196

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 03:36:01