博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
判断App是否在后台运行
阅读量:5159 次
发布时间:2019-06-13

本文共 2019 字,大约阅读时间需要 6 分钟。

在一些场景中,经常会需要判断App是否在后台运行,比如是否显示解锁界面,收到新消息是否显示Notification等。需求可能是多样化的,但所依仗的原理是相通的,今天Stay打算说说这些需求的最优解。

当然,Stay肯定不会说去for loop判断当前runningProcess或者runningTasks。比如:

这样

或者这样

这种方法调用起来感觉就像是在用Windows系统里的任务管理器,真是让人蛋疼。我们暂且不去计较性能问题,就说为啥Android连个像样的API都不给我,着实让人郁闷。

如果带着这样的质疑去调研,你会发现还真有其他方式来实现。

Android在SDK 14的时候提供了一个Callback。ActivityLifecycleCallbacks,你可以通过这个Callback拿到App所有Activity的生命周期回调。看图:

这个Callback写在Application里的,你可以在Application初始化的时候来注册。我们可以写个单例类来cache这些status。这里我叫它AppStatusTracker。在Application的onCreate()里让AppStatusTracker注册ActivityLifecycleCallbacks。

拿到这些Callback有什么用呢,我怎么能知道App是否在前台运行呢。 

别急,我们先来说说Activity的生命周期。这是面试时必问题,虽然有官方答案,但真正理解生命周期,并灵活运用的不多。

我们来设想下如果Activity调用了onResume(),那么这个Activity肯定是可见的,也就是运行在前台的。如果调用了onPause(),且没有Activity来调用onResume(),那么App要跑到后台去了。至于它是点了home键还是back键我都不管。

通过这样的判断,我们来利用ActivityLifecycleCallbacks回调的onActivityResumed()和onActivityPaused()方法来计数,如果只有一个activityCount,那么当前App在前台,如果木有activityCount,它就在后台。

好了,就这么愉快的解决了,再也不用for loop了。但是很快你会发现,这里有个延时,会导致判断不准确。

我们假设有两个Activities,一个A,一个B,从A跳转到B,生命周期怎么走的? A.onPause() -> B.onResume() 对应到ActivityLifecycleCallbacks里是onActivityPaused(A) -> onActivityResumed(B),刚才我们说的计数resumeCount,在onActivityPaused()里--,在onActivityResumed()里++, 根据这样的判断会有个短暂的间隔,也就是在A的onPause()到B的onResume()之间,App是运行在后台的,这样逻辑肯定就不对了。

那如何解决问题呢?如果你打印过生命周期的哪些方法,你会发现是Activity间切换的步骤是这样的: 

从WelcomeActivity跳转到GestureActivity。(这里只说onStart, onResume这些回调 )
A.onPause() -> B.onStart() -> B.onResume() -> A.onStop()

我估摸着60%的同学都没想过Activities之间切换的生命周期是什么样的。

 

通过这些回调我们可以将这个计数放在onStart()和onStop()中去,这样就不会存在那个短暂间隔。activityCount==1,那么就是前台,activityCount==0,那就是后台。这样判断很很简单了吧。

现在再说,什么情况下来显示手势解锁界面。 

我的需求是当用户锁屏后再解锁或者切换到后台10分钟后显示手势解锁界面。 
我们拆分下需求,先说锁屏,解锁。

这个是有BroadCastReciever来接收的,注册下就可以了,每次收到锁屏ACTION_SCREEN_OFF的action时,将AppStatusTracker里的isScreenOff设置为true。 

当onActivityResumed()被调用时再将isScreenOff设为false。

再说切换到后台10分钟后显示手势解锁。这个只需要在onActivityStop()时更新下lastBackgroudTimestamp就可以了

核心代码如下:

原理很简单,但是涉及到的知识点很重要,大家可以自己写写测试下,别总依赖别人的代码,别人的类库,技术实现很简单,但需求的变体扩展有时候还是需要自己来想办法解决的。

转载于:https://www.cnblogs.com/dongweiq/p/5062474.html

你可能感兴趣的文章
win10 下 protobuf 与 qt
查看>>
在Linux中设置共享目录
查看>>
随笔记
查看>>
零基础逆向工程16_C语言10_宏定义_头文件_内存分配_文件读写
查看>>
Map,HashMap,LinkedHashMap,TreeMap比较和理解
查看>>
【公告】新博客、新地址,欢迎交换友链
查看>>
几年前毕业设计做的CAD二次开发
查看>>
命名空间
查看>>
索引的创建和使用
查看>>
Bouncy Castle内存溢出
查看>>
多线程_java多线程环境下栈信息分析思路
查看>>
机器学习数学【1】
查看>>
Problem E: Automatic Editing
查看>>
Java数组排序
查看>>
SpringBoot 使用 MyBatis 分页插件 PageHelper 进行分页查询
查看>>
《DSP using MATLAB》Problem 6.17
查看>>
微信公众平台开发实战Java版之如何网页授权获取用户基本信息
查看>>
beta阶段第一次scrum meeting
查看>>
一周TDD小结
查看>>
(三)建筑物多边形化简系列——去除冗余点
查看>>