1.AMS/ATMS
在android10之前,android的四大组件统一由AMS进行管理;android10及之后,ATMS负责activity的相关管理,剩下的三大组件还是由AMS管理,不过在AMS中持有ATMS的引用。同时AMS也对进程、电池、内存、权限等进行管理。
注:AMS、ATMS服务都是在系统进程system server进程中。
2.Android系统启动
Android系统启动后Zygote进程第一个fork出SystemServer进程,ActivityManagerService是在SystemServer.java中启动的。
在SystemServer中会按顺序依次启动各个服务。
SystemServer.java:
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
...
//1.初始化 System Context
createSystemContext();
//2.创建SystemServiceManager对象,主要用来管理SystemService的创建和启动等生命周期
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo( mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService( SystemServiceManager.class, mSystemServiceManager);
...
//3.启动服务
startBootstrapServices(); //启动引导服务,在其中启动了ATM和AMS服务,通过AMS安装Installer、初始化Power,设置系统进程等
startCoreServices(); //启动核心服务
startOtherServices(); //启动其他服务
}
在SystemServer的run函数中,启动AMS之前,调用了createSystemContext函数,主要用来初始化System Context和SystemUi Context,并设置主题。
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
……
}
SystemServer初始化时ActivityThread.systemMain()创建的是系统进程(SystemServer进程)的主线程。
然后新建了SystemServiceManager对象,并将该对象保存到LocalServices中。然后通过三个方法启动各种服务。
AMS、ATM在startBootstrapServices函数里启动,WMS在startOtherServices函数里启动。
跟踪startBootstrapServices函数:
SystemServer.java:
private void startBootstrapServices() {
.....
//创建ATMS服务,并调用它的start方法
ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();
//创建AMS对象,并调用它的start方法(AMS中持有ATM的引用)
mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm);
mActivityManagerService.setSystemServic eManager(mSystemServiceManager);
mActivityManagerService.setInstaller( installer);
mActivityManagerService.initPowerManagem ent();
mActivityManagerService.setSystemProcess();
watchdog.init(mSystemContext, mActivityManagerService);
}
在这里创建了ATMS对象和AMS对象,并启动服务。
3.ATMS的启动
startBootstrapServices方法中通过ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();创建并启动ATMS服务。
进入SystemServiceManager类的startService()中继续看:
SystemServiceManager.java:
public <T extends SystemService>T startService( Class<T> serviceClass) {
final String name = serviceClass.getName();
if (!SystemService.class.isAssignableFrom( serviceClass)) {
throw new RuntimeException("Failed to create " + name + ": service must extend " + SystemService.class.getName());
}
//反射创建ATMS
final T service;
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
//启动服务
startService(service);
return service;
}
通过反射调用了ATMS的构造方法,创建了ATMS服务,然后调用startService(service)启动服务。
SystemServiceManager.java:
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
public void startService(final SystemService service) {
mServices.add(service); //注册服务
service.onStart(); //启动服务,调用ATMS.LifeCycle的onStart方法
}
在startService(service) 中通过service.onStart()调用了ATMS.LifeCycle的onStart方法启动服务。
ActivityTaskManagerService.java:
public static final class Lifecycle extends SystemService {
private final ActivityTaskManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityTaskManagerService(context);
}
public void onStart() {
publishBinderService( Context.ACTIVITY_TASK_SERVICE, mService);
mService.start();
}
}
其中publishBinderService方法是将ActivityTaskManagerService加入到ServiceManager中。
SystemService.java:
protected final void publishBinderService(String name, IBinder service) {
publishBinderService(name, service, false);
}
protected final void publishBinderService(String name, IBinder service, boolean allowIsolated) {
publishBinderService(name, service, allowIsolated, DUMP_FLAG_PRIORITY_DEFAULT);
}
protected final void publishBinderService(String name, IBinder service, boolean allowIsolated, int dumpPriority) {
ServiceManager.addService(name, service, allowIsolated, dumpPriority);
}
ServiceManager的addService()方法将ATMS与Context.ACTIVITY_TASK_SERVICE绑定,即将ATMS注册到ServiceManager统一管理,方便跨进程通信。这样其他进程中就可以通过如下方式获取ATMS:
IBinder b = ServiceManager.getService( Context.ACTIVITY_TASK_SERVICE);
IActivityTaskManager atm = IActivityTaskManager.Stub.asInterface(b);
4.AMS的启动
startBootstrapServices方法中通过mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm);创建并启动AMS服务。
进入ActivityManagerService.Lifecycle类:
ActivityManagerService.java:
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
private static ActivityTaskManagerService sAtm; //AMS中持有ATMS的信用
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService( context, sAtm); //创建AMS对象,主要完成一些对象的构造及变量的初始化。三大组件的管理和调度、监控内存、电池、权限以及性能相关的对象或变量
}
public static ActivityManagerService startService(SystemServiceManager ssm, ActivityTaskManagerService atm) {
sAtm = atm; //AMS中持有ATMS的信用
return ssm.startService( ActivityManagerService.Lifecycle.class).getService(); //startService()最终返回的是mService,即创建的AMS对象
}
@Override
public void onStart() {
mService.start(); //调用AMS的start()方法
}
public ActivityManagerService getService() {
return mService;
}
}
这里的Lifecycle是AMS的内部类。在AMS.Lifecycle的startService中,首先调用了SystemServiceManager的startService方法启动服务。
SystemServiceManager.java:
public <T extends SystemService>T startService( Class<T> serviceClass) {
final String name = serviceClass.getName();
if (!SystemService.class.isAssignableFrom( serviceClass)) {
throw new RuntimeException("Failed to create " + name + ": service must extend " + SystemService.class.getName());
}
//反射创建AMS
final T service;
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
//启动服务
startService(service);
return service;
}
SystemServiceManager.java:
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
public void startService(final SystemService service) {
mServices.add(service); //注册到ServiceManager列表中
service.onStart(); //启动服务
}
在startService(service) 中反射创建AMS并调用service.onStart()启动了服务。启动服务后通过getService()最终返回mService,即创建的AMS对象。
5.总结AMS的启动
①系统启动后Zygote进程第一个fork出SystemServer进程;
②SystemServer->run()->createSystemContext():创建了系统的ActivityThread对象,运行环境mSystemContext、systemUiContext;
③SystemServer->run()->startBootstrapServices()->ActivityManagerService.Lifecycle.startService():AMS在引导服务启动方法中,通过构造函数new ActivityManagerService()进行了一些对象创建和初始化(除activity外3大组件的管理和调度对象创建;内存、电池、权限、性能、cpu等的监控等相关对象创建),start()启动服务(移除进程组、启动cpu线程、注册权限、电池等服务);
④SystemServer->run()->startBootstrapServices()->setSystemServiceManager()、setInstaller()、initPowerManagement()、setSystemProcess():AMS创建后进行了一系列相关的初始化和设置。
setSystemProcess():将framework-res.apk的信息加入到SystemServer进程的LoadedApk中,并创建了SystemServer进程的ProcessRecord,加入到mPidsSelfLocked,由AMS统一管理。
⑤SystemServer->run()->startOtherServices():AMS启动后的后续工作,主要调用systemReady()和运行调用时传入的goingCallback。
systemReady()/goingCallback:各种服务或进程等AMS启动完成后需进一步完成的工作及系统相关初始化。 桌面应用在systemReady()方法中启动,systemui在goingCallback中完成。当桌面应用启动完成后,发送开机广播ACTION_BOOT_COMPLETED。
6.如何启动一个未注册的activity
了解完Activity的启动流程后,思考一个问题:如何启动后一个没有在清单文件中注册过的Activity呢?这里就要通过HOOK技术来实现了。Android Hook技术底层原理其实就是java的反射和动态代理。接下来通过HOOK技术取启动一个未注册的Activity。
①未使用HOOK,直接启动一个未注册的Activity
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn).setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(" com.example.hmxxx"," com.example.hmxxx.UnregisteredActivity"));
startActivity(intent);
}
});
}
}
如果UnregisteredActivity没有在AndroidManifest.xml中注册,则startActivity是会报错的,从源码角度看一下原因:
Instrumentation.java:
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
// whoThread被传递过去,用于在ATMS中传递消息到ActivityThread
int result = ActivityTaskManager.getService().startActivity(whoThread, who.getOpPackageName(), who.getAttributionTag(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
checkStartActivityResult(result, intent);//对result进行检查,有异常机会报错
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
startActivity执行后,会对result进行检查,有异常机会报错。在启动一个未注册的activity时的报错就是这里产生的,换句话说就是result的结果有问题,然后checkStartActivityResult在检查Result,发现了问题并抛了出来,根据之前分析的activity启动流程,可以知道result是在ActivityStarter的executeRequest产生的:
private int executeRequest(Request request) {
....
int err = ActivityManager.START_SUCCESS;
....
// 对启动的activity进行检查,要启动的activity未注册的秘密就是在这里被发现的,当发现要启动的acticvit未注册时,err就被赋予一个错误的值并返回回去
return err;
}
所以在启动一个未注册的activity时会报错。那么如何启动有个未注册的activity呢?打哪很明显了 ,那就是绕过atms的检查。
思路如上图:在AndroidManifest里面声明一个代理activity,然后在启动真实Activity的地方,将Intent里面的Activity替换成代理activity。然后等atms检查完acitivity是否在AndroidManifest文件中注册后,替换成需要启动的activity,便实现了启动一个未注册过的Activity的效果。
接下来找HOOK点,找HOOK点尽量静态变量单例(方便反射调用),public(因为public的就是谷歌鼓励使用的)。
按照上面的思路,要在startActivity(intent);之后、在intent交给atms检查之前,把要启动的一个未注册的activity换成一个已经注册的代理activity。
新建一个进行hook的工具类:
public class HookUtil {
private static final String TAG ="HookUtil" ;
public static void hookAMS() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class <?> clazz = Class.forName( "android.app.ActivityTaskManager");
Field singletonField = clazz.getDeclaredField( "IActivityTaskManagerSingleton");
singletonField.setAccessible(true);
Object singleton = singletonField.get(null);
Class<?> singletonClass = Class.forName("android.util.Singleton");
Field mInstanceField = singletonClass.getDeclaredField("mInstance");
mInstanceField.setAccessible(true);
Method getMethod = singletonClass.getMethod("get");
Object mInstance = getMethod.invoke(singleton);
Log.d(TAG, "invoke: hm test1");
Class IActivityTaskManagerClass = Class.forName("android.app.IActivityTaskManager");
Object InstanceProxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{IActivityTaskManagerClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("startActivity".equals( method.getName())) { // 方法名是startActivity时
int index = -1;
Log.d(TAG, "invoke: hm test");
// 获取Itent参数在args 数组中的index值
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof Intent) {
index = i;
break;
}
}
// 生成代理proxyIntent
Intent proxyIntent = new Intent();
// 这个包名是宿主的
proxyIntent.setClassName( "com.example.hmxxx","ProxyActivity");
// 原始的Intent丢掉吗? 保留原始的Intent对象
Intent intent = (Intent) args[index];
proxyIntent.putExtra( "TARGET_INTENT",intent);
}
return method.invoke(mInstance,args);
}
});
// 用代理的对象 替换系统的对象
mInstanceField.set(singleton,InstanceProxy);
}
}
MainActivity:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
HookUtil.hookAMS(); // 注意这里
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
findViewById(R.id.btn).setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.hmxxx"," com.example.hmxxx.UnregisteredActivity"));
startActivity(intent);
}
});
}
}
以上的代码是在activity交给atms之前把未注册的activity替换成一个代理activity,最后还要想办法在返回来的时候,把代理activity替换成要启动的未注册的activity,思路就是在atms检测之后,这个activity的生命周期开始执行之前,把想要启动的activity替换回来。
try {
Class<?> clazz = Class.forName( "android.app.ActivityThread");
Field activityThreadField = clazz.getDeclaredField("sCurrentActivityThread");
activityThreadField.setAccessible(true);
Object activityThread = activityThreadField.get(null);
Field mHField = clazz.getDeclaredField("mH");
mHField.setAccessible(true);
final Handler mH = (Handler) mHField.get(activityThread);
Field mCallbackField = Handler.class.getDeclaredField("mCallback");
mCallbackField.setAccessible(true);
mCallbackField.set(mH, new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case 159:
// msg.obj = ClientTransaction
try {
// 获取 List<ClientTransactionItem> mActivityCallbacks 对象
Field mActivityCallbacksField = msg.obj.getClass().getDeclaredField("mActivityCallbacks");
mActivityCallbacksField.setAccess ible(true);
List mActivityCallbacks = (List) mActivityCallbacksField.get(msg.obj);
for (int i = 0; i < mActivityCallbacks.size(); i++) {
// 打印 mActivityCallbacks 的所有item
// 如果是 LaunchActivityItem,则获取该类中的 mIntent 值,即 proxyIntent
if (mActivityCallbacks.get( i).getClass().getName().equals("android.app.servertransaction.LaunchActivityItem")) {
Object launchActivityItem = mActivityCallbacks.get(i);
Field mIntentField = launchActivityItem.getClass().getDeclaredField("mIntent");
mIntentField.setAccessible( true);
Intent proxyIntent = (Intent) mIntentField.get(launchActivityItem);
// 获取启动插件的 Intent,并替换回来
Intent intent = proxyIntent.getParcelableExtra(TARGET_INTENT);
if (intent != null) {
mIntentField.set( launchActivityItem, intent);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
break;
}
return false;
}
});
} catch (Exception e) {
e.printStackTrace();
}