Android应用程序启动全过程(本文基于Android7.1)

准备

首先要了解Android应用启动过程需要有Framework层代码以及系统应用Launch的代码,当然也可以下载aosp源码,下载编译源码请参考官网

开始

从Binder说起

Binder可以用于IPC通信对于系统FrameWork来说一般用于客户端进程与系统服务进程进行通信,一般流程是客户端通过某种方法获得到对应于服务端Binder对象的BinderProxy对象(无论通过远程服务获取到还是通过ServieManager获得),然后客户端就可以通过这个BinderProxy对象调用服务端的方法 举例如下(Client调用AMS的startActivity)首先通过ServiceManger获取ActivityManagerProxy对象,然后调用其startActivity()

//ActivityManagerNative.java ActivityManagerNative$ActivityManagerProxy
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain(); //1
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeString(callingPackage);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);//2
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }

该方法主要做的内容是现在注释1这里创建了两个Parcel对象一个用来封装调用参数,一个用来储存返回值,接着调用writeXXX来把请求参数写入到Parcel对象中,然后调用注释2的mRemote.transact(code..),调用该方法后会挂起当前线程(直到server进程的onTransact()执行完client线程才能获取到返回值并继续运行),然后切换到SystemProcess进程执行ActivityManagerNative.onTransact()代码如下

 @Override
 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
         throws RemoteException {
     switch (code) {
     case START_ACTIVITY_TRANSACTION:
     {
         data.enforceInterface(IActivityManager.descriptor);
         IBinder b = data.readStrongBinder();
         IApplicationThread app = ApplicationThreadNative.asInterface(b);
         String callingPackage = data.readString();
         Intent intent = Intent.CREATOR.createFromParcel(data);
         String resolvedType = data.readString();
         IBinder resultTo = data.readStrongBinder();
         String resultWho = data.readString();
         int requestCode = data.readInt();
         int startFlags = data.readInt();
         ProfilerInfo profilerInfo = data.readInt() != 0
                 ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
         Bundle options = data.readInt() != 0
                 ? Bundle.CREATOR.createFromParcel(data) : null;
         int result = startActivity(app, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
         reply.writeNoException();
         reply.writeInt(result);
         return true;
     }
     ...
}

该方法根据客户端的code来调用对应的方法,然后从Parcel里面取出请求参数,调用其startActivity(),而在SystemProgress里AMS实现了ActivityManagerNative因此会调用AMS里面的startActivity()

客户端启动过程

当zygote进程启动并且通过fork自身创建完系统进程后就进入了等待连接状态,系统进程初始化完成后就会启动Launch应用程序(如何启动的与下文其他应用程序类似,只是其Intent不同)当Launch应用程序所在进程被创建后就会调用到ActivityThread.main()代码如下

public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        SamplingProfilerIntegration.start();
        CloseGuard.setEnabled(false);
        Environment.initForCurrentUser();
        EventLogger.setReporter(new EventLoggingReporter());
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
        Process.setArgV0("<pre-initialized>");
        Looper.prepareMainLooper();//1
        ActivityThread thread = new ActivityThread();//2
        thread.attach(false);//3
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();//4
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

该方法关键代码主要有四个地方
1. 调用Looper.prepareMainLooper() 创建了一个主线程的Looper(内部包含MessageQuene)
2. 创建ActivityThread对象其目的主要有两个1.创建了ApplicationThread对象2.创建了H类(Handler类对象)由于主线程中已经拥有了Looper所以可以成功的创建
3. 调用thread.attach(false)下面会介绍
4. 调用Looper.loop()死循环不断调用MessageQuene获取消息,唯一退出方式是Looper.quit()不过mainLooper不能退出Message.quit()里面会判断如果是main线程会抛出异常
下面看看注释3代码执行过程

private void attach(boolean system) {//1
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                @Override
                public void run() {
                    ensureJitEnabled();
                }
            });
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManagerNative.getDefault();//2
            try {
                mgr.attachApplication(mAppThread);//3
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            // Watch for getting close to heap limit.
            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                                + " total=" + (runtime.totalMemory()/1024)
                                + " used=" + (dalvikUsed/1024));
                        mSomeActivitiesChanged = false;
                        try {
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            });
        } else {
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }
        ...
    }
  1. 如果当前进程是SystemServer进程则参数为true(在创建AMS前会调用),否则为false
  2. 获取一个AMS的代理对象即ActivityManagerProxy
  3. 通过ActivityManagerProxy对象IPC调用AMS的attachApplication()
    下面来看看AMS的attachApplication()
//ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

然后又调用到了AMS的attachApplicationLocked()

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
            ...
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());//1
            updateLruProcessLocked(app, false, null);
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {
            app.resetPackageList(mProcessStats);
            app.unlinkDeathRecipient();
            startProcessLocked(app, "bind fail", processName);
            return false;
        }
        mPersistentStartingProcesses.remove(app);
        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
                "Attach application locked removing on hold: " + app);
        mProcessesOnHold.remove(app);

        boolean badApp = false;
        boolean didSomething = false;

        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {//2
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        ...
        return true;
    }

该方法主要工作有两个工作先来看看注释1,通过ApplicationThread这个Binder对象IPC调用ApplicationThread.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) {
            if (services != null) {
                ServiceManager.initServiceCache(services);
            }
            setCoreSettings(coreSettings);
            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providers;
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            sendMessage(H.BIND_APPLICATION, data);
        }

ApplicationThread发送了一个消息返回了,然后执行AMS.attachApplicationLocked()注释二处的代码mStackSupervisor.attachApplicationLocked()(注意这里Client虽然Looper和Handler都已经创建了但是这个消息并不能立即得到执行因为这里还没有调用Looper.loop() )

//ActivityStackSupervisor
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        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 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)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
        return didSomething;
    }

上述代码又调用到了ActivityStackSupervisor.realStartActivityLocked()

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
            ...
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
            ...
        } catch (RemoteException e) {
            if (r.launchFailed) {
                mService.appDiedLocked(app);
                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                        "2nd-crash", false);
                return false;
            }
            app.activities.remove(r);
            throw e;
        }
        ...
        return true;
    }

又通过ApplicationThread这个Binder对象IPC调用到了ApplicationThread.scheduleLaunchActivity()

@Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
            updateProcessState(procState, false);
            ActivityClientRecord r = new ActivityClientRecord();
            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;
            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;
            r.startsNotResumed = notResumed;
            r.isForward = isForward;
            r.profilerInfo = profilerInfo;
            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

又只是发了个消息就返回了,至此AMS的事情正式完成了,客户端主线程又开始执行,当ActivityThread执行到Looper.loop()就开始从消息队列中取消息了

public static void main(String[] args) {
    Looper.prepareMainLooper();
    Looper.loop();
}

而当前应用程序主线程的MessageQuene里面应该包含两个消息,首先先执行H.BIND_APPLICATION,来看看H类的handleMessage()
1. H.BIND_APPLICATION
2. H.LAUNCH_ACTIVITY

//ActivityThread.java ActivityThread$H
public void handleMessage(Message msg) {
      switch (msg.what) {
          ...
           case BIND_APPLICATION:
               AppBindData data = (AppBindData)msg.obj;
               handleBindApplication(data);
               break;
           ...
      }
      ...
}

从Message里面获取到了AppBindData,然后执行handleBindApplication()

