开头
下面是计划,哎…万事开头难,看了知识A发现知识B还不了解,计划也是修修改改
计划
任务 | 阶段目标 |
---|---|
1,进程通讯机制 - binder 和 aidl (binder不能恋战) | 这很重要,理解了这个才能看懂系统服务间大量的进程间调用关系 |
2,Android系统的启动流程 | 理解init进程,zygote,systemServer的启动流程,承担的角色 |
3,AMS的启动流程 | 理解AMS从哪里启动,负责启动和管理哪些服务 |
4,ActivityTask,ActivityRecord,ActivityStackSupervisor | 理解Activity的基本数据结构和管理方式 |
5,Activity的启动流程 | 梳理startActivity的调用逻辑 |
6,SurfaceFling,Choreographer渲染机制 | Jank的理解和计算方式 |
7,WMS窗口管理机制 | (后面可能有调整) |
未完待续 |
大佬们的指导思想
在迷茫的时候多看一些过来人的意见
Android Framework 如何学习,如何从应用深入到Framework?
我起跑时跌倒的经历
当然每个人的知识水平不同,我个人偏上层。
从Binder开始
binder是我们入门Framework的最重要的基础之一,至少理解了binder在系统服务间的跨进程调用,否则很难看懂。
从应用开发者角度开始认识Binder
怎样学习binder?我推荐你先看完这个
Binder学习指南
一,Java层的几个类和概念
类
- android.os.IBinder.java : 代表进程通讯的能力。
- android.os.IInterface.java :客户端和服务端的接口定义(远程接口有什么样的功能)。
- android.os.Binder.java :可以进程通讯的对象。
角色概念
我想大家都看过科幻剧,一般都有真人投影会议的桥段。
- Proxy : 代理。影分身,和真人一模一样,客户端通过代理对象访问服务端,感官上和真人说话一模一样。
- Stub :存根。一般是服务端来实现,就是真人本尊。
方法
- transact :传送门,开始传送…
- onTransact :传送门,到达了…
二,从一个AIDL的demo引入思考
demo结构,一个app模块,一个service模块
app模块
service模块
AIDL内容:我利用模板生成,为了好区分,我把方法名修改为add。
// IMyAidlInterface.aidl
package com.demo.service;
// Declare any non-default types here with import statements
interface IAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void add(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
build后,编译器会帮助我们生成aidl对应的IAidlInterface.java文件,不贴出全部了,重点我截取片段出来。
android的编译器一股脑全部生成在一个类,原本是这样的:
public interface IAidlInterface extends android.os.IInterface{
...
public static abstract class Stub extends android.os.Binder implements com.demo.service.IAidlInterface{
...
private static class Proxy implements com.demo.service.IAidlInterface{
}
}
}
嵌套了两层内部类,其实这个java文件也可以自己编写,我更喜欢这样看:
public interface IAidlInterface extends android.os.IInterface{}
public abstract class Stub extends android.os.Binder implements com.demo.service.IAidlInterface{}
private class Proxy implements com.demo.service.IAidlInterface{}
Framework中binder的调用
一,binder在AMS中的样子
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
/**
* Retrieve the system's default/global activity manager.
* 通过这个静态方法,App就可以调用ams在IActivityManager注册的接口。
*/
static public IActivityManager getDefault() {
return gDefault.get();
}
........
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
// 向SM大管家获取AMS的binder引用
IBinder b = ServiceManager.getService("activity");
...
//如果是客户端调用,就返回代理对象。
IActivityManager am = asInterface(b);
...
return am;
}
};
}
二,APP获取AMS的Binder代理,进行调用
例如:Activity启动过程中,会调用AMS中去,那么Client访问Server的目的就达成了。
Instrumentation.java
ActivityManagerNative.getDefault().startActivities(whoThread,who.getBasePackageName(),intents,resolvedTypes,token, options, userId);
三,AMS获取APP的Binder代理
AMS在完成Activity的启动后,需要回调通知app,app也要像AMS那样注册到SM吗?不是的,app在调用AMS的方法时,把自己的binder传给了AMS。
ActivityThread.java
public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);//启动的时候调用了这个方法。
...
}
private void attach(boolean system){
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//这个调用了AMS的方法,传入了一个mAppThread,我们紧接着去看AMS是怎么实现的
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
private class ApplicationThread extends ApplicationThreadNative{}
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread{}
public interface IApplicationThread extends IInterface
基本就和AMS的实现一样,说明ApplicationThread也是一个S端。
传递的逻辑,如图
紧接着就有一次对app的跨进程调用,调用了bindApplication方法。
ActivityManagerService.java#attachApplicationLocked
调用bindApplication方法的逻辑,如图
理解完上面的调用很重要,至此我们至少熟悉了binder跨进程中调用的流程,这下我们就可以继续下一步正式进行系统启动流程的分析了。
呜谢:
Android Framework 如何学习,如何从应用深入到Framework?