Android应用功能开发之计时锁屏

需求描述

    在开发金融类APP时,经常会有这样一种需求,超过时间限制未操作页面,需要页面回到密码登录页,一般是回到手密页,那我们如何实现这样一种需求呢?

方案设计

    APP跑起来之后,我们一定会有一种类似Manager的角色,它是单例的且与APP生命周期相同的一直跑在内存中。它的作用是管理业务,串联业务流程,启动页面等。我们可以单独做一个TouchTimeoutManager作为计时器,每隔一秒检查时间是否超过了限定时间,若超过了限定时间向外回调。另一个业务管理器,例如登录管理器实现监听方法,并在监听方法中调用返回手密登录页面的方法。

详细设计

这里我们描述TouchTimeoutManager的详细功能设计:

1、需要维护一个上次操作时间lastUpdatedTime,每次进行检查时,用当前时间减去上次操作时间,就得出了多长时间还未操作的时间数值。并对外提供更新更新lastUpdatedTime的方法,我们可以在每个activity启动时和在activity中覆盖dispatchTouchEvent()在其中更新lastUpdatedTime

check方法:

    private void check(){
        //时间差值
        long actualTimeout = System.currentTimeMillis() - lastUpdatedTime;
        //差值大于时间限制向外回调
        if(actualTimeout >= timeoutInMs)
            notifyAllListeners();
    }

向外提供更新lastUpdatedTime方法:

    public synchronized void onUserAction(){
        lastUpdatedTime = System.currentTimeMillis();
    }

2、计时

这里我们需要有一个计时任务,每秒执行一次,我们可以选择TimerTask、handler.postDealy()、甚至线程来做。这里我们选择使用handler.postDealy()

private Runnable checkTask = new Runnable() {
        @Override
        public void run() {
            //停止检查标识
            if(checkingStopped)
                return;

            //检查是否超时
            check();

            //每隔一秒检查一次
            handler.postDelayed(this, 1000);
        }
    };

check()方法我们在上边贴过,这里就不贴了

3、向外回调

这里我们应该可以想到,向外回调采用观察者模式,本地维护一个listener,当事件发生遍历Listener调用onXXX()方法,并对外提供注册listener方法

维护的本地队列

private HashSet<HDTouchEvtTimeoutListener> listeners = null;

HDTouchTimeoutListener

public interface HDTouchEvtTimeoutListener {
    void touchTimeoutReached(Object tag, long timeoutInMs);
}

notifyAllListeners():

    private void notifyAllListeners(){
        //防止有listener处理回调的时候执行unregister动作造成迭代器失效
        HashSet<HDTouchEvtTimeoutListener> cloneListeners = (HashSet<HDTouchEvtTimeoutListener>) listeners.clone(); 

        for(HDTouchEvtTimeoutListener listener : cloneListeners){
            listener.touchTimeoutReached(tag, timeoutInMs);
        }

    }

对外提供注册方法:

    public synchronized void registerListener(HDTouchEvtTimeoutListener listener){
        if(listeners.contains(listener))
            return;

        listeners.add(listener);
        startChecking();
        check(); //保证时效性
    }

这里比较好理解,我们就不赘述了

同时,我们提供startChecking和stopChecking方法,外部可以调用启动或停止check

    private void startChecking(){
        checkingStopped = false;
        handler.postDelayed(checkTask, 1000);
    }

    private void stopChecking(){
        checkingStopped = true;
        handler.removeCallbacks(checkTask);
    }
完整代码就不贴了,相信大家理解思路后自己可以写出检查计时器

展开阅读全文

没有更多推荐了,返回首页