版权声明:
本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有。
未经允许,不得转载。
一、前言
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 现在看来确实挺鸡肋的,它有什么使用场景,就只能发挥想象力了。