赞
踩
踏入Android开发有一小段时间了,第一次接手项目的时候状态就是上午自己写Bug,下午改自己的Bug,慢慢的接触的技术多了,就开始写项目上的一些小模块之类的,作为一个开发,技术是永远都学不完的,技术的更新速度快过自己的学习速度,但是个人觉得,如果想作为一名合格的程序猿,一些开发 的底层代码是肯定要了解的。就打个比方(就拿Android来说),你如果是实习的时候去面试,面试官问你Activity的启动流程是怎样的,你脑子里第一反应就是onCreate,onStrat,onResume,onPause,onStop,onDestory。但是如果你是有两三年工作经验的程序猿,面试官问你Activity的具体启动流程是怎样的,如果你还是回答如上的话,那不好意思,你可以回家等消息了。所以说,不管做什么技术开发都好,一些底层的代码还是需要去了解的,这对你提升自身技术的速度有很大的帮助…废话就不多说,开始进入今天的话题…
当你点击手机桌面的一个App图标的时候,App是怎么知道要打开哪个界面,是谁通知这个App要启动的,这就离不开AMS的存在了,带着这些疑问,接着往下看…
首先,在手机屏幕上点击App的图标,此时的手机屏幕就是一个Activity,而这个Activity所在的App,在Android业界中称之为Launcher,Launcher是各个手机系统厂商提供的,主要的不同就是一些动画效果以及人性化设计。
然后,我们在开发App的时候,每创建一个Activity都要在AndroidManifest.xml文件里面注册这个Activity,这是因为当你安装这个App的时候,PMS(PackageManagerService)会把这个Apk包里面的AndroidManifest.xml文件里面所有信息都读取并且保存下来,以便后续的使用。
最后,以斗鱼为例,斗鱼和Launcher是两个不同的App,他们两个存在于不同的进程之中,Launcher要启动斗鱼App,这就少不了这两个进程之间的相互通信了,Android中通信最常用的也是最好用的无非就是Binder了,没了解过Binder的同学可以看看这篇文章Android Binder之间的相互通信。
当你启动斗鱼App的时候,主要大致经过如下7个流程:
这些步骤只是从Launcher中启动一个App,接下来我们接着说一个Activity是如何从开始启动到onCreate函数之间的流程。
想必也都知道Java的程序入口就是main()方法,也就是上文我们步骤4中提到的main函数,看看源码
public static void main(String[] args){
...
//初始化Looper
Looper.prepareMainLooper();
//实例化一个ActivityThread
ActivityThread thread = new ActivityThread();
//这个方法最后就是为了发送出创建Application的消息
thread.attach(false);
//主线程进入无限循环状态,等待接收消息
Looper.loop();
...
}
这里比较关键的就是attach方法,attach()方法最终的目的是发送出一条创建Application的消息——H.BIND_APPLICATION,到主线程的主Handler中,告知要初始化Application
public void attach(boolean system){
...
//获得IActivityManager实例,下面会看看它是个啥
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
这里出现了IActivityManager,它其实是一个接口,当调用ActivityManagerNative.getDefault()的时候,我们可以得到ActivityManagerProxy,ActivityManagerProxy是一个代理类的实例,也是ActivityManagerNative的一个内部类,然而ActivityManagerProxy的构造函数需要一个IBinder参数,然后进行一个赋值操作
public ActivityManagerProxy(IBinder remote) {
mRemote = remote;
}
调用这个AMP构造函数的地方如下:
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
//先检查一下本地有木有,有的话直接取
IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
...
//没有就New一个新的
return new ActivityManagerProxy(obj);
}
然后返回ActivityManagerNative.getDefault()来,我们来看看getDefault()获取到的静态常量gDefault的源码:
private static final Singleton<IActivityManager> gDefault =
new Singleton<IActivityManager>() {
protected IActivityManager create() {
//在这里就获得了上文需要的IBinder实例
IBinder b = ServiceManager.getService("activity");
...
IActivityManager am = asInterface(b);
...
return am;
}
};
这里是通过ServiceManager获取到IBinder实例的,获取IBinder的目的就是为了通过这个IBinder和ActivityManager进行通讯,进而ActivityManager会调度发送H.BIND_APPLICATION即初始化Application的Message消息,既然拿到了IBinder,那我们接着看attachApplication(mAppThread)这个方法中的mAppThread,在ActivityThread的成员变量中,你可以看到:
final ApplicationThread mAppThread = new ApplicationThread();
mAppThread是ActivityThread和AMS交互的中间桥梁,ApplicationThread是ActivityThread中的一个内部类,继承自ApplicationThreadNative,巧了,ApplicationThreadNative继承自Binder
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread{
...
public ApplicationThreadNative() {
attachInterface(this, descriptor);
}
...
}
那么很明显,ApplicationThread最终也是一个Binder,所以说mAppThread是ActivityThread和AMS交互的中间桥梁,经过上面的辗转,ApplicationThread终于到了ActivityManagerService中了。
接着我们看下AMS里面的其中一个方法:
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
...
//此处省去N行代码
thread.bindApplication();
...
}
经过一系列的操作,最终被调用了自己的bindApplication()方法,发出初始化Applicationd的消息,在bindApplication()方法里有这样一行代码:
sendMessage(H.BIND_APPLICATION, data);
发出创建Application的消息,一旦接收到这个消息就开始创建Application了,这个过程是在handleBindApplication()中完成的。
private void handleBindApplication(AppBindData data) { ... //通过反射初始化一个Instrumentation仪表(后续会单独出一篇相关文章来介绍)。 //Instrumentation会在应用程序的任何代码运行之前被实例化,它能够允许你监视应用程序和系统的所有交互 mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); ... //通过LoadedApp命令创建Application实例 Application app = data.info.makeApplication(data.restrictedBackupMode, null); ... mInitialApplication = app; ... //让仪器调用Application的onCreate()方法 mInstrumentation.callApplicationOnCreate(app); ... }
最后调用了callApplicationOnCreate()方法,就创建了Application,当Application初始化完成后,系统会从AndoridManifest中的配置启动Activity发送一个Intent去启动相应的Activity,当H收到LAUNCH_ACTIVITY消息后便开始执行创建Activity,处理消息的源码如下:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { ... Activity a = performLaunchActivity(r, customIntent); ... if (a != null) { ... //Activity创建成功就执行onResume() handleResumeActivity(r.token, false , r.isForward ,!r.activity.mFinished && !r.startsNotResumed , r.lastProcessedSeq, reason); ... } }
performLaunchActivity方法中,挑选了几行重要的代码如下所示:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ... //通过仪表来创建Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); ... //获取Application Application app = r.packageInfo.makeApplication(false, mInstrumentation); ... //根据是否可持久化选择Activity的onCreate()方法 if (r.isPersistable()) { mInstrumentation.callActivityOnCreate( activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } }
在newActivity里面就反射实例化Activity,没有别的了,然后根据是否可持久化选择Activity的onCreate()方法,到此,Activity就创建好了,同学们细品哈,如有不足之处请多多指教~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。