当前位置: 首页 > news >正文

Android进阶之路 - app后台切回前台触发超时保护退出登录

我们经常会在银行、金融或者其他行业的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原理,例如 LooperTherad

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.
}

MainThread(kt文件)

@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 version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:name=".OurApplication"android:theme="@style/Theme.LifeStartupDemo"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

相关文章:

Android进阶之路 - app后台切回前台触发超时保护退出登录

我们经常会在银行、金融或者其他行业的app中看到用户长时间将app放置于后台&#xff0c;当再次唤醒app时就会提示用户已退出登录&#xff0c;需要重新登录&#xff0c;那么该篇主要就是用于处理这种场景的 针对于放置后台的超时保护属于进程级别&#xff0c;所以我们需要监听进…...

论文阅读笔记:Semi-supervised Semantic Segmentation with Error Localization Network

论文阅读笔记&#xff1a;Semi-supervised Semantic Segmentation with Error Localization Network 1 背景2 创新点3 方法4 模块4.1 使用标注数据训练ELN4.2 使用ELN进行半监督 5 效果5.1 与SOTA方法对比5.2 消融实验 论文&#xff1a;https://arxiv.org/pdf/2204.02078v3.pdf…...

Flink开发语言选择:Java vs Scala,哪种更适合你的项目?

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…...

轻空间成功完成陕西渭南砂石料场气膜仓项目

轻空间&#xff08;江苏&#xff09;膜结构科技有限公司凭借卓越的技术实力与丰富的项目经验&#xff0c;成功完成了陕西省渭南市砂石料场气膜仓的建设。这一项目的顺利交付&#xff0c;不仅满足了当地对高效仓储的需求&#xff0c;也为西北地区的仓储设施建设树立了标杆。 陕西…...

pikachu~文件下载漏洞

0x02文件下载 # 首先看到界面都是对图片的下载&#xff0c;然后我们需要对其中一张照片进行下载&#xff0c;查看它的文件地址可以发现 http://127.0.0.1/pikachu-master/vul/unsafedownload/execdownload.php?filenameai.png# 看到链接后发现我们可以修改我们想要传的的路径…...

MTK Android12 关机界面全屏展示

需求:关机和重启按钮点击后,去掉正在关机的动画和tips,改为一张图片实现。 修改点 修改点如下: 涉及到的修改文件 修改: \vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\globalactionsGlobalActionsDialogLite.java新增: \vendor\media…...

初识云计算

随着科技的飞速发展&#xff0c;云计算作为一种新兴的信息技术架构&#xff0c;正在逐渐改变我们的工作方式和生活方式。 云计算是什么&#xff1f; 云计算是一种通过互联网提供计算资源和服务的计算模式。它通过互联网将计算和存储资源进行集中和共享&#xff0c;为用户提供…...

golang sync.Cond实现读写锁

直接上代码: package mainimport ("fmt""sync""time" )// RWLock 实现一个简单的读写锁 type RWLock struct {readerCount int // 当前正在读取的读者数量writerCount int // 当前正在写的写者数量mutex sync.Mutex // 保护…...

从通用到定制:营销Agent如何跨越数据鸿沟,实现对话SOP的个性化飞跃

从通用到定制:营销Agent如何跨越数据鸿沟,实现对话SOP的个性化飞跃 1.背景 营销 Agent 指的是在营销过程中洞察客户并作出决策以及行动的 AI 智能体,包括感知、理解、决策、交互、反馈多个模块。对话 SOP 是交互模块中非常重要的部分,如何在缺少数据的情况下快速实现千人…...

设计模式-单例设计模式

单例模式的设计和线程安全 单例模式是一种创建型设计模式&#xff0c;确保一个类只有一个实例&#xff0c;并提供一个全局访问点。实现单例模式时&#xff0c;线程安全性是一个重要考虑因素&#xff0c;特别是在多线程环境中。 1. C11 之前的线程安全实现 在 C11 之前&#…...

23_windows 使用sqlmap、kali使用sqlmap,SQL注入、sqlmap自动注入

