美文网首页
Android应用程序的启动

Android应用程序的启动

作者: G_Freedom | 来源:发表于2020-04-26 17:03 被阅读0次

    Android源码版本9.0

    应用程序的启动

    从手机屏幕点击APP图标起,APP的启动就已经开始了
    首先:
    执行java首次启动都要执行的main方法开始
    Android main方法存在于ActivityThread中,也就是说启动应用都要从ActivityThread的main方法开始

    ##ActivityThread
    public static void main(String[] args) {
            ...
            Looper.prepareMainLooper(); //1
            long startSeq = 0;
            if (args != null) {
                for (int i = args.length - 1; i >= 0; --i) {
                    if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                        startSeq = Long.parseLong(
                                args[i].substring(PROC_START_SEQ_IDENT.length()));
                    }
                }
            }
            ActivityThread thread = new ActivityThread();  //2
            thread.attach(false, startSeq); //3
            ...
            Looper.loop();
            throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    

    说一下几个比较重要的方法 ->

    • 注释1 -> Looper.prepareMainLooper() -> 用于应用启动创建进程唯一的UI线程
    • 注释2 -> 把ActivityThread创建出来并调用attach连接
    • 注释3 -> 启动Looper的消息队列

    接下来看一下具体连接了什么

    ##ActivityThread
    private void attach(boolean system, long startSeq) {
            ...
            if (!system) {
                ...
                final IActivityManager mgr = ActivityManager.getService();  //1
                try {
                    mgr.attachApplication(mAppThread, startSeq);  //2
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
                ...
            } else {
                ...
            }
            ...
    }
    
    • 注释1 -> 通过ActivityManager获取IActivityManager,这个是系统的本地代理对象,作用是应用进程请求系统进程接口,为了实现进程间通信,这里用到的是AIDL。具体用法不再此处说明,只需要知道这能够实现进程间交互。
    • 注释2 -> 调用attachApplication方法,调用系统进程接口,用于连接Application

    IActivityManager具体执行方法是在ActivityManagerService,这里让Application去和AMS连接是为了APP和系统绑定,更好的方便管理当前APP。

    ##ActivityManagerService
    public final void attachApplication(IApplicationThread thread, long startSeq) {
            synchronized (this) {
                //获取pid
                int callingPid = Binder.getCallingPid();  //1
                //获取uid
                final int callingUid = Binder.getCallingUid();  //2
                final long origId = Binder.clearCallingIdentity();
                //连接Application
                attachApplicationLocked(thread, callingPid, callingUid, startSeq);  //3
                Binder.restoreCallingIdentity(origId);
            }
    }
    

    attachApplication是AMS中的一个方法。

    • 注释1和2 -> 分别获取到pid和uid(由系统创建,并分配,并且是处以没有进程使用)。
    • 注释3 -> 可以看到pid和uid传入到了attachApplicationLocked这个方法中。
    ##ActivityManagerService
    private final boolean attachApplicationLocked(IApplicationThread thread,
                                                      int pid, int callingUid, long startSeq) {
            ProcessRecord app;  //1
            long startTime = SystemClock.uptimeMillis();
            if (pid != MY_PID && pid >= 0) {
                synchronized (mPidsSelfLocked) {
                    app = mPidsSelfLocked.get(pid);  //2
                }
            } 
            ...
            if (app.instr != null) {  //当前进程是否正在活动
               thread.bindApplication(processName, appInfo, providers, app.instr.mClass,
                        profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection,
                        testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, isAutofillCompatEnabled);   //3
            } else {
                //Application 绑定到当前线程
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode, mBinderTransactionTrackingEnabled,
                        enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled);  //4
            }
            ...
            //检测最可见的Activity是否在运行进程中等待,如果再则创建Activity
            if (mStackSupervisor.attachApplicationLocked(app)) {  //5
                didSomething = true;
            }
            ...
    }
    
    • 注释1 -> rocessRecord是个进程记录类,可以看作是一个javabean,用来保存当前进程先关的一些信息(如pid、uip、ApplicationInfo等)
    • 注释2 -> 根据pid获取到了这个类,其实也就是获得当前进程的相关属性。
    • 注释3、注释4 -> 绑定Application到当前进程,thread也就是IApplicationThread,它是一个AIDL的接口,作用是系统进程请求应用进程的接口。实现类是ActivityThread中的内部类ApplicationThread。
    • 注释5 -> 开始创建Activity

    总结:App的启动从应用图标被点击开始,首先执行的是ActivityThread中的main方法。
    1、创建出进程唯一的UI线程,并启动它的消息队列。
    2、获取IActivityManager也就是ActivityManagerService请求系统进程接口,通过AIDL实现进程间通信,作用是APP连接系统进程,方便管理当前APP。这样就完成了系统和应用进程的绑定。

    绑定Application

    ##ActivityThread.ApplicationThread
    public final void bindApplication(String processName...boolean autofillCompatibilityEnabled) {
            ...
            setCoreSettings(coreSettings);
            AppBindData data = new AppBindData();
            data.processName = processName;  //当前进程名字
            data.appInfo = appInfo;     //app信息
            data.providers = providers; //providers
            ...
            //最后使用Handler发送消息,并携带AppBindData数据
            sendMessage(H.BIND_APPLICATION, data);
    }
    

    在bindApplication中,会把传入的一系列参数封装成一个AppBindData对象,然后通过Handler把这个对象发送出去。H是ActivityThread中的内部类,是Handler的子类。

    ##ActivityThread.H
    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;
                ...
            }
            ...
    }
    

    handleMessage方法是H中的方法,主要是用来处理消息。

    ##ActivityThread 
    private void handleBindApplication(AppBindData data) {
            ...
            final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);  //1
            ...
            Application app;
            ...
            //创建Application
            app = data.info.makeApplication(data.restrictedBackupMode, null);  //2
            ...
            //调用Application中的onCreate方法
            mInstrumentation.callApplicationOnCreate(app);  //3
            ...
    }
    
    ##LoadedApk
    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);//2
                appContext.setOuterContext(app);
            } catch (Exception e) {
                if (!mActivityThread.mInstrumentation.onException(app, e)) {
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    throw new RuntimeException(
                        "Unable to instantiate application " + appClass
                        + ": " + e.toString(), e);
                }
            }
            ...
    }
                
    ##Instrumentation
    public Application newApplication(ClassLoader cl, String className, Context context)
                throws InstantiationException, IllegalAccessException, 
                ClassNotFoundException {
            Application app = getFactory(context.getPackageName())
                    .instantiateApplication(cl, className);
            app.attach(context);//2
            return app;
    }
    public void callApplicationOnCreate(Application app) {
            app.onCreate();//3
    }
    
    • 注释1 -> 创建App的上下文环境,ContextImpl是Context的子类,getApplicationContext()中获取到的Context其实就是ContextImpl。
    • 注释2 -> 一路往下调用,发现Application是通过类加载器和反射创建的,并把Context绑定到Application。
    • 注释3 -> Application中的onCreate方法调用

    总结:创建Application步骤
    1、获取系统分配的pid和uid。
    2、通过IApplicationThread请求当前进程。
    3、发送消息把创建逻辑切换到UI线程中,如果现在可能是在其他线程的话。
    4、通过类加载器和反射创建Application并绑定一个上下文环境。
    5、最后执行Application中的onCreate方法完成整个Application的创建并初始化。

    创建Activity

    ##ActivityStackSupervisor
    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
            ...
            if (realStartActivityLocked(activity, app,
                    top == activity /* andResume */, true /* checkConfig */)) {
                didSomething = true;
            }
            ...
    }
    

    realStartActivityLocked,真正开始Activity的创建。

    ##ActivityStackSupervisor
    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                                              boolean andResume, boolean checkConfig) throws RemoteException {
            ...
            // 创建启动Activity
            final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                    r.appToken);
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                    profilerInfo));  //添加LaunchActivityItem的回调
            // Set desired final state.
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);
            // 通过生命周期管理对象ClientLifecycleManager,来管理Activity的生命周期状态
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            ...
            return true;
    }
    
    ##ClientLifecycleManager
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            final IApplicationThread client = transaction.getClient();
            //ClientTransaction是个javabean 实现了Parcelable 序列化。
            //schedule()方法内部,会回调到ActivityThread.ApplicationThread的scheduleTransaction()方法
            transaction.schedule();
            if (!(client instanceof Binder)) {
                // If client is not an instance of Binder - it's a remote call and at this point it is
                // safe to recycle the object. All objects used for local calls will be recycled after
                // the transaction is executed on client in ActivityThread.
                transaction.recycle();
            }
    }
    
    ##ActivityThread.ApplicationTread
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            //ActivityThread.this 指的是父类ClientTransactionHandler
            ActivityThread.this.scheduleTransaction(transaction);
    }
    
    ##ClientTransactionHandler
    void scheduleTransaction(ClientTransaction transaction) {
            transaction.preExecute(this);
            //发送Handler消息
            sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    

    执行这一系列的方法后,会发送一条消息,在ActivithThread中处理。

    ##ActivityThread.H
    public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                ...
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    //开始执行
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;
                    ...
            }
            ...
    }
    
    ##TransactionExecutor
    public void execute(ClientTransaction transaction) {
            final IBinder token = transaction.getActivityToken();
            log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
            executeCallbacks(transaction);  //1
            executeLifecycleState(transaction);  //5
            mPendingActions.clear();
            log("End resolving transaction");
    }
    public void executeCallbacks(ClientTransaction transaction) {
            final List<ClientTransactionItem> callbacks = transaction.getCallbacks();  //2
            ...
            for (int i = 0; i < size; ++i) {
                final ClientTransactionItem item = callbacks.get(i);  //3
                ...
                item.execute(mTransactionHandler, token, mPendingActions);  //4
                ...
            }
    }
    
    ##LaunchActivityItem
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
                PendingTransactionActions pendingActions) {
            ...
            client.handleLaunchActivity(r, pendingActions, null /* customIntent */);//5
            ...
    }
    
    • 注释1 -> 执行回调。
    • 注释2 -> 获取到ClientTransaction中的ClientTransactionItem集合。
    • 注释3 -> 处理回调,这里获取到的ClientTransactionItem是LaunchActivityItem。
    • 注释4 -> 调用LaunchActivityItem中的execute方法。
    • 注释5 -> 发送一个创建Activity的消息,ClientTransactionHandler其实就是ActivityThread,这是它的子类。 LaunchActivityItem可以把它理解成队列中等待创建的Activity实例,说白了就是最终调用的位置是在ActivityThread的handleLaunchActivity方法中去处理。
    ##ActivityThread
    public Activity handleLaunchActivity(ActivityClientRecord r,
                                             PendingTransactionActions pendingActions, Intent customIntent) {
            ...
            //开始执行Activity的创建
            final Activity a = performLaunchActivity(r, customIntent);
            ...
            return a;
    }
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
            ActivityInfo aInfo = r.activityInfo;   //1
            ...
            ContextImpl appContext = createBaseContextForActivity(r);   //2
            Activity activity = null;
            try {
                java.lang.ClassLoader cl = appContext.getClassLoader();   //3
                activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);  //4
               ...
            } catch (Exception e) {
               ...
            }
            ...
            //调用Activity的OnCreate()方法
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);   //5
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);   
            }
            ...
            return activity;
    }
    
    ##Instrumentation
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
            prePerformCreate(activity);
           
            activity.performCreate(icicle);
            postPerformCreate(activity);
    }
    
    ##Activity
    final void performCreate(Bundle icicle) {
            performCreate(icicle, null);
    }
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
            mCanEnterPictureInPicture = true;
            restoreHasCurrentPermissionRequest(icicle);
            //onCreate 生命周期方法被调用
            if (persistentState != null) {
                onCreate(icicle, persistentState);
            } else {
                onCreate(icicle);
            }
            ...
    }
    
    • 注释1 -> 获取Activity的信息。
    • 注释2 -> 获取Activity的上下文环境。
    • 注释3 -> 获取类加载器。
    • 注释4 -> 通过类加载器和反射创建出一个Activity。
    • 注释5 -> 调用Activity的onCreate方法。到这里就完成了一个Activity的创建。

    总结:Activity的创建
    1、前期先做好Activity创建前的一系列相关环境配置
    2、依然是通过ActivityThread的Handler把需要创建Activity的消息发送过去并把对应的申请放入到ClientTransaction队列当中。
    3、最终消息会回到ActivityThread的handleLaunchActivity方法中去处理,在里面完成Activity的创建步骤。

    • 获取Activity的信息
    • 获取Activity的上下文环境
    • 获取类加载器
    • 通过类加载器和反射创建出一个Activity
    • 调用Activity的onCreate方法。到这里就完成了一个Activity的创建

    相关文章

      网友评论

          本文标题:Android应用程序的启动

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