在一些场景中,经常会需要判断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就可以了

核心代码如下:

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

 

判断App是否在后台运行的更多相关文章

  1. Android 判断APP前台,后台运行

    public void checkAppState() { ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVI ...

  2. Android判断App是否在前台运行(转)

    原文地址: http://blog.csdn.net/zuolongsnail/article/details/8168689 Android开发中,有时候需要判断App是否在前台运行. 代码实现如下 ...

  3. APP长时间后台运行

    *  参考:http://www.nivalxer.com/archives/187 首先,我要说明的是在iOS中,一般应用程序在后台挂起之后仅拥有3分钟时间来处理相应的未完成事件,但是3分钟之后就会 ...

  4. 判断app是否在后台

    1.通过RunningTaskInfo类判断(需要额外权限):(测试通过5.1可用,权限名称修改 <uses-permission android:name="android.perm ...

  5. [UWP小白日记-1]判断APP是否是第一次运行初始化SQLITE数据库

    利用应用程序设置来实现此功能. 1.首先,获取APP设置的容器: ApplicationDataContainer localSettings = ApplicationData.Current.Lo ...

  6. Android判断App是否在前台运行

    版权声明:本文为博主原创文章,未经博主允许不得转载. //当前应用是否处于前台 private boolean isForeground(Context context) { if (context ...

  7. Android 判断app是否在前台运行

    <!-- 前台还是后台 --> <uses-permission android:name="android.permission.GET_TASKS" /> ...

  8. 判断App运行是否在前台

    转自:http://notes.stay4it.com/2016/02/26/check-if-app-is-running-forground/ 在一些场景中,经常会需要判断App是否在后台运行,比 ...

  9. 原创翻译:iOS 应用程序 蓝牙后台运行

    默认情况下,普通的CoreBluetooth 任务中的大多数,无论是Central还是peripheral ,在后台或者挂起状况下都是无法进行的.也就是说,你可以通过宣布你的应用程序支持后台处理模式来 ...

随机推荐

  1. 简述memcached中的一致哈希

    memcached是一个开源的高性能分布式内存对象缓存系统. 其实思想还是比较简单的,实现包括server端(memcached开源项目一般只单指server端)和client端两部分: server ...

  2. FZU 2165 v11(最小重复覆盖)+ codeforces 417D Cunning Gena

    告诉你若干个(<=100)武器的花费以及武器能消灭的怪物编号,问消灭所有怪物(<=100)的最小花费...当然每个武器可以无限次使用,不然这题就太水了╮(╯▽╰)╭ 这题当时比赛的时候连题 ...

  3. KV6.60 SP1

    组态王6.60 SP1全新发布! 组态王6.60 SP1对过去几年6系列中已解决过的故障进行了合并,包括各主线分支.各OEM版本中的故障总计122个,覆盖运行系统.开发系统.历史趋势曲线控件.报表.A ...

  4. July 1st, Week 27th Friday, 2016

    It does not do to dwell on dreams, and forget to live. 不要生活在梦里,不要沉醉于空想而疏忽了生活. Stand straightly, and ...

  5. Linux安装xwindow图形界面

    在我们安装Linux系统时,刚开始的时候可能没有安装图形界面的需要,但在使用过程中却有可能产生这种需求.那么这种情况下,我们需不需要重新安装Linux系统来安装桌面呢?答案是不需要.下面我将交大家在已 ...

  6. monkey测试

    一.理解monkey测试 1.Monkey测试是Android自动化测试的一种手段.Monkey测试本身非常简单,就是模拟用户的按键输入,触摸屏输入,手势输入等,看设备多长时间会出异常. 2.当Mon ...

  7. php连接sql server

    这两天有个php连接sql server的项目,顺便学习学习sql server  说明: 1:PHP5.2.x本身有个php_mssql.dll的扩展用来连接Sql server,但是这个dll只是 ...

  8. mysql优化学习笔记

    优化sql的一般步骤 通过show status了解各种sql的执行频率 定位执行效率低的sql语句 通过explain分析效率低的sql 通过show profile分析sql 通过trace分析优 ...

  9. Jquery.Datatables 服务器处理(Server-side processing)

    看了看介绍 http://datatables.club/manual/server-side.html 没有经过处理的分页,先显示出来看看效果,就这样写(存储过程自己写) cshtml " ...

  10. Shell编程基础教程3--Shell输入与输出

    3.Shell输入与输出    3.1.echo        echo命令可以显示文本行或变量,或者把字符串输出到文件        echo [option] string             ...