sqlmap介绍 安装sqlmap 安装python环境 链接&#xff1a;https://pan.baidu.com/s/16QhhYCppSvuUikhKiOHNgg?pwd9LJY 提取码&#xff1a;9LJY C:\Users\leyilea> python // 测试python能不能用 >>> exit() // 退出 测试sqlmap是否可用 kali中运行sqlmap&#xff…...

WPF学习(12)-Image图像控件+GroupBox标题容器控件

Image图像控件 Image也算是独门独户的控件&#xff0c;因为它是直接继承于FrameworkElement基类。 Image控件就是图像显示控件。Image类能够加载显示的图片格式有.bmp、.gif、.ico、.jpg、.png、.wdp 和 .tiff。要注意的是&#xff0c;加载.gif动画图片时&#xff0c;仅显示第…...

【Linux】基础IO认知

文件 1、回顾C语言中的文件接口2、对文件的理解(阶段一)3、文件操作3、1、C的文件操作接口3、2、认识系统调用接口3、2、强化对fd文件描述符及周边知识的理解 1、回顾C语言中的文件接口 事实上&#xff0c;我们在C语言的学习中了解的文件并不是真正的文件。从语言角度来说&…...

7. Kubernetes核心资源之Service服务实战

**service分类 : ** **ClusterIP : ** 默认类型&#xff0c;自动分配一个【仅集群内部】可以访问的虚拟IP **NodePort : ** 对外访问应用使用&#xff0c;在ClusterIP基础上为Service在每台机器上绑定一个端口&#xff0c;就可以通过: ipNodePort来访问该服务 **LoadBalanc…...

《向量数据库指南》——企业采用非结构化数据的场景及其深远影响

引言 在当今数字化转型的浪潮中,企业数据的种类与规模正以前所未有的速度增长,其中非结构化数据作为信息时代的重要组成部分,其价值日益凸显。Lynn提出的关于企业最先采用非结构化数据的观察,引发了我们对这一领域深入探索的兴趣。Charles的见解则为我们揭示了非结构化数据…...

Linux内核编程(十二)热插拔

本文目录 一、知识点1. 热插拔概念2. 热插拔机制3. Netlink机制 二、内核发送uevent事件到用户空间1. kobject发送uevent事件2. udevadm命令查看★示例代码&#xff1a;★优化&#xff1a;完善kset_uevent_ops&#xff08;热插拔事件结构体&#xff09; 三、用户空间使用Netlin…...

七夕警示:探索社工库与网络搜索下的个人隐私泄露与保护策略

随着七夕节的脚步日益临近&#xff0c;空气中弥漫着浪漫与温馨的气息。这个充满爱意的节日&#xff0c;我们沉浸在与心爱之人共享甜蜜时光的同时&#xff0c;不应忽视网络安全和个人隐私保护的重要性。在数字化时代&#xff0c;个人信息泄露的风险无处不在&#xff0c;如何在享…...

Redis-哨兵监控(sentinel)

是什么 Docs 吹哨人巡查监控后台master主机是否故障&#xff0c;如果故障了根据投票数自动将某一个从库转换为新主库&#xff0c;继续对外服务 作用:无人值守运维 能干嘛 1.主从监控 监控主从redis的库是否运行正常 2.消息通知 哨兵可以将故障转移的结果发送给客户端 3.…...

RISC-V反汇编调试记录分享

RISC-V反汇编调试记录分享 本文记录一次使用反汇编进行调试分析。 最近在 rtthread 下适配 MilkV Duo 的硬件定时器驱动时遇到了一些问题&#xff0c;demo 运行时报以下错误&#xff1a; Unhandled Exception 2:Illegal Instruction scause:0x0x0000000000000002,stval:0x0x…...

python上下文管理器 with的使用

python上下文管理器 with是从Python一个语法糖&#xff0c;它是一种上下文管理协议&#xff0c;目的在于把我们之前常见一个开发 try,except 和finally 关键字和一些文件开关闭合资源分配释放等问题都简化。 总结起来使用python 提供的with主要的作用是&#xff1a; 实现自动…...

OpenClaw版本升级指南:Phi-3-mini-128k-instruct无缝迁移到最新框架