//ActivityThread.java
private void handleBindApplication(AppBindData data) {
        final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
                DateFormat.set24HourTimePref(is24Hr); //1
        ...
        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);//2
        ...
        if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) { //3
            StrictMode.enableDeathOnFileUriExposure();
        }
        ...
        if (data.debugMode != IApplicationThread.DEBUG_OFF) {
            Debug.changeDebugPort(8100);
            if (data.debugMode == IApplicationThread.DEBUG_WAIT) {//4
                IActivityManager mgr = ActivityManagerNative.getDefault();//5
                try {
                    mgr.showWaitingForDebugger(mAppThread, true);//6
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
                Debug.waitForDebugger();//7
                try {
                    mgr.showWaitingForDebugger(mAppThread, false);//8
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            } else {
                ...
            }
        }
        final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
        if (b != null) {
            final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
            try {
                final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
                Proxy.setHttpProxySystemProperty(proxyInfo);//9
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        final InstrumentationInfo ii;
        ...
        if (ii != null) {
            ...
        } else {
            mInstrumentation = new Instrumentation();//10
        }
        try {
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);//10
            mInitialApplication = app;
            ...
            try {
                mInstrumentation.callApplicationOnCreate(app);//12
            } 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);
        }
    }

该方法需要关注以下12点,先来看看第11点
1. 设置时间格式12小时制或者是24小时制
2. 创建LoadApk实例,该实例用来创建Activity、Application等等
3. 如果当前系统SDK版本大于等于24就不允许使用类似file://开头的Uri
4. 判断是否需要debug(从as里面直接run debug或者在开发人员选项里面选择该程序为调试程序)
5. 获取AMS的client代理对象ActivityManagerProxy
6. IPC调用AMS.showWaitingForDebugger(true),AMS会弹出一个dialog显示等待调试器(debug的时候常常会遇到该dialog)
7. 循环等待调速器attach,在该方法执行完后才能进行debug因此该方法前运行的语句在不修改源码的情况下是没法调试的
8. IPC调用AMS.showWaitingForDebugger(false), AMS会调用dialog.dismiss(),表明可以调试了
9. 设置应用程序的网络代理
10. 创建了一个Instrumentation实例该实例用来调用Activity的生命周期
11. 调用LoadApk.makeApplication()创建Application实例
12. 调用Application.onCreate()

//LoadApk.java
public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) { //1
            return mApplication;
        }
        Application app = null;
        String appClass = mApplicationInfo.className;
        try {
            java.lang.ClassLoader cl = getClassLoader();
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);//2
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);//3
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ...
        }
        mApplication = app;
        return app;
    }

该方法主要就是创建Application对象并调用其onCreate()
1. 一个进程里面只会存在一个Application对象(如果一个应用程序中有其他组件运行在其他进程,则会创建多个Application对象)
2. 创建Application的ContextImpl实例
3. 通过反射创建Application对象并且调用它的attach(appContext)

接下来来看看ActivityThread.handleBindApplication()的第12点,内部就简单调用了Application.onCreate()

public void callApplicationOnCreate(Application app) {
    app.onCreate();
}

至此一个应用程序的Application对象已经创建了并且调用了其onCreate(),下面来看看第二个消息H.LAUNCH_ACTIVITY

//ActivityThread.java ActivityThread$H
public void handleMessage(Message msg) {
    switch (msg.what) {
       case LAUNCH_ACTIVITY: {
              final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
              r.packageInfo = getPackageInfoNoCheck(
                      r.activityInfo.applicationInfo, r.compatInfo);
              handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
       } 
       ...
}

该方法内部取出ActivityClientRecord对象并且调用handleLaunchActivity()

//ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        Activity a = performLaunchActivity(r, customIntent);//1
        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
            ...
        } 
        ...
    }

该方法主要做了以下两件事,先来看看1
1. 调用performLaunchActivity()去创建Activity对象并调用其onCreate()
2. handleResumeActivity去调用Activity.onResume()

//ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);//1
             ...
        } catch (Exception e) {
            ...
        }
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);//2
            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());//3
                ...
                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);//4
                ...
                int theme = r.activityInfo.getThemeResource();//5
                if (theme != 0) {
                    activity.setTheme(theme);
                }
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);//6
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");//7
                }
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();//8
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);//9
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);//10
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;
            mActivities.put(r.token, r);
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            ...
        }
        return activity;
    }

该方法的重点是以下10点
1. 通过反射创建Activity实例
2. 检测当前进程是否存在Application实例若没有则创建(当Activity在清单文件中配置到其他进程中会创建Application实例)
3. 加载配置文件中的label属性并设置为title
4. 调用Activity.attach() 内部创建了PhoneWindow实例,并且调用PhoneWindow.setCallback(activity)用来获取触摸事件等等
5. 获取清单文件中的Activity的主题并设置
6. 调用Activity的onCreate(),内部调用Fragment.onCreate(),其他生命周期也一样先调Activity的再掉Fragment的
7. 若没调用Activity.onCreate()则抛出异常,下同(onStart()…)
8. 调用Activity.onStart()
9. 判断是否有保存数据(被系统杀死或者Configuration发生改变r.state不等于null),若有则调用Activity.onRestoreInstanceState()其参数savedInstanceState一定不为空,onCreate()的时候可能为空
10. 调用Activity.onPostCreate()
到现在为止Activity实例已经创建了并且也调用了onCreate()、onStart()但是当前Activity还处于后台View还没绘制,下面来看看handleResumeActivity()

