前言

最近在工作中遇到了这么一个需求:如何实现 Android 应用前后台切换的监听?下面来一起看看详细的介绍:
iOS 内边是可以实现的,AppDelegate 给了一个回调监听:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
}
我保留了系统注释。一个iOS应用周期,大概的流程是这样的。
应用从前台进入到后台:
applicationWillResignActive() -> applicationDidEnterBackground()
应用从后台恢复到前台:
applicationWillEnterForeground() -> applicationDidBecomeActive()
Android 中也存在 Application,但是并没有提供前后台切换的监听。
倒不如说,在 Android 中,压根就没有应用前后台的概念。
Android 中基本页面单位是 Activity。
Activity 有自己的生命周期,但是 Application 却没有一个整体的生命周期。
我们可以通过监听 Activity 的生命周期,来模拟实现一个 Application 的生命周期。
Activity 的生命周期不在阐述,写过 Android 的都应该知道。
我们假设现在有两个 Activity 分别是 A 和 B,A 是启动页面,那么生命周期回调是这样的:(我们忽略掉一些不关心的回调)
A 被启动或者 A 进入前台
A.onStart() A.onResume()
从 A 跳转到 B:
A.onPause() B.onStart() B.onResume() A.onStop()
从 B 返回 A:
B.onPause() A.onStart() A.onResume() B.onStop()
A 被关闭或者 A 进入后台
A.onPause() A.onStop()
注意上面两个页面回调的启动顺序。
onResume 和 onPause 是一组,两个页面之间是顺序调用。
onStart 和 onStop 是一组,两个页面之间是交叉调用。
也就是说,A 启动到 B,会先调用 B.onStart() ,然后再调用 A.onStop() ;而 B 返回 A 则是相反的,会先调用 A.onStart() ,然后再调用 B.onStop() 。
利用这个特性,我们可以做一个全局计数器,来记录前台页面的数量,在所有 Activity.onStart() 中计数器 +1,在所有 Activity.onStop() 中计数器 -1。计数器数目大于0,说明应用在前台;计数器数目等于0,说明应用在后台。计数器从1变成0,说明应用从前台进入后台;计数器从0变成1,说明应用从后台进入前台。
有了思路,我们来实现。
Application 提供了一个监听器用于监听整个应用中 Activity 声明周期:Application.ActivityLifecycleCallbacks 。
这个监听器要求 API >= 14。对应 API < 14 的情况,可以通过编写一个 BaseActivity,然后让所有的 Activity 都集成这个类来实现整个应用 Activity 声明周期的监听,效果是相同的。
API >= 14,实现如下:
public class ApplicationListener implements Application.ActivityLifecycleCallbacks {
private int foregroundCount = 0; // 位于前台的 Activity 的数目
@Override
public void onActivityStarted(final Activity activity) {
if (foregroundCount <= 0) {
// TODO 这里处理从后台恢复到前台的逻辑
}
foregroundCount++;
}
@Override
public void onActivityStopped(Activity activity) {
foregroundCount--;
if (foregroundCount <= 0) {
// TODO 这里处理从前台进入到后台的逻辑
}
}
/*
* 下面回调,我们都不需要
*/
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
@Override
public void onActivityResumed(Activity activity) {}
@Override
public void onActivityPaused(Activity activity) {}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
@Override
public void onActivityDestroyed(Activity activity) {}
}
我们在 Application 中注册这个监听器来发挥效果:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ApplicationListener());
}
}
对于 API < 14 的情况,BaseActivity 实现如下:
public class BaseActivity extends AppCompatActivity {
private static int foregroundCount = 0; // 注意是个静态变量
@Override
protected void onStart() {
super.onStart();
if (foregroundCount <= 0) {
// TODO 这里处理从后台恢复到前台的逻辑
}
foregroundCount++;
}
@Override
protected void onStop() {
foregroundCount--;
if (foregroundCount <= 0) {
// TODO 这里处理从前台进入到后台的逻辑
}
super.onStop();
}
}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如有疑问大家可以留言交流,谢谢大家对的支持。
# android
# 监听应用切换
# 网络切换监听
# 网络监听
# 深入解析Android系统中应用程序前后台切换的实现要点
# Android开发中实现应用的前后台切换效果
# Android切换前后台点击通知进入当前页面
# 回调
# 是这样
# 我们可以
# 然后再
# 用在
# 来实现
# 会先
# 自己的
# 是个
# 都不
# 如有
# 则是
# 可以通过
# 给了
# 做一个
# 可以实现
# 这篇文章
# 中也
# 谢谢大家
# 却没
相关文章:
建站之星如何取消后台验证码生成?
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
如何在宝塔面板中创建新站点?
小说建站VPS选用指南:性能对比、配置优化与建站方案解析
杭州银行网站设计制作流程,杭州银行怎么开通认证方式?
建站主机如何安装配置?新手必看操作指南
制作网站建设的公司有哪些,网站建设比较好的公司都有哪些?
专业网站建设制作报价,网页设计制作要考什么证?
如何在阿里云通过域名搭建网站?
如何基于云服务器快速搭建网站及云盘系统?
头像制作网站在线制作软件,dw网页背景图像怎么设置?
建站之星在线版空间:自助建站+智能模板一键生成方案
建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略
胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?
如何在建站宝盒中设置产品搜索功能?
建站之星云端配置指南:模板选择与SEO优化一键生成
网站制作公司排行榜,四大门户网站排名?
如何在IIS中新建站点并解决端口绑定冲突?
制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?
如何通过远程VPS快速搭建个人网站?
活动邀请函制作网站有哪些,活动邀请函文案?
企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?
建站主机是否属于云主机类型?
如何快速上传建站程序避免常见错误?
如何选择CMS系统实现快速建站与SEO优化?
建站之星后台管理如何实现高效配置?
如何选择网络建站服务器?高效建站必看指南
成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?
如何高效利用200m空间完成建站?
长沙做网站要多少钱,长沙国安网络怎么样?
如何零基础开发自助建站系统?完整教程解析
定制建站平台哪家好?企业官网搭建与快速建站方案推荐
实现虚拟支付需哪些建站技术支撑?
常州企业网站制作公司,全国继续教育网怎么登录?
开封网站制作公司,网络用语开封是什么意思?
建站主机SSH密钥生成步骤及常见问题解答?
C#如何使用XPathNavigator高效查询XML
如何在IIS服务器上快速部署高效网站?
实例解析angularjs的filter过滤器
ppt在线制作免费网站推荐,有什么下载免费的ppt模板网站?
太原网站制作公司有哪些,网约车营运证查询官网?
建站主机与服务器功能差异如何区分?
专业商城网站制作公司有哪些,pi商城官网是哪个?
如何在云主机上快速搭建多站点网站?
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
装修招标网站设计制作流程,装修招标流程?
c# 在高并发下使用反射发射(Reflection.Emit)的性能
已有域名能否直接搭建网站?
代刷网站制作软件,别人代刷火车票靠谱吗?
建站之星收费标准详解:套餐费用及年费价格表一览
*请认真填写需求信息,我们会在24小时内与您取得联系。