您的位置:首页 > 运维架构 > 网站架构

移动架构09_Activity的启动流程分析

2017-10-04 15:18 471 查看
用户在点击手机中App的图标时,到底做了那些呢?
一个App启动(冷启动)就是启动一个main函数,那么这个main函数在哪里呢?
是哪个类的main函数呢?



如上图所示,第一次启动时会去加载.class文件;开启一个进程,这个进程包含方法区、堆区、栈区;在物理上就是包含这些的内存区域,这个进程是在ActivityThread中启动的,启动app实际就是启动ActivityThread 。

(1)打开源码ActivityThread:

找到main方法,当点击app图标时,系统会去启动这个main方法,并且分配一个内存区域。

main方法中:

Looper.prepareMainLooper();这是一个消息机制。

通常,如果在子线程中想要接受主线程的消息,通过下面的方式:

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

new Thread(new MyThread()).start();

}

private Handler handler;

public void onClick(View v){

Message message=Message.obtain();

message.obj="Jackson";

handler.sendMessage(message);

}

public class MyThread implements Runnable {

@Override

public void run() {

//在子线程没有Looper的概念

Looper.prepare();//循环消息队列

//在子线程实例化handler

handler = new Handler() {

@Override

public void handleMessage(Message msg) {

//子线程中接收主线程发送过来的消息

super.handleMessage(msg);

System.out.println("--从主线程获取消息-->>" + msg.obj);

}

};

Looper.loop();

}

}

通过Looper.prepare()和Looper.loop()不断的循环去获取消息,但是在主线程中,我们没有手动调用Looper.prepare()的方法,就是因为main方法中在这里已经调用过了。Android和IOS与用户的交互,都是基于消息机制的分发。

紧接着调用了attach方法:

ActivityThread thread = new ActivityThread();

thread.attach(false);

attach方法中:

传入的boolean类型参数,表示是否是系统应用,false表示普通应用。

执行了代码:

final IActivityManager mgr = ActivityManagerNative.getDefault();

try {

mgr.attachApplication(mAppThread);

} catch (RemoteException ex) {

throw ex.rethrowFromSystemServer();

}

(2)在ActivityManagerNative的getDefault方法中:

static public IActivityManager getDefault() {

return gDefault.get();

}

调用了内部类gDefault的get方法

gDefault中执行了代码:

IBinder b = ServiceManager.getService("activity");

返回一个IBinder(通过map中key找value方法,返回的IBinder);

有get就有add,在ServiceManager中,找对应"activity"的添加方法,

寻找发现没有,找其子类,ActivityManagerService;在ActivityManagerService中,找到了对应的代码:

ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);//Context.ACTIVITY_SERVICE就是“activity”

this表示当前类ActivityServiceManager

所有上述中返回的IBinder就是ActivityServiceManager;

(3)返回到ActivityThread的attach()中。

ActivityThread中,mgr.attachApplication(mAppThread);即ActivityManagerService的attachApplication方法。

(4)ActivityManagerService的attachApplication()方法中:

-》attachApplicationLocked():

1)调用thread.bindApplication,thread是ActivityThread中定义的ApplicationThread,绑定了整个应用的上下文。

2)执行了代码:

if (normalMode) {

try {

if (mStackSupervisor.attachApplicationLocked(app)) {

didSomething = true;

}

} catch (Exception e) {

Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);

badApp = true;

}

}

mStackSupervisor是ActivityStackSupervisor

(5)ActivityStackSupervisor的attachApplicationLocked中

调用了realStartActivityLocked(hr, app, true, true)真正的启动Activity,

--》app.thread.scheduleLaunchActivity(回到了ActivityThread的scheduleLaunchActivity方法)

(6)ActivityThread的scheduleLaunchActivity

1)sendMessage(H.LAUNCH_ACTIVITY, r);

-》handleMessage中:

handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");

-》handleLaunchActivity中:

Activity a = performLaunchActivity(r, customIntent);//反射

2) performLaunchActivity:

xml中找Activity类

java.lang.ClassLoader cl = r.packageInfo.getClassLoader();

activity = mInstrumentation.newActivity(

cl, component.getClassName(), r.intent);

StrictMode.incrementExpectedActivityCount(activity.getClass());

//Instrumentation的newActivity方法

Instrumentation的newActivity:实例化一个Activity

Activity activity = (Activity)clazz.newInstance();

(7)回到performLaunchActivity中,代码执行:

mInstrumentation.callActivityOnCreate

--》activity.performCreate(icicle, persistentState)

(8)Activity的performCreate中:

最终调用了:onCreate(icicle, persistentState);

Instrumentation真正的调用了Activity的onCreate方法

时序图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息