背景
我们想启动 APK 程序,有很多种方法,可以使用 Intent,也可以使用 adb shell 命令来启动,还有通过反射来启动 APk 程序。
我们这里主要讨论通过反射的方式来启动 apk 程序。Android10 之前,我们通过反射来启动 APK,反射的是 startActivityAndWait(…) 方法,该方法是在 IActivityMessage.java 实现的,通过来启动 APk 程序。
在 Android10 的时候,该方案不太适用,需要反射 shellCommand(…) 来启动 Android 系统 10 的 APK 程序。
本方案是基于 AM 启动 Activity 的方式来实现的。
核心技术方案和原理图
Android 10 为了增加安全性 IActivityMessage.java 类去掉了,变为 IActivityMessage.aidl 文件,其中 startActivityAndWait(…) 方法转移到了 ActivityManagerServer.java 服务类中。所以,我们不能使用 IActivityMessage.java 去执行 startActivityAndWait(…) 方法。
Android 10 AM.java 启动源码:
Android 10 原先 AM.java 功能逻辑转移到 ActivityManagerShellCommand.java 源码如下:
我们要反射 mAm.asBinder().shellCommand 来启动 APK。方案实现时序图如下:
技术优势
兼容了 Android10 通过反射启动 APK 。
技术实现
1.首先获取 ActivityManagerNative 类对象。
2.获取 IActivityManager 对象。
3.获取当前的手机系统版本。
4.调用 IActivityManager 中的 asBinder 方法,可以通过该方法获取 BinderProxy 对象。
5.反射获取 ShellCallback 类对象和 ResultReceiver 类对象。
6.获取 shellCommand 方法。
7.调用 shellCommand 方法。
整体实现代码
效果展示
Android 10 手机
  运行成功 cmd 界面截图
  启动成功后的 APK 界面