ActivityThread.java
final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
        ...
        r = performResumeActivity(token, clearHide, reason);//1
        if (r != null) {
            final Activity a = r.activity;
            r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                ...
                if (a.mVisibleFromClient && !a.mWindowAdded) {
                    a.mWindowAdded = true;
                    wm.addView(decor, l); //2
                }
            } else if (!willBeVisible) {
                ...
            }
            ...
    }

这个方法需要关注两点
1. 调用performResumeActivity()
2. wm.addView()内部去绘制View 进行View的三大流程执行完后才能看到界面
来看看performResumeActivity()

public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null && !r.activity.mFinished) {
             ...
             try {
                 ...
                 r.activity.performResume();
             } catch (Exception e) {
                 ...
             }
        }
        return r;
  }

内部就调用了Activity.onResume(),而在Activity.onResume()里面会判断当前Activity是否显示在前台若没显示在前台则会等待1秒,当View绘制完毕后就第一个Activity就显示出来了。

为什么点击launch界面的应用程序图标就能把应用程序启动起来? 并且会打开该应用程序清单文件中的配置如下IntentFilter的Activity?

<intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

先来看下点击Launch上的应用程序图标都执行了什么代码

//launch2/launch.java
boolean startActivitySafely(View v, Intent intent, Object tag) {
        boolean success = false;
        try {
            success = startActivity(v, intent, tag);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
        }
        return success;
}

那么这个Intent对象是从哪来的呢?翻看源码后发现是在构造ApplicationInfo时创建的其代码如下

//Launch2/LaunchMode.java
//其中的LaunchActivityInfo里面保存了对应Application的入口Activity的组件名
public ApplicationInfo(LauncherActivityInfo info, UserHandle user, IconCache iconCache,
            HashMap<Object, CharSequence> labelCache) { 

        this.componentName = info.getComponentName();
        this.container = ItemInfo.NO_ID;

        int appFlags = info.getApplicationInfo().flags;
        if ((appFlags & android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0) {
            flags |= DOWNLOADED_FLAG;
        }
        if ((appFlags & android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
            flags |= UPDATED_SYSTEM_APP_FLAG;
        }
        firstInstallTime = info.getFirstInstallTime();
        iconCache.getTitleAndIcon(this, info, labelCache);
        intent = new Intent(Intent.ACTION_MAIN);  //action
        intent.addCategory(Intent.CATEGORY_LAUNCHER); //category
        intent.setComponent(info.getComponentName()); //组件
        intent.putExtra(EXTRA_PROFILE, user);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION;
        updateUser(intent);
    }

startActivitySafely里面又调用了startActivity(v, intent, tag)代码如下

boolean startActivity(View v, Intent intent, Object tag) {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //为新打开的应用程序创建新的Activity栈
        try {
            boolean useLaunchAnimation = (v != null) &&
                    !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
            UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE);
            LauncherApps launcherApps = (LauncherApps)
                    this.getSystemService(Context.LAUNCHER_APPS_SERVICE);
            if (useLaunchAnimation) {
                ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,
                        v.getMeasuredWidth(), v.getMeasuredHeight());
                if (user == null || user.equals(android.os.Process.myUserHandle())) {
                    // Could be launching some bookkeeping activity
                    startActivity(intent, opts.toBundle());
                } else {
                    launcherApps.startMainActivity(intent.getComponent(), user,
                            intent.getSourceBounds(),
                            opts.toBundle());
                }
            } else {
                if (user == null || user.equals(android.os.Process.myUserHandle())) {
                    startActivity(intent); //1
                } else {
                    launcherApps.startMainActivity(intent.getComponent(), user,
                            intent.getSourceBounds(), null);
                }
            }
            return true;
        } catch (SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Launcher does not have the permission to launch " + intent +
                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +
                    "or use the exported attribute for this activity. "
                    + "tag="+ tag + " intent=" + intent, e);
        }
        return false;
    }

