Application的创建、Activity的创建

关于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 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的创建)