我们在桌面上打开一个应用经历的流程

手机的桌面本质是一个Activity,是一个LauncherActivity。

public abstract class LauncherActivity extends ListActivity {

}

可以看到这个LauncherActivity 是继承自ListActivity,而ListActivity继承自Activity。

我们点击这些应用程序,启动应用程序,就是通过调用startActivity()方法。

每个应用都是一个单独的dalvik虚拟机,每一个应用都是一个单独的进程。桌面是一个Launcher进程。发送一个startActivity告诉ActivityManagerService(AMS)系统服务需要打开一个APP。打开APP需要知道包名和类名,就可以打开这个APP了。

ActivityManagerService就会通过Socket方式告诉Zygote进程,我需要开启新的进程,经过一系列的调用,就会fork一个进程出来,fork它自己的一个进程,这个进程就是我们的APP进程。

这个APP进程第一步就是创建一个Application线程出来,也是要去向ActivityManagerService请求的,告ActivityManagerService系统服务我需要一个ApplicationThread,经过一系列的方法调用,创建出了ApplicationThread以后,通过Handler方式会发送一个消息。之后就会进入Activity的生命周期。

简单的概括下:

1.点击app图标,Launcher进程使用Binder IPC向system_server进程发起startActivity请求;
2.system_server进程收到1中的请求后,向zygote进程发送创建新进程的请求;
3.zygote进程fork出新的App进程
4.App进程通过Binder IPC向system_server进程发起attachApplication请求;
5.system_server进程收到4中的请求后,通过Binder IPC向App进程发送scheduleLauncherActivity请求;
6.App进程的ApplicationThread线程收到5的请求后,通过handler向主线程发送LAUNCHER_ACTIVITY消息;
7.主线程收到6中发送来的Message后,反射创建目标Activity,回调oncreate等方法,开始执行生命周期方法,我们就可以看到应用页面了。

Zygote进程:

在FramWork层中最重要的2个进程一个是SystemServer进程还有一个就是Zygote进程。开启进程就是通过Zygote分裂一遍的进程。只有和Zygote进程之间通信是通过Socket方式,其他进程之间的通信是用Binder方式,进程内部通信使用Handler方式。

SystemServer进程:

启动一些服务,ActivityMangerService、WindowManagerService、PackageManagerService 。这些就像一个服务器,我们的APP就像一个客户端,我们需要什么了,就向服务端请求。

如何创建一个进程

 startActivity之后通过Binder方式告诉ActivityManagerService(AMS),ActivityManagerService负责系统中所有Activity的生命周期,告诉ActivityManagerService需要创建一个进程,AMS会调用Process.start,告诉Zygote进程需要创建一个新的进程,创建完以后就会调用ActivityThread.main()方法,一个APP的开始就开始于ActivityThread.main()方法。

一个APP的创建是从ActivityThread.main()开始的,我们看下main()的源码。

 public static void main(String[] args) {
       
        Looper.prepareMainLooper();
        //开启消息队列循环
    
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();
}
   private void attach(boolean system, long startSeq) {
        
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        
}
  public final void bindApplication(...){
     sendMessage(H.BIND_APPLICATION, data);
}

  public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

}

 private void handleBindApplication(AppBindData data) {
     app = packageInfo.makeApplication(false, mInstrumentation);
     context = (ContextImpl) app.getBaseContext();

}
 public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
 try {
            java.lang.ClassLoader cl = getClassLoader();
            ...
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {...}
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

}

创建Application的核心代码:

    public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException,  ClassNotFoundException {
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context);
        return app;
    }

只要知道一个包名和MainActivity就可以打开一个Activivity。这里用到了反射机制去获得一个Application。

可以看到attach()方法比onCreate方法先执行。

整个流程可以概括如下:

1、点击桌面应用图标,Launcher 进程将启动Activity(MainActivity)的请求以Binder 的方式发送给了AMS。

2、AMS 接收到启动请求后,交付ActivityStarter 处理Intent 和Flag 等信息,然后再交给ActivityStackSupervisior/ActivityStack 处理Activity 进栈相关流程。同时以Socket 方式请求Zygote 进程fork 新进程。

3、Zygote 接收到新进程创建请求后fork 出新进程。

4、在新进程里创建ActivityThread 对象,新创建的进程就是应用的主线程,在主线程里开启Looper 消息循环,开始处理创建Activity。

5、ActivityThread 利用ClassLoader 去加载Activity、创建Activity 实例,并回调Activity 的onCreate()方法,这样便完成了Activity 的启动。

再看看另一幅启动流程图来加深理解:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值