然后又调用到了注释1处的startActivity(intent),Activity的startActivity最终调到了如下代码处

//Activity.java
//这里的requestCode = -1,options = null
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options); //1
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

该方法会执行注释1处的代码,其中的mInstrumentation是在Lunch这个Activity反射创建后调用attach赋值的,该类主要用于创建Application、Activity以及调用Activity的生命周期方法,然后再来看下Instrumentation.execStartActivity()

//Instrumentation.java
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;//1
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                if (am.match(who, null, intent)) {
                    am.mHits++;
                    if (am.isBlocking()) {
                        return requestCode >= 0 ? am.getResult() : null;
                    }
                    break;
                }
            }
        }
    }
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options); //2
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

该方法需要关注的地方只有注释1和注释2,其中注释1获取了ApplicationThread对象该对象是一个Binder对象,AMS通知Client应用程序几乎都是通过该Binder对象进行IPC调用,注释二调用了ActivityManagerNative.getDefault().startActivity(),先来看看ActivityManagerNative.getDefault()是个什么东西,代码如下所示

//ActivityManagerNative.java
static public IActivityManager getDefault() {
   return gDefault.get();
}

其中gDefault是一个Singleton<IActivityManager>对象其get方法如下

//Singleton.java
public final T get() {
    synchronized (this) {
        if (mInstance == null) {
            mInstance = create();
        }
        return mInstance;
    }
}

因此只要看其create方法即可

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        IBinder b = ServiceManager.getService("activity"); //1
        if (false) {
            Log.v("ActivityManager", "default service binder = " + b);
        }
        IActivityManager am = asInterface(b);
        if (false) {
            Log.v("ActivityManager", "default service = " + am);
        }
        return am;
    }
};

注释1通过ServiceManger获取AMS的BinderProxy对象也就是ActivityManagerProxy(该类是ActivityManagerNative的内部类,整个ActivityManagerNative类可以看做是使用AIDL自动生成的类)对象,并返回,然后来看看ActivityManagerProxy.startActivity()

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain(); //1
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeString(callingPackage);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);//2
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }

该方法主要做的内容是现在注释1这里创建了两个Parcel对象一个用来封装调用参数,一个用来储存返回值,接着调用writeXXX来把请求参数写入到Parcel对象中,然后调用注释2的mRemote.transact(code..),调用该方法后会挂起当前线程(直到server进程的onTransact()执行完client线程才能获取到返回值并继续运行),然后切换到SystemProcess进程执行ActivityManagerNative.onTransact()代码如下

 @Override
 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
         throws RemoteException {
     switch (code) {
     case START_ACTIVITY_TRANSACTION:
     {
         data.enforceInterface(IActivityManager.descriptor);
         IBinder b = data.readStrongBinder();
         IApplicationThread app = ApplicationThreadNative.asInterface(b);
         String callingPackage = data.readString();
         Intent intent = Intent.CREATOR.createFromParcel(data);
         String resolvedType = data.readString();
         IBinder resultTo = data.readStrongBinder();
         String resultWho = data.readString();
         int requestCode = data.readInt();
         int startFlags = data.readInt();
         ProfilerInfo profilerInfo = data.readInt() != 0
                 ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
         Bundle options = data.readInt() != 0
                 ? Bundle.CREATOR.createFromParcel(data) : null;
         int result = startActivity(app, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
         reply.writeNoException();
         reply.writeInt(result);
         return true;
     }
     ...
}

该方法根据客户端的code来调用对应的方法,然后从Parcel里面取出请求参数,调用其startActivity(),而在SystemProgress里AMS实现了ActivityManagerNative因此会调用AMS里面的startActivity()

//ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}

又调用到了startActivityAsUser()

@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
         int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
     enforceNotIsolatedCaller("startActivity");
     userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
             userId, false, ALLOW_FULL_ONLY, "startActivity", null);
     // TODO: Switch to user app stacks here.
     return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
             resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
             profilerInfo, null, null, bOptions, false, userId, null, null);
 }

