android 在实现定时器的方法很多,网上可以搜到很多,但是实现的时候一定要注意句柄导致的内存泄露问题。这里我们主要通过对Timer封装实现一个简易的定时器。

  1. 为了避免内部类导致的内存泄露,实现将TimerTaskHandler都放在类外部实现
  2. 为了方便使用,定义interface IXTimer,使用者从IXTimer派生即可使用定时器

为什么选用Timer?
因为Timer支持一个定时器设置多个TimerTask(通过堆实现,效率高),符合实际使用场景。不需要为每个定时器单独启用一个线程。

interface IXTimer{
    public final static String TAG ="ITimer";

    default void onTimer(int timerId){
        Log.i(TAG, String.format("ontimer id:%d", timerId));
    }
}

class XTimerHandle extends Handler{
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        Log.i("finalize","XTimerHandle::finalize");
    }
    @Override
    public void handleMessage(@NonNull Message msg) {
        super.handleMessage(msg);

        WeakReference<IXTimer> weakReference = (WeakReference<IXTimer>) msg.obj;
        IXTimer iTimer = weakReference.get();
        if(iTimer != null){
            iTimer.onTimer(msg.what);
        }
    }
};

class XTimerTask extends TimerTask{
    public XTimerTask(int timerId,WeakReference<IXTimer> refweak_timer,Handler timer_hander){
        m_timer_hander = new WeakReference<>(timer_hander);
        m_timerId = timerId;
        m_refweak_timer = refweak_timer;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        Log.i("finalize","XTimerTask::finalize");

    }

    @Override
    public void run() {
        Message msg = new Message();
        msg.obj = m_refweak_timer;
        msg.what = m_timerId;
        Handler handler = m_timer_hander.get();
        if(handler != null){
            handler.sendMessage(msg);
        }
    }

    private WeakReference<IXTimer> m_refweak_timer;
    private int m_timerId;
    private WeakReference<Handler> m_timer_hander;
}

public class XTimer {
    public final static String TAG ="XTimer";

    private WeakReference<IXTimer> m_refweak_timer;
    public XTimer(IXTimer iTimer){
        m_refweak_timer = new WeakReference<>(iTimer);
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        Log.i("finalize","XTimer::finalize");
        m_map_timertask.clear();
        m_timer.cancel();
        m_timer = null;
        m_timer_hander.removeCallbacksAndMessages(null);
        m_timer_hander = null;
    }

    public void setTimer(int timerId, int time){
        if(m_map_timertask.containsKey(timerId))
        {
            //取消当前定时器
            m_map_timertask.get(timerId).cancel();
        }
        TimerTask timerTask = new XTimerTask(timerId,m_refweak_timer,m_timer_hander);
        m_map_timertask.put(timerId,timerTask);
        m_timer.schedule(timerTask,time,time);
    }

    public void killTimer(int timerId){
        if(m_map_timertask.containsKey(timerId)){
            m_map_timertask.get(timerId).cancel();
            m_map_timertask.remove(timerId);
        }
    }

    private HashMap<Integer,TimerTask> m_map_timertask = new HashMap<>();
    private Timer m_timer = new Timer();
    private Handler m_timer_hander = new XTimerHandle();
}

使用

class CA implements IXTimer{
    private XTimer m_timer = new XTimer(this);

    public CA(){
        m_timer.setTimer(0x12,1000);
        m_timer.setTimer(0x13,15000);
    }
    @Override
    public void onTimer(int timerId) {
       Log.i("onTimer","onTimer");
    }
}
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