Android 监听APP进入后台或切换到前台方案对比
在我们开发的过程中,经常会遇到需要我们判断app进入后台,或者切换到前台的情况。比如我们想判断app切换到前台时,显示一个解锁界面,要求用户输入解锁密码才能继续进行操作;我们想判断app切换到后台,记录一下log;或者当用户切换回前台时,我们想刷新一下页面的数据等等......
android里面监听app前后台的方案很多(这还是得归根于安卓提供了丰富的api和强大的架构支撑,呵呵~),比如可以通过ActivityManager提供的getRunningAppProcesses()获取系统当前运行的app,从而判断app是否处于前台。或者通过监听点击Home键,判断app是否回到了后台。下面将针对笔者已知的几种方案,进行对比分析。
方案一:利用ActivityManager的RunningAppProcessInfo类
ActivityManager在整个系统里面起着非常重要的作用,主要为系统中运行着的activity交互提供接口,其中RunningAppProcessInfo类则封装了正在运行着的进程信息,当然也包含了正在运行的app的包名,因此我们可以activitymanager.getRunningAppProcesses()获取当前运行的app列表,对比自身的包名,来判断本身app是否处于前台运行。
这打断一下,ActivityManager框架是Android系统十分重要的一部分,在以后有时间,笔者会好好学习整理ActivityManager框架的分析。
回到这里,下面给出部分关键代码。
/**
* App前后台状态
*/
public boolean isForeground = false;
@Override
protected void onResume() {
......
if (isForeground == false) {
//由后台切换到前台
isForeground = true;
}
} @Override
protected void onPause() {
......
if (!isAppOnForeground()) {
//由前台切换到后台
isForeground = false;
}
}
/**
* 判断app是否处于前台
*
* @return
*/
public boolean isAppOnForeground() { ActivityManager activityManager = (ActivityManager) getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE);
String packageName = getApplicationContext().getPackageName();
/**
* 获取Android设备中所有正在运行的App
*/
List<RunningAppProcessInfo> appProcesses = activityManager
.getRunningAppProcesses();
if (appProcesses == null)
return false; for (RunningAppProcessInfo appProcess : appProcesses) {
// The name of the process that this object is associated with.
if (appProcess.processName.equals(packageName)
&& appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
} return false;
}
小结:通过ActivityManager来获取当前运行的app列表,然后判断我们的app是否处于前台,能基本达到我们的预期需求。但如果将上面代码放到每一个activity,或者activity基类里面,这消耗还是挺大的。而且而且,ActivityManager通过.getRunningAppProcesses()获取当前运行列表这个方法,在5.0以后已经被deprecated掉了....(心中万马奔腾...)
方案二:监听Home键点击
说起home键的监听,也算是android里面的一个梗。这看上去简单的功能,实际上实现起来却十分的曲折,这跟android系统的设计有很大的关系。当home键被点击的时候,会发出一个系统广播,在系统收到这个广播以后,会在framework层做一系列操作将当前的app退到后台,然后把事件消费掉不传给应用层,所以这时候 onKeyDown事件也接收不到了..用官方的解释就是——“Home key. This key is handled by the framework and is never delivered to applications.”。实际上这也是为了安全性的考虑,不然每家的app都监听home键,然后禁掉响应,不都成了流氓软件了。
官方不支持,可是这难不到我们万能的攻城狮们的,毕竟有很多想我们正规的开发者,还是需要监听home键来做一些如写日志之类的操作的。网上谷歌百度会有很多类似的解决方案,在这里就不展开了。(不过这里可以推荐一下)
小结:我们能监听到home键点击,当然就知道app处于前台还是后台了。但毕竟这个方案是基于官方不支持的前提下的,而且home键的监听在很多设备都会有兼容性的问题,因此我们不大推荐这样做。
方案三:利用ActivityLifecycleCallbacks监听所有activity的生命周期
通过监听所有activity的onStart、onStop调用,然后统计当前是不是所有的activity都调用了onStop,确实可以判断app处于了后台,不过让我们重写每一个activity的onStop,并加这段奇怪的代码,实在不大优雅,即使在activity基类里面统一写,那天如果忘了或者不需要继承基类的activity,就不大好了。
因此,这里推荐一个新的接口ActivityLifecycleCallbacks,说新也不新,其实早在API 14 (android 4.0)就已经推出了。ActivityLifecycleCallbacks接口在Application类里面,因此需要我们自己继承Application,自定义一个MyApplication,然后注册接口。ActivityLifecycleCallbacks为application提供了对所有activity生命周期的监听,因此我们通过重写ActivityLifecycleCallbacks的onActivityStarted和onActivityStopped方法,定义一个变量,来统计当前有几个activity处于前台。
/**
* 当前Acitity个数
*/
private int activityAount = ; @Override
public void onCreate() {
......
registerActivityLifecycleCallbacks(activityLifecycleCallbacks);
......
} /**
* Activity 生命周期监听,用于监控app前后台状态切换
*/
ActivityLifecycleCallbacks activityLifecycleCallbacks = new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
} @Override
public void onActivityStarted(Activity activity) {
// if (activityAount == 0) {
// //app回到前台
// isForeground = true;
// }
activityAount++;
} @Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
} @Override
public void onActivityStopped(Activity activity) {
activityAount--;
if (activityAount == ) {
isForeground = false;
}
} @Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
};
以上代码写在MyApplication里面。怎么样,是不是很简单快捷!而且准确无误。
总结:
1、利用ActivityManager的RunningAppProcessInfo类,直接粗暴,官方摒弃,不推荐;
2、监听Home键点击,官方不支持,兼容性差,不稳定,不推荐;
3、利用ActivityLifecycleCallbacks监听所有activity的生命周期,官方指定饮品,哦,不对,官方指定接口,大力推荐!我们举一反三,利用ActivityLifecycleCallbacks监听,我们还能控制我们的activity堆栈,甚至还可以在里面做日志统计...想想还是很强大的。
PS:虽则利用ActivityLifecycleCallbacks接口监听的方案最优,但这毕竟是4.0以后的产品,因此对于4.0以下的,可以考虑增加方案一判断。
Android 监听APP进入后台或切换到前台方案对比的更多相关文章
- android 监听app进入后台以及从后台进入前台
package com.pinshang.base; import com.pinshang.common.CommonValue; import com.pinshang.investapp.Ent ...
- ios 监听app从后台恢复到前台
正常情况下,在AppDelegate中实现下面两个方法,能够监听从后台恢复到前台 [cpp] - (void)applicationDidEnterBackground:(UIApplication ...
- Cocos Creater 监听程序到后台和重新到前台
cocos creator前后台切换当玩家在玩游戏时,突然接了一个电话,此时游戏会被切到后台待机,所有的声音播放都会停止,等打完电话,回到游戏,游戏又会被切回前台来,需要手动播放声音.可使用如下代码 ...
- Android监听来电和去电
要监听android打电话和接电话,只需下面2步骤1.第一步,写一个Receiver继承自BroadcastReceiver import android.app.Service; import an ...
- Android监听ScrollView滑动到顶端和底部
Android监听ScrollView滑动到顶端和底部 package cn.testscrollview; import android.os.Bundle; import android. ...
- Android 监听 WiFi 开关状态
Android 监听 WiFi 开关状态 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/70854309 本文出自[赵彦军的博客] ...
- Android监听系统短信数据库变化-提取短信内容
由于监听系统短信广播受到权限的限制,所以很多手机可能使用这种方式没法监听广播,从而没办法获取到系统短信,所以又重新开辟一条路. Android监听系统短信数据库内容变化使用场景: 1.监听短信数据库的 ...
- Android监听返回键、Home键+再按一次返回键退出应用
Android监听返回键需重写onKeyDown()方法 Home键keyCode==KeyEvent.KEYCODE_HOME @Override public boolean onKeyDown( ...
- Android监听应用程序安装和卸载
Android监听应用程序安装和卸载 第一. 新建监听类:BootReceiver继承BroadcastReceiver package com.rongfzh.yc; import android. ...
随机推荐
- Sublime Text3安装、配置及常用插件(陆续补全中~)
一.安装Sublime Text3 网址:http://www.sublimetext.com/3 注册码:(sublime Text3汉化和激活注册码) ----- BEGIN LICENSE -- ...
- linux线程切换和进程切换
进程切换分两步: 1.切换页目录以使用新的地址空间 2.切换内核栈和硬件上下文 对于linux来说,线程和进程的最大区别就在于地址空间,对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的. ...
- php屏蔽错误消息
定义和用法: error_reporting() 设置 PHP 的报错级别并返回当前级别. 函数语法: error_reporting(report_level) 如果参数 level 未指定,当前报 ...
- opencv-机器学习章节介绍
概念 1.机器学习:训练样本,特征,分类器.最需要的是特征. 2.深度学习:海量的训练数据,神经网络.最需要的是样本多一些. 特征 Hear特征一般是人脸检测用到的 Hog特征一般是物体检测用到的 分 ...
- 移动app整合个推进行消息推送
首先前端代码写好之后进行发行打包: 然后再进行发行打包: 然后登录个推官网: 测试: 点击推送,在手机端就可以获取到信息了. java代码测试: package com.cxy.bean; impor ...
- LCA最近公共祖先模板(求树上任意两个节点的最短距离 || 求两个点的路进(有且只有唯一的一条))
原理可以参考大神 LCA_Tarjan (离线) TarjanTarjan 算法求 LCA 的时间复杂度为 O(n+q) ,是一种离线算法,要用到并查集.(注:这里的复杂度其实应该不是 O(n+q) ...
- 毕业设计 python opencv实现车牌识别 界面
主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https://github.com/yinghualuow ...
- 江西财经大学第一届程序设计竞赛 F
链接:https://www.nowcoder.com/acm/contest/115/F来源:牛客网 题目描述 对于方程 2018 * x ^ 4 + 21 * x + 5 * x ^ 3 + 5 ...
- 衡量DevOps成功的15个标准
DevOps在你的组织中运行的如何?如果你需要帮忙衡量它运行的如何,我们准备了一些DevOps的关键指标来进行追踪.这些指标可以帮助理解你的团队过去做的如何. 定义DevOps对你的组织意味着什么 D ...
- 微软原版SQL Helper
代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-- ...