1.Activity的启动流程 不是Activity的生命周期,什么都不说先来看张图了解一下 1869462-882b8e0470adf85a.jpg
一.桌面应用图标被点击后发生的事情,大致分为几个流程
(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<IActivityManager> gDefault = new Singleton<IActivityManager>() {
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<ProviderInfo> 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<String, IBinder> 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);
//平时重写的最多的。
网友评论