欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-13 23:27:11
一个APP的创建是从ActivityThread.main()开始的。 public static void main(String[] args) { Looper.prepareMainLooper(); //开启消息队列循环 ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); ......

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

手机的桌面本质是一个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的生命周期。

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

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 的启动。

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

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

 

 

本文地址:https://blog.csdn.net/jingerlovexiaojie/article/details/108979591