android App休眠页开发

背景

需求:app在页面无操作,60S后进入休眠页,点击休眠页面再回到上一个页面。

实现

思路:
1、设置全局定时器管理类SleepManager,启动定时器,60S跳转休眠页。
2、监听全局activity的touch事件,重置定时器。

实施

1、创建管理类:


object SleepManager {

    private val handler = Handler(Looper.getMainLooper())
    private var inactivityTimeout: Long = 60000 // 1 minute in milliseconds
    private var reference: WeakReference<Activity>? = null
    private val inactivityRunnable = Runnable {
        reference?.get()?.let { activity ->
        	//跳转休眠页面
            ScreenSaverActivity.start(activity)
        }
    }

    fun register(app: Application) {
        app.registerActivityLifecycleCallbacks(object : CustomActivityCallBack() {
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
                val window = activity.window
                val callback = window.callback
                val handler = WindowCallbackInvocation(callback,activity)
                val proxy = Proxy.newProxyInstance(
                    Window.Callback::class.java.classLoader,
                    arrayOf(Window.Callback::class.java),
                    handler
                ) as Window.Callback
                window.callback = proxy
            }

            override fun onActivityPaused(activity: Activity) {
                stopInactivityTimer()
            }

            override fun onActivityResumed(activity: Activity) {
                startInactivityTimer(activity)
            }
        })
    }

    fun startInactivityTimer(activity: Activity?) {
        activity?.let {
            reference = WeakReference(activity)
            if (activity is ScreenSaverActivity) {
                return
            }
        }
        handler.postDelayed(inactivityRunnable, inactivityTimeout)
    }

    fun stopInactivityTimer() {
        handler.removeCallbacks(inactivityRunnable)
    }

    fun resetInactivityTimer(activity: Activity?) {
        handler.removeCallbacks(inactivityRunnable)
        startInactivityTimer(activity)
    }
}

解释一下:

  • register():通过app获取全局activity的生命周期,监听window的touch事件
  • 在onActivityPaused移除监听。
  • onActivityResumed重新启动监听。
    当时想着在baseactivity里重写dispatchTouchEvent,再重置runnable,但是侵入性太强,后面看到有大佬使用动态代理的思路,简单方便。

WindowCallbackInvocation代码如下:

class WindowCallbackInvocation(private val callback: Any, private val activity: Activity) : InvocationHandler {

    override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any? {
        if ("dispatchTouchEvent" == method?.name) {
            val event = args?.firstOrNull() as? MotionEvent
            if (MotionEvent.ACTION_UP == event?.action) {
                SleepManager.resetInactivityTimer(activity)
            }
        }
        return method?.invoke(callback, *(args ?: arrayOfNulls<Any>(0)))
    }
}

原理是:运行时生成代理类WindowCallbackInvocation ,内部拦截Window.Callback的dispatchTouchEvent函数,重置runnable。
好处是还能监听第三方sdk的activity。

使用

在Application中:

class TabletApp : Application() {

    override fun onCreate() {
        super.onCreate()
        SleepManager.register(this)
    }
}

不足,目前只能在activity中重置runnable,dialog无效。
解决思路:在dialog show的时候获取window,执行代理逻辑即可。

参考:Android 监听页面无操作,定时返回(动态代理)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值