一、前言
Android Support v4 一直作为一个向下兼容的库而存在,而从 23.3.0 开始,增加了一个 AppLaunchChecker 的类,用于判定当前的 App 是否被用户从桌面启动过。
这样一个功能,有点略显鸡肋,不过不影响我们去了解它。
二、AppLaunchChecker
1.1 存在的意义
看 Api Doc ,AppLaunchChecker 就是为了检查当前 App 是否被用户启动过,是一个用户行为。
***次看到这样的解释,可能会有歧义,如果 App 能做这样的检测,就说明当前处于运行阶段,所以很难想像这样的一个判断的意义在哪里。
而实际上,有一些 App ,是会提供一些其他服务给别的 App 使用的,例如最常见的系统相册的 App ,其他 App 是可以调用它来选择图片的,而无需从桌面去启动它,但是它的代码却被运行过。
AppLaunchChecker 就是为了做这种区分,标记是否有一个以用户行为为出发点,启动了你的 App。
1.2 它的 Api
AppLaunchChecker 的功能非常的简单,所以它的 Api 也相对简单。
它提供了一个 onActivityCreate() 的方法,供启动的 Activity 在 onCreate() 的时候调用,主要用于检测是否由用户从 Launcher App 中启动,又提供了一个 hasStartedFromLauncher() 方法来获取检测的结果。
这实际上也没什么好说的,既然这么简单,那我们进去看看它的实现原理。
先来看看 onActivityCreate() 的实现。
可以看到,它的原理就是通过启动 Activity 的 Intent 中的 Action 和 Category 来区分,这个看看代码就能知道,没什么好说的。
它会把判断的结果,存入 SharedPreferences 中,name 和 key 都在 AppLauncherChecker 中定义好了。
最终,需要在我们需要判断的时候,调用 hasStartedFromLauncher() 方法即可。
2.3 需要注意什么?
既然知道 AppLaunchChecker 的判断原理,那么它使用的时候还是有一些需要注意的。
1、需要在 App 的入口 Activity 中,调用 onActivityCreate()
因为现在大部分 App 的结果是有一个 SplashActivity 来放一个启动图,然后再去跳转到 MainActivity 。所以这样的情况下,就需要在 SplashActivity 的 onCreate() 中,调用 AppLaunchChecker.onActivityCreate() ,之后就可以在需要的地方去获取结果了。而在 MainActivity 中去检测的话,它的 Action 和 Category 都将是不正确的。
2、它只能判断是否曾经启动过
AppLaunchChecker.onActivityCreate() 方法,只有存储状态的,一旦存储将不会去修改它,所以只要有一次是用户启动的,通过 hasStartedFromLauncher() 方法获取到的值将永远是 true 。
3、它真的不准
既然它是通过 Action 和 Category 去做的判断,实际上这是不严谨的。只要是个 App ,通过 PackageManager 去启动你的 App ,它的 Action 和 Category 其实都是符合这里的判断条件的。
只要有 App 通过这样的方式启动,AppLaunchChecker 就会人为是用户行为。
看看 ApplicationPackageManager 中的实现,确实也是这样的。
三、结语
到这里就基本上明白了 AppLaunchChecker 的原理了,有一些人觉得它的值没有修改的时机,然后对 AppLaunchChecker 进行修改的逻辑,想在判断的地方加个 else ,修改它为 false。
现在看来,实际上这样的修改完全没有意义,通过正常走 PackageManager.getLaunchIntentForPackage() 去调起,必然会判断是用户启动的,否者也启动不起来。
AppLaunchChecker 现在看来确实挺鸡肋的,它有什么使用场景,就只能发挥想象力了。
【本文为51CTO专栏作者“张旸”的原创稿件,转载请通过微信公众号联系作者获取授权】