美文网首页高级UI
Application的创建、Activity的创建

Application的创建、Activity的创建

作者: 沐白白白白白 | 来源:发表于2019-10-28 17:50 被阅读0次

    关于Activity需要知道的更多内容

    前言

    Activity作为作为四大组件中我们最常见的一个组件,经常接触使用,但是往往每次让我们对这个组件进行说明的时候,我们只知道它的几个生命周期,几种启动模式,但是具体的更多的就讲不出来了。
    ps:我在写这个之前实际上也是一知半解,所以今天我们一起去看看Activity更多的东西,源码版本为 android-26

    • 1、Application的创建
    • 2、Activity的创建和生命周期

    一、Application的创建

    我们知道,java程序想运行都是通过调用main方法来启动,我们的Android应用程序也是如此,但是我们每次都是直接点击手机屏幕的应用图标就直接启动了app,这时候难免有疑惑,我们为什么不需要调用main方法就可以直接启动我们的程序呢,虽然我们没有直接的去写main方法,但是实际上还是通过ActivityThread类的main方法来作为我们应用程序的入口。

    # ActivityThread类
    public static void main(String[] args) {
            ...
            Looper.prepareMainLooper();
            ActivityThread thread = new ActivityThread();//1、这边new了一个ActivityThread对象
            thread.attach(false);//2、这边去进行连接,连接什么?
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
            if (false) {
                Looper.myLooper().setMessageLogging(new
                        LogPrinter(Log.DEBUG, "ActivityThread"));
            }
            Looper.loop();
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    

    在ActivityThread类中,能看到一个main方法,它就是我们程序的入口,在注释1的地方,会去创建一个ActivityThread对象,在注释2的地方,调用thread的attach方法去连接,具体的连接什么我们继续看下面的代码

      #ActivityThread类
      private void attach(boolean system) {
            ...
            if (!system) {
                ...
                final IActivityManager mgr = ActivityManager.getService();//1、通过AIDL,获取AMS的代理对象IActivityManager
                try {
                    mgr.attachApplication(mAppThread);//2、这边将AMS和我们的应用进程application进行连接
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            } else {
                ...
            }
        }
    

    关于AIDL,这边不进行展开,我们关心的是注释2,这边通过AIDL将AMS和我们应用进程application进行连接,具体的是调用ActivityManagerService的attachApplication方法进行连接。

      #ActivityManagerService类
      @Override
      public final void attachApplication(IApplicationThread thread) {
            synchronized (this) {
                int callingPid = Binder.getCallingPid();//1、获取pid
                final long origId = Binder.clearCallingIdentity();
                attachApplicationLocked(thread, callingPid);//2、传入pid进行连接
                Binder.restoreCallingIdentity(origId);
            }
        }
    

    这边的注释1通过Binder对象获取应用的pid,注释2处调用attachApplicationLocked的方法传入pid连接application。需要注意的这边加了synchronized关键字,表示我们需要等待这里执行完毕才能下一步,也就是说我们一个应用需要当我们application被连接后才能走下面的流程。

    ##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、根据id获取相关信息赋值给记录对象
                }
            } 
            ...
            if (app.instr != null) {  //3、判断进程是否正在活跃
               //Application 4、绑定到当前线程
               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);   
            } else {
                //Application 4、绑定到当前线程
                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);  
            }
            ...
            // See if the top visible activity is waiting to run in this process...
            //查看顶部可见活动是否正在等待在此进程中进行
            if (normalMode) {
                try {
                    //TODO 5、Activity创建的分析
                    //检测top的Activity是否在运行中等待
                    if (mStackSupervisor.attachApattachApplicationplicationLocked(app)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                    badApp = true;
                }
            }
    
            // Find any services that should be running in this process...
            //查看在此进程中进行的服务
            if (!badApp) {
                try {
                    didSomething |= mServices.attachApplicationLocked(app, processName);
                    checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                    badApp = true;
                }
            }
    
            // Check if a next-broadcast receiver is in this process...
            //查看在此进程中进行的广播接收者
            if (!badApp && isPendingBroadcastProcessLocked(pid)) {
                try {
                    didSomething |= sendPendingBroadcastsLocked(app);
                    checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
                } catch (Exception e) {
                    // If the app died trying to launch the receiver we declare it 'bad'
                    Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
                    badApp = true;
                }
            }
    
            // Check whether the next backup agent is in this process...
            //检测下一个备份代理是否在此进程中
            if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
                        "New app is backup target, launching agent for " + app);
                notifyPackageUse(mBackupTarget.appInfo.packageName,
                        PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
                try {
                    thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                            compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                            mBackupTarget.backupMode);
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
                    badApp = true;
                }
            }
            ...
    }
    

    看具体的attachApplicationLocked方法里面,注释1处创建了一个进程记录对象用来保存进程的相关信息,注释2根据id获取到相关信息赋值给记录对象,注释3先判断进行是否活跃,然后调用bindApplication的方法进行application的绑定,这边的thread是IApplicationThread对象,IApplicationThread它是一个AIDL的接口,是系统进程调用应用进程的接口,它的实现类是ApplicationThread,是一个在ActivityThread的内部类,注释5的地方是关于Activity的创建,我们这边先跳过,等我们将Application进行绑定完成后在来分析。

    ##ActivityThread.ApplicationThread
    public final void bindApplication(String processName, ApplicationInfo appInfo...,String buildSerial) {
    
                if (services != null) {
                    // Setup the service cache in the ServiceManager
                    ServiceManager.initServiceCache(services);
                }
    
                setCoreSettings(coreSettings);//1、添加核心设置
    
                //2、将bindApplication带进来的信息封装到AppBindData类中,通过handler发送出去
                AppBindData data = new AppBindData();
                data.processName = processName;
                data.appInfo = appInfo;
                data.providers = providers;
                ...
                sendMessage(H.BIND_APPLICATION, data);//3、将data通过handler发送出去,具体的WHAT 是 H.BIND_APPLICATION
            }
    

    在注释1会去添加一些核心的设置,我们这边就不去关注,我们看注释2的地方,去将带进来的信息封装到data中然后在注释3通过handler发送出去,具体的WHAT 是 H.BIND_APPLICATION。H是一个继承Handler的子类,这边我们去看下消息是如何被分发处理的。

    ##ActivityThread.H
    public void handleMessage(Message msg) {
                ...
            switch (msg.what) {
                ...
               case BIND_APPLICATION:
                        //1、这边进行handler消息的处理 处理创建Application的消息
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                        AppBindData data = (AppBindData) msg.obj;
                        handleBindApplication(data);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                ...
            }
            ...
    }
    
    

    这边注释1处理创建Application的消息,调用handleBindApplication的方法去绑定application

      ##ActivityThread
      private void handleBindApplication(AppBindData data) {
    
            final InstrumentationInfo ii;//1、创建InstrumentationInfo对象
    
            ...
    
           
            final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 2、 //获取application的context上下文
            
            //  3、加载instrumentation
            if (ii != null) {
                ...
                
                mInstrumentation.init(this, instrContext, appContext, component,
                        data.instrumentationWatcher, data.instrumentationUiAutomationConnection); //4、instrumentation初始化
                ...
            } else {
                mInstrumentation = new Instrumentation();
            }
    
            try {
              
                Application app = data.info.makeApplication(data.restrictedBackupMode, null);//5、通过makeApplication方法创建application
    
                ...
                
                // Do this after providers, since instrumentation tests generally start their
                // test thread at this point, and we don't want that racing.
                try {
                    mInstrumentation.onCreate(data.instrumentationArgs);
                } catch (Exception e) {
                    throw new RuntimeException(
                            "Exception thrown in onCreate() of "
                                    + data.instrumentationName + ": " + e.toString(), e);
                }
    
                try {
                    mInstrumentation.callApplicationOnCreate(app);//6、回调application的onCreate方法
                } catch (Exception e) {
                    if (!mInstrumentation.onException(app, e)) {
                        throw new RuntimeException(
                                "Unable to create application " + app.getClass().getName()
                                        + ": " + e.toString(), e);
                    }
                }
            } finally {
                StrictMode.setThreadPolicy(savedPolicy);
            }
        }
    
    

    这个方法里面处理了许多事情,注释1创建了一个InstrumentationInfo对象,在注释2获取了application的上下文,注释3和4去加载并初始化了InstrumentationInfo,注释5是我们的关键地方,通过调用makeApplication的方法创建了我们的application,我们看下makeApplication的方法都做了什么操作。然后在注释6调用InstrumentationInfo去回调application的onCreate方法,到这里我们的application就创建并且回到了我们熟悉onCreate方法。

     ##LoadedApk
     public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
            if (mApplication != null) {//1、如果mApplication不为null,直接返回mApplication对象
                return mApplication;
            }
          
            Application app = null;
           //如果是有自定义的application,就用这个,如果没有,就用系统的application
            String appClass = mApplicationInfo.className;
            if (forceDefaultAppClass || (appClass == null)) {
                appClass = "android.app.Application";
            }
            try {
                //2、获得类加载器然后通过反射去new一个Appliction
                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;//3、赋值给mApplication
    
            if (instrumentation != null) {//4、这边会为instrumentation是为null的
                try {
                    instrumentation.callApplicationOnCreate(app);//5、这边如果instrumentation不为null,才能执行到这里
                } catch (Exception e) {
                    if (!instrumentation.onException(app, e)) {
                       ...
                    }
                }
            }
            ...
            return app;
        }
    
    

    这边我们首先判断mApplication如果不为null,直接返回这个对象,如果为null的话,我们通过类加载然后反射去new出一个application对象并且赋值给mApplication,还有这边因为我们在调用makeApplication方法时传入的Instrumentation是个null对象,所以我们这边不会去执行
    callApplicationOnCreate回调onCreate方法的。具体的回调onCreate会在上面的源码注释6的地方去执行回调。

    二、Activity的创建

    这边我们首先需要知道Activity的状态和生命周期

    状态:运行、暂停、停止、销毁(运行和暂停是不可见的,停止和销毁是不可见的)
    生命周期:包括了常见的onCreate、onResume、onStart、onPause、onStop、onDestory等

    上面的分析过程中我们在ActivityManagerService类中留了一个

    ##ActivityManagerService
    private final boolean attachApplicationLocked(IApplicationThread thread,
                                                      int pid, int callingUid, long startSeq) {
            ...
     //5、检测最可见的Activity是否在运行进程中等待,如果再则创建Activity
            //TODO 待分析Activity的创建
            if (mStackSupervisor.attachApplicationLocked(app)) {  
                didSomething = true;
            }
    }
    ...
    

    这边我们对它进行深入下看看是如何创建的

     ##ActivityStackSupervisor
     boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
            ...
            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
                ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                    final ActivityStack stack = stacks.get(stackNdx);
                    if (!isFocusedStack(stack)) {
                        continue;
                    }
                    //ActivityRecord来维护Activity运行时的状态信息,需要将Activity绑定到AMS,ActivityRecord才能开始Activity的生命周期
                    ActivityRecord hr = stack.topRunningActivityLocked();
                    if (hr != null) {
                        if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                                && processName.equals(hr.processName)) {
                            try {
                                if (realStartActivityLocked(hr, app, true, true)) {//1、真正的创建Activity
                                    didSomething = true;
                                }
                            } catch (RemoteException e) {
                                throw e;
                            }
                        }
                    }
                }
            }
            ...
            return didSomething;
        }
    
    

    在realStartActivityLocked我们会创建Activity

    ##ActivityStackSupervisor
     final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                boolean andResume, boolean checkConfig) throws RemoteException {
            ...
    
            r.startFreezingScreenLocked(app, 0);//1、开始屏幕相关的启动
            
    
            // schedule launch ticks to collect information about slow apps.
            r.startLaunchTickingLocked();//2、启动定时锁定
    
            r.app = app;
            app.waitingToKill = null;
            r.launchCount++;//3、每启动一次launchCount的数量自增
            r.lastLaunchTime = SystemClock.uptimeMillis();//4、修改最后一次的启动时间
    
            final ActivityStack stack = task.getStack();
            try {
                ...
    
                //5、根据具体的包名,通知应用
    
             mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
                                          PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
                
                ...
    
                //6、调用ApplicationThread的scheduleLaunchActivity 方法去启动LaunchActivity
                app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global and
                        // override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, !andResume,
                        mService.isNextTransitionForward(), profilerInfo);
    
                ...
            } catch (RemoteException e) {
                ...
            }
    
            ...
            if (isFocusedStack(stack)) {
                mService.startSetupActivityLocked();7、开始设置活动锁
            }
            if (r.app != null) {
                mService.mServices.updateServiceConnectionActivitiesLocked(r.app);//8、更新服务连接活动锁
            }
    
            return true;
        }
    
    

    这边的注释很多,但是我们主要关心的是注释6,这边调用ApplicationThread的scheduleLaunchActivity 方法去启动LaunchActivity,我们回到ApplicationThread

    ##ActivityThread.ApplicationThread
    @Override
    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                                           ..., ProfilerInfo profilerInfo) {
    
        updateProcessState(procState, false);
    
        ActivityClientRecord r = new ActivityClientRecord();
        ...
    
        sendMessage(H.LAUNCH_ACTIVITY, r);//通过handler发送启动Activity的消息
    }
    

    这边是不是很眼熟,我们刚刚的application的绑定也是通过handler去发送消息去处理(这边我们能发现handler是有多么重要了吧,哈哈),我们去ActivityThread的子类H去看下具体的activity创建的消息处理

    public void handleMessage(Message msg) {
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {//1、接收到关于创建Activity的消息,进行处理
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//2、去创建LaunchActivity
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                }
    }
    

    根据message的what值我们找到了具体的消息处理,这边会通过handleLaunchActivity去处理我们Activity创建

    ##ActivityThread
     private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
            ...
            Activity a = performLaunchActivity(r, customIntent);//1、去执行LaunchActivity
    
            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);//2、处理可见Activity
                ...
            } else {
                // If there was an error, for any reason, tell the activity manager to stop us.
                try {
                //3、这边如何activity是个null的对象,直接通过ActivityManagerService调用finishActivity去关闭掉
                    ActivityManager.getService()
                            .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                    Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }
        }
    

    这边我们先看注释1的performLaunchActivity方法

    ##ActivityThread
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
            ...
    
            ActivityInfo aInfo = r.activityInfo;//1、获取Activity的信息
            if (r.packageInfo == null) {
                r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                        Context.CONTEXT_INCLUDE_CODE);
            }
            ...
    
            ContextImpl appContext = createBaseContextForActivity(r);//2、获取Acitivty的上下文
            Activity activity = null;
            try {
                java.lang.ClassLoader cl = appContext.getClassLoader();//3、获取类加载器,使用cl(类加载器)加载出Activity,再使用反射new出Activity
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                StrictMode.incrementExpectedActivityCount(activity.getClass());
                r.intent.setExtrasClassLoader(cl);
                r.intent.prepareToEnterProcess();
                if (r.state != null) {
                    r.state.setClassLoader(cl);
                }
            } catch (Exception e) {
               ...
            }
    
            try {
                //4、这边又去调用一次makeApplication方法
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
                if (activity != null) {
                    ...
                    appContext.setOuterContext(activity);
    
                    activity.attach(appContext, this, getInstrumentation(), r.token,
                            r.ident, app, r.intent, r.activityInfo, title, r.parent,
                            r.embeddedID, r.lastNonConfigurationInstances, config,
                            r.referrer, r.voiceInteractor, window, r.configCallback);
    
                    ...
                    if (r.isPersistable()) {//5、这边去调用Activity的onCreate方法
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }
                    ...
    
            } catch (SuperNotCalledException e) {
                throw e;
    
            } catch (Exception e) {
               ...
            }
            return activity;
        }
    

    在注释3我们会发现这边是获取类加载去然后通过反射去new出一个Activity,然后在注释5去回调Activity的onCreate方法,到这边我们就能去调用我们的setContentView去加载布局了。注释4的地方又调用了一次makeApplication方法,如果Application不为null,直接返回application对象。
    现在我们回到上一个源码的注释2那里,看看handleResumeActivity都做了什么?

    ##ActivityThread
     final void handleResumeActivity(IBinder token,
                                        boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
            ...
            r = performResumeActivity(token, clearHide, reason);
            ...
        }
    
    

    这个方法里面有很多代码,我们只需要去看performResumeActivity方法

    ##ActivityThread
    public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide, String reason) {
        ...
        r.activity.performResume();//主要是这个方法
        ...
        return r;
    }
    

    这边是调用Activity的performResume方法

    ##Activity
    final void performResume() {
            performRestart();
    
            mFragments.execPendingActions();
    
            mLastNonConfigurationInstances = null;
    
            mCalled = false;
            // mResumed is set by the instrumentation
            mInstrumentation.callActivityOnResume(this);//回调Activity的onResume方法
           
        }
    

    到这边我们就能发现它跟Activity的onCreate的回调是类似的,都是通过mInstrumentation.callActivityxxx去回调执行。

    沿着别人走过的路,跟上去发现不一样的风景

    参考链接:https://www.jianshu.com/p/f55467033146

    相关文章

      网友评论

        本文标题:Application的创建、Activity的创建

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