华为网站建设费用,做淘宝返利网站能挣钱,百度seo刷排名工具,网站开发常遇到客户问题我们经常会在银行、金融或者其他行业的app中看到用户长时间将app放置于后台#xff0c;当再次唤醒app时就会提示用户已退出登录#xff0c;需要重新登录#xff0c;那么该篇主要就是用于处理这种场景的 针对于放置后台的超时保护属于进程级别#xff0c;所以我们需要监听进… 我们经常会在银行、金融或者其他行业的app中看到用户长时间将app放置于后台当再次唤醒app时就会提示用户已退出登录需要重新登录那么该篇主要就是用于处理这种场景的 针对于放置后台的超时保护属于进程级别所以我们需要监听进程的生命周期主要用到了 Lifecycle 组件有兴趣的可以去 组件化之路 - Lifecycle一知半解 了解一下如何监听进程的生命周期
以前写过一篇 前后台切换监听 也是用于监听组件生命周期的可以参考参考 创建观察者 - 监听生命周期关于 Handler 、Thread 扩展函数观察者 绑定 进程生命周期初始化配置Application 初始化监听绑定 Application 实现思路通过监听进程的生命周期从而判断app处于前后台的状态在不同状态下进行计时操作当状态切换后判断是否超过所设时间从而执行相关逻辑
这里并不涉及什么原理最多就是有兴趣看看 Lifecycle 对于 Android 常用组件Activity、Service、Process在生命周期方面如何绑定、监听等
废话不多说直接向目标进发
创建观察者 - 监听生命周期
主要用于监听app处于前后台的一个状态以及前后台切换后的时差是否超过保护时间如果超过则可以将用户踢出去让其重新登录
package com.example.lifestartupdemoimport android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent// 超时重新登录提示
internal class LoginStateObserver : LifecycleObserver {companion object {private const val interval 10 * 1000L //保护时间10s可自行设置}private var timestamp 0L //onPause 时间点/*** 应用程序出现到前台时调用*/OnLifecycleEvent(Lifecycle.Event.ON_RESUME)fun onResume() {Log.e(tag, 应用 onResume() - 前台)val currentTime System.currentTimeMillis()if (timestamp ! 0L currentTime - timestamp interval) { // 后台超过保护时间需要执行的逻辑timestamp 0mainHandler.postDelayed(300) {//常见于清空用户信息请用户重新登录Log.e(tag, 应用由后台到了前台进入了超时逻辑)}}}/*** 应用程序退出到后台时调用*/OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)fun onPause() {Log.e(tag, 应用 onPause() 已被切换至后台)timestamp System.currentTimeMillis()}}关于 Handler 、Thread 扩展函数
这里主要涉及到了一些Handler原理例如 Looper、Therad等
package com.example.lifestartupdemoimport android.os.Build
import android.os.Handler
import android.os.Looperfun Handler.postDelayed(delayMillis: Long,runnable: Runnable
) this.postDelayed(runnable, delayMillis)JvmField
val mainHandler: Handler if (Build.VERSION.SDK_INT 28) Handler.createAsync(mainLooper) else try {Handler::class.java.getDeclaredConstructor(Looper::class.java,Handler.Callback::class.java,Boolean::class.javaPrimitiveType // async).newInstance(mainLooper, null, true)
} catch (ignored: NoSuchMethodException) {Handler(mainLooper) // Hidden constructor absent. Fall back to non-async constructor.
}MainThreadkt文件
file:Suppress(UNUSED)package com.example.lifestartupdemoimport android.os.Looper/** This main looper cache avoids synchronization overhead when accessed repeatedly. */
JvmField
val mainLooper: Looper Looper.getMainLooper()!!JvmField
val mainThread: Thread mainLooper.threadval isMainThread: Boolean inline get() mainThread Thread.currentThread()PublishedApi
internal val currentThread: Any?inline get() Thread.currentThread()观察者 绑定 进程生命周期
从架构而言有很多东西需要初始化可以写一个接口便于解耦
package com.example.lifestartupdemoimport android.app.Applicationinterface ApplicationStartup {fun onCreate(application: Application)
}具体绑定组件生命周期的实现类
package com.example.lifestartupdemoimport android.app.Application
import androidx.lifecycle.ProcessLifecycleOwnerinternal class MineApplicationStartup : ApplicationStartup {override fun onCreate(application: Application) {ProcessLifecycleOwner.get().lifecycle.addObserver(LoginStateObserver())}
}初始化配置
Application 初始化监听
package com.example.lifestartupdemoimport android.app.Applicationclass OurApplication : Application() {override fun onCreate() {super.onCreate()//应用启动则初始化该配置val mineApplicationStartup MineApplicationStartup()mineApplicationStartup.onCreate(this)}
}绑定 Application
?xml version1.0 encodingutf-8?
manifest xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:toolshttp://schemas.android.com/toolsapplicationandroid:allowBackuptrueandroid:dataExtractionRulesxml/data_extraction_rulesandroid:fullBackupContentxml/backup_rulesandroid:iconmipmap/ic_launcherandroid:labelstring/app_nameandroid:supportsRtltrueandroid:name.OurApplicationandroid:themestyle/Theme.LifeStartupDemotools:targetApi31activityandroid:name.MainActivityandroid:exportedtrueintent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter/activity/application/manifest