美文网首页
2018-10-25 Activity的启动流程

2018-10-25 Activity的启动流程

作者: 小刘灰灰 | 来源:发表于2018-10-25 15:17 被阅读0次
    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);
    //平时重写的最多的。
    

    好了 到了这里 activity的启动就写完了 根据主线一直跟下去 就可以发现他的实现方法 主要是在细节的发现。

    相关文章

      网友评论

          本文标题:2018-10-25 Activity的启动流程

          本文链接:https://www.haomeiwen.com/subject/krmqtqtx.html