然后调用了ActivityStarter.startActivityMayWait()

//ActivityStarter.java
final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
            Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask) {
        ...
        intent = new Intent(intent);
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
        // Collect information about the target of the Intent.
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
        ...
        int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor,
                resultTo, resultWho, requestCode, callingPid,
                callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                inTask);
        ...
        return res;
    }
}

接着又调用到了ActivityStarter.startActivityLocked

final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
        ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
        ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
        TaskRecord inTask) {
    ...
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
            intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
            requestCode, componentSpecified, voiceSession != null, mSupervisor, container,
            options, sourceRecord);
    ...
    try {
        mService.mWindowManager.deferSurfaceLayout();
        err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true, options, inTask);
    } finally {
        mService.mWindowManager.continueSurfaceLayout();
    }
    postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);
    return err;
}

该方法的主要内容就是创建了ActivityRecord对象,然后再调用ActivityStarter.startActivityUnchecked()

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
        ...
        mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);//1
        if (mDoResume) {
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                    ...
            } else {
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);//2
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);//2
        }
        return START_SUCCESS;
    }

上述代码注释1处用于处理根据启动模式以及Intent的flag判断Activity应该放入哪个栈中,然后调用注释二ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()

//ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);//1
    }
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || r.state != RESUMED) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);//2
    }
    return false;
}

根据Activity的目标栈是否存在调用注释1或2

//ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    ...
    try {
        ...
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    return result;
}

然后再调用resumeTopActivityInnerLocked

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
if (mResumedActivity != null) {
    if (DEBUG_STATES) Slog.d(TAG_STATES,
            "resumeTopActivityLocked: Pausing " + mResumedActivity);
    pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
}

经过一系列流程调用到了startPausingLocked()

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
     ActivityRecord resuming, boolean dontWait) {
     ...
     if (prev.app != null && prev.app.thread != null) {
     if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
     try {
         EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                 prev.userId, System.identityHashCode(prev),
                 prev.shortComponentName);
         mService.updateUsageStats(prev, false);
         prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                 userLeaving, prev.configChangeFlags, dontWait);//1
     } catch (Exception e) {
         // Ignore exception, if process died other code will cleanup.
         Slog.w(TAG, "Exception thrown during pause", e);
         mPausingActivity = null;
         mLastPausedActivity = null;
         mLastNoHistoryActivity = null;
     }
 } else {
     mPausingActivity = null;
     mLastPausedActivity = null;
     mLastNoHistoryActivity = null;
 }
 ...

该方法关键代码就在注释1处,这里会通过上文说过ApplicationThread这个Binder对象IPC调用ActivityThread$ApplicationThread. 注:服务端通过ApplicationThread调用客户端方法客户端都会发送一个消息给H类(Handler)用于切换到UI线程

//ActivityThread.java ActivityThread$ApplicationThread
public final void schedulePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport) {
    int seq = getLifecycleSeq();
    if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
            + " operation received seq: " + seq);
    sendMessage(
            finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
            token,
            (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
            configChanges,
            seq);
}

来看看handleMessage()

public void handleMessage(Message msg) {
    case PAUSE_ACTIVITY_FINISHING: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
                            args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
                } break;
}

private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
        ActivityClientRecord r = mActivities.get(token);
        ...
        if (r != null) {
            ...
            performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");//1
            if (!dontReport) {
                try {
                    ActivityManagerNative.getDefault().activityPaused(token);//2
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }
            mSomeActivitiesChanged = true;
        }
    }

注释1会调用Launch.onPause(),注释2则又IPC调用AMS.activityPaused()通知AMS onPause()已经调用完毕了,在stack.activityPausedLocked()经过一系列流程会判断待启动的Activity的进程是否存在若不存在会调用Process.start()来给Zygote进程发送消息使之fork自己创建一个子进程,然后调用刚启动的应用程序的ActivityThread.main(),这与上文启动一模一样。

//ActivityManagerService.java
public final void activityPaused(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityPausedLocked(token, false);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

猜你喜欢

转载自blog.csdn.net/qq_22194581/article/details/79752863
今日推荐