1.Activity的启动流程 不是Activity的生命周期,什么都不说先来看张图了解一下
一.桌面应用图标被点击后发生的事情,大致分为几个流程
(1)APP的启动首先需要的是创建出Application的初始化创建。
1.Mian方法(JAVA的入门的方法)。
实例化ActivityThread 这个类
创建一个 Looper的轮训器作用是等待消息去创建Application,
thread.attach(false),这个方法为了Application的初始化做准备的。
public static void main(String[] args){
... Looper.prepareMainLooper();
//初始化
Looper ... ActivityThread thread = new ActivityThread();
//实例化一个
ActivityThread thread.attach(false);
//这个方法最后就是为了发送出创建Application的消息
... Looper.loop();
//主线程进入无限循环状态,等待接收消息
}
2.attach方法的执行所做的事情。
上面提到过,ActivityThread的attach()方法最终的目的是发送出一条创建Application的消息——H.BIND_APPLICATION,到主线程的主Handler中。那我们来看看attach()方法干了啥。
ActivityManagerNative.getDefault();这个静态方法所做的一些操作是初始化准备的关键性的操作
public void attach(boolean system){
... final IActivityManager mgr = ActivityManagerNative.getDefault();
//获得IActivityManager实例,下面会看看它是个啥
try { mgr.attachApplication(mAppThread);
//看见没?关键啊。
mAppThread这个参数下面也会说一下
} catch (RemoteException ex)
{
throw ex.rethrowFromSystemServer();
}
...
}
IActivityManager mgr是个啥?
从上图也可以看到,IActivityManager是一个接口,当我们调用ActivityManagerNative.getDefault()获得的实际是一个代理类的实例——ActivityManagerProxy,这个东西实现了IActivityManager接口。打开源码你会发现,ActivityManagerProxy是ActivityManagerNative的一个内部类。可以看出,Android团队在设计的过程中是实践了最小惊异原则的,就是把相关的东西尽量放在一起。那么既然是个代理类,它究竟代理了谁?代码里看看喽。
在这里我直接将三段代码粘起来 (我的理解是:就是为了让ActivityManager获取IBinder 这个事例 )
在这里为了好理解 稍微扯远一点aidl 服务端创建一个Service 制定好aidl文件的中的方法,服务端创建一个server和aidl文件 创建Server创建的时候绑定aidi的文件的事例类 和实现下面的那些方法,这就是服务端要做的代码 ,在客户端需要做的就是,先启动服务端的server,在根据ServiceConnection这个类的回调的回来 获取(其实根据server的获取aidl的实现类对象,从而调用服务端的方法的)。这里只是一个aidi的简单的解释。
这里是通过ServiceManager获取到IBinder实例的。如果你以前了解AIDL通讯流程的话。这可能比较好理解一点,这只是通过另一种方式获取IBinder实例罢了。获取IBinder的目的就是为了通过这个IBinder和ActivityManager进行通讯,进而ActivityManager会调度发送H.BIND_APPLICATION即初始化Application的Message消息。
public ActivityManagerProxy(IBinder remote) {
mRemote = remote;
}
----------华丽的分割线-------------------
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); /
/先检查一下有没有
if (in != null) {
return in;
} ...
return new ActivityManagerProxy(obj);
//这个地方调用了构造函数 }
----华丽的分割线------
private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
//重点啊!IBinder实例就是在这里获得的。 ...
IActivityManager am = asInterface(b);
//调用了上面的方法。 ...
return am;
}
};
----华丽的分割线------
public void attachApplication(IApplicationThread app){
...
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
...
}
这个方法我在上图中也体现出来了。
这个方法中上面这一句是关键。调用了IBinder实例的tansact()方法,并且把参数app(这个参数稍后就会提到)放到了data中,最终传递给ActivityManager。
现在,我们已经基本知道了IActivityManager是个什么东东了。其实最重要的就是它的一个实现类ActivityManagerProxy,它主要代理了内核中与ActivityManager通讯的Binder实例。
ApplicationThread mAppThread又是个啥?
IApplicationThread是继承了IInterface的一个接口,我们需要关注一下里面的descriptor参数。后面会用它,它是一个标识,查询的时候很重要。
好,我们终于知道attach()方法中出现的两个对象是啥了。ApplicationThread作为IApplicationThread的一个实例,承担了最后发送Activity生命周期、及其它一些消息的任务。也就是说,前面绕了一大圈,最后还是回到这个地方来发送消息。我擦!
也许你会想,既然在ActivityThread中我们已经创建出了ApllicationThread的了,为什么还要绕这么弯路?,当然是为了让系统根据情况来控制这个过程喽,不然为什么要把ApplicationThread传到ActivityManager中呢?
到这里就是application的初始化已经做完了,下来就是给main方法中的looper发送一个消息 开始初始化application
ActivityManagerService调度发送初始化消息
private final boolean attachApplicationLocked(IApplicationThread thread
, int pid) {
...
thread.bindApplication();
//注意啦!
...
}
华丽的分割线-----------
public final void bindApplication(
String processName,
ApplicationInfo appInfo,
List providers,
ComponentName instrumentationName,
ProfilerInfo profilerInfo,
Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection,
int debugMode,
boolean enableBinderTracking,
boolean trackAllocation,
boolean isRestrictedBackupMode,
boolean persistent,
Configuration config,
CompatibilityInfo compatInfo,
Map services,
Bundle coreSettings){
... sendMessage(H.BIND_APPLICATION, data);
}
重点来了 初始化的方法
private void handleBindApplication(AppBindData data) {
... mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()) .newInstance();
//通过反射初始化一个Instrumentation仪表。后面会介绍。
... Application app = data.info.makeApplication(data.restrictedBackupMode, null);
//通过LoadedApp命令创建Application实例
mInitialApplication = app;
... mInstrumentation.callApplicationOnCreate(app); /
/让仪器调用Application的onCreate()方法 ... }
Instrumentation仪表,什么鬼?(重点了 这个类初始化llication和activity都需要的)
1.这个叫Instrumentation仪表的东西十分诡异,姑且翻译为仪器吧。字面上看不出任何它是干什么的线索。但是,我们可以打开文档看看喽。
Instrumentation会在应用程序的任何代码运行之前被实例化,它能够允许你监视应用程序和系统的所有交互。
大概就这个意思啦。
2.但是,从上面的代码我们可以看出,Instrumentation确实是在Application初始化之前就被创建了。那么它是如何实现监视应用程序和系统交互的呢?
打开这个类你可以发现,最终Apllication的创建,Activity的创建,以及生命周期都会经过这个对象去执行。简单点说,就是把这些操作包装了一层。通过操作Instrumentation进而实现上述的功能。
3.那么这样做究竟有什么好处呢?仔细想想。Instrumentation作为抽象,当我们约定好需要实现的功能之后,我们只需要给Instrumentation仪表添加这些抽象功能,然后调用就好。剩下的,不管怎么实现这些功能,都交给Instrumentation仪器的实现对象就好。啊!这是多态的运用。啊!这是依赖抽象,不依赖具体的实践。啊!这是上层提出需求,底层定义接口,即依赖倒置原则的践行。呵!抽象不过如此。
从代码中可以看到,这里实例化Instrumentation的方法是反射!而反射的ClassName是来自于从ActivityManagerService中传过来的Binder的。套路太深!就是为了隐藏具体的实现对象。但是这样耦合性会很低。
4.好了,不瞎扯了。既然在说Instrumentation,那就看看最后调的callApplicationOnCreate()方法。
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
LoadedApk就是data.info哦!
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
... String appClass = mApplicationInfo.className;
//Application的类名。明显是要用反射了。
... ContextImpl appContext = ContextImpl.createAppContext(mActivityThread , this);
//留意下
Context app = mActivityThread.mInstrumentation .newApplication( cl, appClass, appContext);
//通过仪表创建Application ...
}
newApplication的方法
static public Application newApplication(Class> clazz , Context context)
throws InstantiationException ,
IllegalAccessException ,
ClassNotFoundException {
Application app = (Application)clazz.newInstance(); //反射创建,简单粗暴 app.attach(context);
//关注下这里,Application被创建后第一个调用的方法。 //目的是为了绑定Context。 return app; }
第一部分到这里已经全部结束了 下来是创建Activity 的过程
LaunchActivity
当Application初始化完成后,系统会更具Manifests中的配置的启动Activity发送一个Intent去启动相应的Activity
1.直接的,H就收到了一条LAUNCH_ACTIVITY的消息。然后开始初始化Activity之旅。收到消息后,真正处理是在ActivityThread中的handleLaunchActivity()中进行的
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}
handleConfigurationChanged(null, null);
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
if (!ThreadedRenderer.sRendererDisabled) {
GraphicsEnvironment.earlyInitEGL();
}
WindowManagerGlobal.initialize();
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
try {
ActivityManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
//再来一个方法
private Activity performLaunchActivity(ActivityClientRecord r , Intent customIntent) {
... activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);
//通过仪表来创建Activity ... Application app = r.packageInfo.makeApplication(false , mInstrumentation);
//前面说过,是在获取Application
... activity.attach(
appContext ,
this ,
getInstrumentation() ,
r.token ,
.ident ,
app ,
r.intent , r.activityInfo ,
title ,
r.parent ,
r.embeddedID ,
r.lastNonConfigurationInstances ,
config ,
r.referrer , r.voiceInteractor , window); //方法怪出现! ... if (r.isPersistable()) { mInstrumentation.callActivityOnCreate( activity, r.state, r.persistentState); }
else {
mInstrumentation.callActivityOnCreate(activity, r.state); }
//根据是否可持久化选择onCreate()方法。... }
public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException , IllegalAccessException, ClassNotFoundException { return (Activity)cl.loadClass(className).newInstance(); //真的没干啥。反射实例化Activity而已 }
if (r.isPersistable()) { mInstrumentation.callActivityOnCreate( activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); }
onCreate(icicle, persistentState);
//可获得持久化数据
onCreate(icicle);
//平时重写的最多的。