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

如何定时更新ViewModel/LiveData且避免应用后台时执行高成本计算

实现方案

核心思路

利用组件生命周期的可见性回调,在用户可见时启动定时任务,不可见时主动停止任务,从根源上避免后台执行高成本计算。

具体实现(按页面可见性启停,适配单页面使用场景)

1. 改造ViewModel

暴露定时器启停方法,增加多观察者兼容逻辑,同时修复原有代码的无效判断问题:

public class EventDatesViewModel extends AndroidViewModel {

    private final MutableLiveData<String> timeToEvent = new MutableLiveData<>();
    private final Handler handler = new Handler();
    private boolean isTimerRunning = false;
    // 多观察者计数,避免单个页面退出就停掉所有页面的计时
    private int observerCount = 0;

    private final Runnable runnable = new Runnable() {
        @Override
        public void run() {
            new Thread(() -> calculateTimeToEvent()).start();
            handler.postDelayed(this, 10000);
        }
    };

    public EventDatesViewModel(@NonNull Application application) {
        super(application);
    }

    public LiveData<String> getTimeToEvent() {
        // 原有判断无效,timeToEvent已经初始化,永远不为null
        return timeToEvent;
    }

    // 对外暴露启动计时方法
    public void startTimer() {
        observerCount++;
        if (isTimerRunning) {
            return;
        }
        isTimerRunning = true;
        // 立刻执行一次计算
        new Thread(this::calculateTimeToEvent).start();
        handler.postDelayed(runnable, 10000);
    }

    // 对外暴露停止计时方法
    public void stopTimer() {
        observerCount--;
        if (observerCount > 0) {
            return;
        }
        isTimerRunning = false;
        handler.removeCallbacks(runnable);
    }

    private void calculateTimeToEvent() {
        // 原有计算逻辑不变
        timeToEvent.postValue(t);
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        handler.removeCallbacks(runnable);
    }
}

2. 改造Fragment

绑定Fragment生命周期启停定时器:

public class GarbageFragment extends Fragment {
    private EventDatesViewModel model;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_garbage, container, false);
        model = new ViewModelProvider(requireActivity(), new ViewModelProvider.AndroidViewModelFactory(requireActivity().getApplication())).get(EventDatesViewModel.class);
        model.getTimeToEvent().observe(this, timeToEvent -> {
            ((TextView)root.findViewById(R.id.textTimeToEvent)).setText(timeToEvent);
        });
        return root;
    }

    // 页面可见时启动计时
    @Override
    public void onStart() {
        super.onStart();
        model.startTimer();
    }

    // 页面不可见(退后台、息屏、切页面)时停止计时
    @Override
    public void onStop() {
        super.onStop();
        model.stopTimer();
    }
}

可选实现(按应用前后台启停,适配多页面共用ViewModel场景)

如果希望只要应用在前台就运行倒计时,不管当前在哪个页面,可以使用ProcessLifecycleOwner做全局监听:

  1. 先添加Module级依赖:
dependencies {
    implementation "androidx.lifecycle:lifecycle-process:2.6.2"
}
  1. 在ViewModel构造方法中注册全局生命周期观察者,无需在每个页面单独调用启停方法即可自动适配应用前后台状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 03:15:03