OpenClaw版本升级指南&#xff1a;Phi-3-mini-128k-instruct无缝迁移到最新框架 1. 为什么需要升级OpenClaw&#xff1f; 上周我在处理一个自动化文档整理任务时&#xff0c;突然发现OpenClaw对Phi-3-mini-128k-instruct模型的调用开始频繁报错。经过排查才发现&#xff0c;原…...

React 自定义 Hook 的命名规范与调用规则详解

React 允许在普通函数中调用 Hook&#xff0c;但该函数必须是符合约定的自定义 Hook&#xff08;即以 use 开头&#xff09;&#xff0c;且只能在 React 组件或其它自定义 Hook 内部调用&#xff1b;违反规则虽不一定立即报错&#xff0c;却会破坏依赖追踪、导致状态异常或未来…...

Windows内核级游戏控制器模拟驱动实战指南

Windows内核级游戏控制器模拟驱动实战指南 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 在Windows平台上实现游戏控制器完美模拟一直是技术爱好者和游戏玩…...

嵌入式开发必备硬件知识解析与应用

1. 嵌入式开发与硬件的关系解析作为一名在嵌入式领域摸爬滚打多年的工程师&#xff0c;我经常被新人问到一个经典问题&#xff1a;"做嵌入式软件开发是不是可以完全不懂硬件&#xff1f;"我的回答永远是&#xff1a;你可以选择不精通&#xff0c;但绝对不能完全不懂。…...

OpenClaw技能市场挖掘:千问3.5-9B增强插件TOP5

OpenClaw技能市场挖掘&#xff1a;千问3.5-9B增强插件TOP5 1. 为什么需要关注OpenClaw技能市场&#xff1f; 第一次接触OpenClaw时&#xff0c;我以为它只是个简单的自动化脚本工具。直到在项目里连续熬了三个深夜处理邮件分类和会议纪要&#xff0c;才意识到自己错过了什么—…...

AITINKR_JSON_FIELDS:面向MCU的零碎片JSON字段管理库

1. AITINKR_JSON_FIELDS 库深度解析&#xff1a;面向资源受限 IoT 设备的动态 JSON 字段管理方案在嵌入式物联网设备开发中&#xff0c;JSON 已成为事实上的数据交换标准。从传感器数据上报、OTA 配置下发&#xff0c;到设备状态同步与远程控制指令解析&#xff0c;JSON 的轻量…...

零信任架构下的企业数据安全防护体系设计与实践

1. 零信任架构&#xff1a;企业数据安全的新范式 过去十年我见过太多企业安全事件&#xff0c;根源往往在于传统边界防护的失效。某次给金融客户做安全评估时发现&#xff0c;他们花重金部署的防火墙就像个筛子——攻击者通过一个普通员工的钓鱼邮件就长驱直入&#xff0c;最终…...

解决Flutter RefreshIndicator在单一列表项下的显示问题

在开发Flutter应用时,RefreshIndicator是一个非常有用的控件,它可以为列表视图提供下拉刷新的功能。然而,当列表中只有一个项目时,RefreshIndicator可能会遇到一个常见的问题:它不会显示。这篇博客将详细探讨这个问题的解决方案,并提供一个具体的实例。 问题描述 假设我…...

Lisk SDK安全最佳实践:保护区块链应用免受攻击的10个技巧

Lisk SDK安全最佳实践&#xff1a;保护区块链应用免受攻击的10个技巧 【免费下载链接】lisk-sdk &#x1f529; Lisk software development kit 项目地址: https://gitcode.com/gh_mirrors/li/lisk-sdk Lisk SDK是一款强大的区块链应用开发工具包&#xff0c;专为构建安…...

深入OTTO音序器:创建复杂节奏和自动化控制的完整指南

深入OTTO音序器&#xff1a;创建复杂节奏和自动化控制的完整指南 【免费下载链接】OTTO Sampler, Sequencer, Multi-engine synth and effects - in a box! [WIP] 项目地址: https://gitcode.com/gh_mirrors/otto1/OTTO OTTO是一款开源的数字硬件合成器、节奏盒和效果处…...