Service启动过程and新进程创建全过程源码分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yulong0809/article/details/77772683

由于Android本身对于四大组件的封装,导致在开发当中根本不需要知道四大组件的底层原理及运行过程,但是如果作为一个高级者来说或者为了解决一些底层出现的问题,那么了解四大组件的运行原理和启动过程那么非常必要的。而且目前市面上的热修复,插件化技术越来越火,那么如果连四大组件的启动过程和运行原理都不知道的话,那么也就根本就不明白这些技术的实现原理的,总之好处还是大大的,那么就让我们来一起研究一下吧。

在阅读源码以前还是先简要的说一下,其实四大组件的底层原理是用了Binder机制,那么如果对Binder机制一点都不了解的话,希望还是先看一下Binder机制,之前也有写一篇关于Binder的文章,希望可以有所帮助插件化知识详细分解及原理 之Binder机制

我们先说Service的启动过程,下面会说新进程的启动过程

一、Service的启动过程 :

启动Service的方式有两种,一种是startService和bindService,虽然调用的方法不同,但是其底层原理基本都一样,这里就从startService开始了,本文源码基于5.1

然后我们先看一下继承关系:

这里写图片描述

1、一般情况下我们都是在Activity当中通过调用startService来启动的,但是Activity并没有重写Context的startService方法,而是调用了ContextWrapper中的startService方法,那么我们就从这里开始了

源码路径:
/frameworks/base/core/java/android/content/ContextWrapper.java

    @Override
    public ComponentName startService(Intent service) {
        return mBase.startService(service);
    }

2、通过上面的代码我们看到他调用了mBase.startService(service)方法,mBase是什么我们看一下,然后我们进入他的startService再看
这里写图片描述

我们看到mBase是Context类型,而Context是一个抽象类,它的实现类是ContextImpl,那么我们就直接去看ContextImpl中的startService就好了
源码路径:
/frameworks/base/core/java/android/app/ContextImpl.java

    @Override
    public ComponentName startService(Intent service) {
        //这里只判断了是否是系统进程,如果是打了一段log,忽略
        warnIfCallingFromSystemProcess();
        //调用了本类的startServiceCommon方法
        return startServiceCommon(service, mUser);
    }

3、上面又调用了ContextImpl类中的startServiceCommon方法,进去看看

    private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            //验证Intent的信息是否有效,无效抛出异常
            validateServiceIntent(service);            
            service.prepareToLeaveProcess();
            //这里又调用了ActivityManagerNative中startService
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
                //对远程调用的结果验证
            if (cn != null) {
                if (cn.getPackageName().equals("!")) {
                    throw new SecurityException(
                            "Not allowed to start service " + service
                            + " without permission " + cn.getClassName());
                } else if (cn.getPackageName().equals("!!")) {
                    throw new SecurityException(
                            "Unable to start service " + service
                            + ": " + cn.getClassName());
                }
            }
            return cn;
        } catch (RemoteException e) {
            return null;
        }
    }

4、上面又转到了ActivityManagerNative.getDefault().startService当中,而ActivityManagerNative.getDefault()是一个Binder对象,我们看一下
源码路径:
/frameworks/base/core/java/android/app/ActivityManagerNative.java

//ActivityManagerNative 类继承Binder 实现了IActivityManager
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    ...

    //getDefault方法返回了gDefault.get()
   static public IActivityManager getDefault() {
        return gDefault.get();
    }

    //gDefault是一个单例,
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
        //获取ActivityManagerService
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            //远程调用将ACtivityManagerService的代理类
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

    //asInterface方法将返回ActivityManagerService的代理类
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        //查询是否是本地调用
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        //返回代理
        return new ActivityManagerProxy(obj);
    }

    ...
}

5、通过上面的代码我们可以知道ActivityManagerNative.getDefault()返回的是ActivityManagerService的代理类,也就是ActivityManagerProxy,而ActivityManagerProxy是ActivityManagerNative的内部类其中的startService也只是发起了远程调用,最终会调用到ActivityManagerService中的startService方法,这里有不明白的请先看插件化知识详细分解及原理 之Binder机制

这里写图片描述

6、上面的代码会转到ActivityManagerService当中,调用startService方法,下面我们就去看ActivityManagerService当中的startService
源码路径:
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    public ActivityManagerService(Context systemContext) {
        ...
        //构造方法中初始化了mServices 
        mServices = new ActiveServices(this);
        ...
    }   
    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, int userId) {
       ...
       //调用了mServices的startServiceLocked方法
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }

}

7、上面的代码又转到了ActiveServices中的startServiceLocked方法中,继续跟进
源码路径:
/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

    ComponentName startServiceLocked(IApplicationThread caller,
            Intent service, String resolvedType,
            int callingPid, int callingUid, int userId) {
        if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "startService: " + service
                + " type=" + resolvedType + " args=" + service.getExtras());

        final boolean callerFg;
        //这里的caller是调用者所在的ActivityThread中的内部类ApplicationThread,它也是一个Binder对象
        //主要用来和应用进程进行通信
        if (caller != null) {
            final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
            if (callerApp == null) {
                throw new SecurityException(
                        "Unable to find app for caller " + caller
                        + " (pid=" + Binder.getCallingPid()
                        + ") when starting service " + service);
            }
            callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
        } else {
            callerFg = true;
        }

        //retrieveServiceLocked是解析Intent对象,从ActivityManagerService中取这个进程中
        //的ServiceMap,然后从ServiceMap当中看是否存在这个service的ServiceRecord,
        //如果不存在则创建一个ServiceRecord,ServiceRecord是用来记录这个service的各种信息的,
        //包括属于哪个进程,service的名称,应用包名等等,然后将ServiceRecord存入ActivityManagerService
        //的成员变量mServiceMap当中
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType,
                    callingPid, callingUid, userId, true, callerFg);
        if (res == null) {
            return null;
        }
        if (res.record == null) {
            return new ComponentName("!", res.permission != null
                    ? res.permission : "private to package");
        }

        ServiceRecord r = res.record;

        ...

        //接着调用本类的startServiceInnerLocked方法
        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    }

8、上面说到了ServiceRecord,ServiceRecord是用来记录这个service的各种信息的,包括属于哪个进程,service的名称,应用包名等等

    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
            ServiceRecord r, boolean callerFg, boolean addToStarting) {

        ....
        //又转到了bringUpServiceLocked方法
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
        if (error != null) {
            return new ComponentName("!!", error);
        }

        ....

        return r.name;
    }

9、点进去,接着看bringUpServiceLocked方法

    private final String bringUpServiceLocked(ServiceRecord r,
            int intentFlags, boolean execInFg, boolean whileRestarting) {
        ...

        //判断要启动的Service是否已经启动,如果启动只调用onStartCommand方法,下面再分析这个方法  
        if (r.app != null && r.app.thread != null) {
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }

        .....

        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != ;
        final String procName = r.processName;
        ProcessRecord app;

        //判断要启动的这个service是否配置了要在独立进程中启动,之前是否加载过这个进程
        if (!isolated) {

            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
            //之前加载过该进程,不需要再创建
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                    //启动service,一会分析
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
                }

                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
        } else {

            app = r.isolatedProc;
        }

        // Not running -- get it started, and enqueue this service record
        // to be executed when the app comes up.
        if (app == null) {
            //没有加载过这个进程,创建一个新的进程,然后启动service
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {
                String msg = "Unable to launch app "
                        + r.appInfo.packageName + "/"
                        + r.appInfo.uid + " for service "
                        + r.intent.getIntent() + ": process is bad";
                Slog.w(TAG, msg);
                //启动service,一会分析
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }

        //保存这个ServiceRecord
        if (!mPendingServices.contains(r)) {
            mPendingServices.add(r);
        }

        ....

        return null;
    }

10、在即将启动service的时候突然出现了三种情况,我们总结一下

v1:要启动的Service是否已经启动,调用了sendServiceArgsLocked方法

v2:Service没有启动,但是需要启动这个service的进程已经存在,调用了realStartServiceLocked方法

v3:Service没有启动,但是需要启动这个service的进程不存在,调用了bringDownServiceLocked

v1.1、我们先来看如果这个service已经启动的情况,即sendServiceArgsLocked方法:

    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) {

       ....
       //调用了r.app.thread,这个参数其实就是上面说过的ActivitiyThread中的内部类ApplicationThread
       r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);


       ....

    }

v1.2、上面调用了ActivitiyThread中的内部类ApplicationThread的scheduleServiceArgs方法,那么我们就去找这个方法就好了
源码路径:
/frameworks/base/core/java/android/app/ActivityThread.java

    private class ApplicationThread extends ApplicationThreadNative {

        ....

        public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
            int flags ,Intent args) {
            ServiceArgsData s = new ServiceArgsData();
            s.token = token;
            s.taskRemoved = taskRemoved;
            s.startId = startId;
            s.flags = flags;
            s.args = args;
            //这里是要发送一条消息
            sendMessage(H.SERVICE_ARGS, s);
        }

        ....

    }   

    private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1) {
        sendMessage(what, obj, arg1, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2) {
        sendMessage(what, obj, arg1, arg2, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

v1.3、上面所有的发送消息的方法最终都会走到参数最多的那个,然后通过mH发送了一条消息,而mH其实就是一个Handler,也是在ActivityThread当中通过内部类的方式创建的,上面发送的是H.SERVICE_ARGS,我们去找这个对应的常量就好了

    case SERVICE_ARGS:
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
        //调用service的onStartCommand方法
        handleServiceArgs((ServiceArgsData)msg.obj);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        break;

v1.4、在接着看ActivityThread当中的handleServiceArgs方法

    private void handleServiceArgs(ServiceArgsData data) {
        //从map中取出service,因为这里已经启动的service
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess();
                }
                int res;
                if (!data.taskRemoved) {
                    //回调service的onStartCommand方法
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }

                QueuedWork.waitToFinish();

                try {
                    //告诉ActivityManagerService,onStartCommand方法已经回调完毕
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                } catch (RemoteException e) {
                    // nothing to do.
                }
                ensureJitEnabled();
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to start service " + s
                            + " with " + data.args + ": " + e.toString(), e);
                }
            }
        }
    }

v1.5、好了,到这里我们就分析完了启动service时的第一种情况,也就是这个service已经被启动了后再次调用startService方法的流程

v2、1:Service没有启动,但是需要启动这个service的进程已经存在,调用了realStartServiceLocked方法,

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {

        ....

        //启动创建service
        app.thread.scheduleCreateService(r, r.serviceInfo,

        ....

        //绑定service,即
        requestServiceBindingsLocked(r, execInFg);

       ....

        //调用service的onStartCommand方法,上边分析过这个方法了
        sendServiceArgsLocked(r, execInFg, true);

       ....
    }

v2、2上面的几个方法都和第一个分析调用onStartCommand的方式一样,只不过调用的方法不同,下面不再贴代码了,我们看一下最后一种创建进程的那种情况

二、新进程启动过程 :

v3.1、Service没有启动,但是需要启动这个service的进程不存在,调用了bringDownServiceLocked,我们再看一下最会出现三种情况的那个方法,这里我们也只分析创建进程的这一部分,其余的原理和步骤都和上边分析的相同。

    private final String bringUpServiceLocked(ServiceRecord r,
            int intentFlags, boolean execInFg, boolean whileRestarting) {
        ...
        //省略前两种情况了,已经分析过

        if (app == null) {
            //没有加载过这个进程,创建一个新的进程,然后启动service
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {
                String msg = "Unable to launch app "
                        + r.appInfo.packageName + "/"
                        + r.appInfo.uid + " for service "
                        + r.intent.getIntent() + ": process is bad";
                Slog.w(TAG, msg);
                //启动service,一会分析
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }

        //保存这个ServiceRecord
        if (!mPendingServices.contains(r)) {
            mPendingServices.add(r);
        }

        ....

        return null;
    }

v3.2、上面判断如果需要创建进程的话是通过调用mAm.startProcessLocked生成了进程,mAm就是AMS,我们直接看startProcessLocked方法

private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        long startTime = SystemClock.elapsedRealtime();
     .....

        try {
           .....

           //注意看如果entryPoint等于null的话,会被赋值android.app.ActivityThread
            boolean isActivityProcess = (entryPoint == null);
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            checkTime(startTime, "startProcess: asking zygote to start proc");
            //启动进程
            Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);
            checkTime(startTime, "startProcess: returned from zygote!");

            ....

        } catch (RuntimeException e) {
           .....
        }
    }

v3.3、指定了ActivityThread的这个类后,在创建进程完成后会调用ActivityThread的main方法,生成进程的代码在Process.java中,想去深入了解的自行查阅,我们再去看ActivityThread
源码路径:
/frameworks/base/core/java/android/app/ActivityThread.java


public final class ActivityThread {

    ....
    //直接创建了一个ApplicationThread类型的mAppThread成员变量
    final ApplicationThread mAppThread = new ApplicationThread();

    ....
    //main方法
    public static void main(String[] args) {
        SamplingProfilerIntegration.start();

     ....

        //创建Looper
        Looper.prepareMainLooper();

        //创建自己的实例
        ActivityThread thread = new ActivityThread();

        //准备和AMS绑定
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        //开启Looper循环
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

    //这里和AMS绑定,system代表是否为系统进程
     private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
           ....
                       RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                //和AMS绑定
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
            ....            
        } 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);
            }
        }

        // add dropbox logging to libcore
        DropBox.setReporter(new DropBoxReporter());

        //ViewRootImpl添加onConfigurationChanged 、 onLowMemory 、 onTrimMemory等方法回调
        ViewRootImpl.addConfigCallback(new ComponentCallbacks() {
            @Override
            public void onConfigurationChanged(Configuration newConfig) {
                synchronized (mResourcesManager) {
                    // We need to apply this change to the resources
                    // immediately, because upon returning the view
                    // hierarchy will be informed about it.
                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
                        // This actually changed the resources!  Tell
                        // everyone about it.
                        if (mPendingConfiguration == null ||
                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {
                            mPendingConfiguration = newConfig;

                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);
                        }
                    }
                }
            }
            @Override
            public void onLowMemory() {
            }
            @Override
            public void onTrimMemory(int level) {
            }
        });
    }
}   

v3.4、这里调用了ActivityManagerNative.getDefault()的attachApplication方法,我们上面分析过ActivityManagerNative.getDefault()返回的是AMS的代理里,那么我们直接去看AMS中的attachApplication方法
源码路径:
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            //调用了本类的attachApplicationLocked方法
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }

v3.5、再看一下attachApplicationLocked

    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

        .....

            ApplicationInfo appInfo = app.instrumentationInfo != null
                    ? app.instrumentationInfo : app.info;
            app.compat = compatibilityInfoForPackageLocked(appInfo);
            if (profileFd != null) {
                profileFd = profileFd.dup();
            }
            ProfilerInfo profilerInfo = profileFile == null ? null
                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);

                    //调用了传进来的ActivityThread的内部类ApplicationThread的bindApplication方法

            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
            updateLruProcessLocked(app, false, null);
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {

            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);

            app.resetPackageList(mProcessStats);
            app.unlinkDeathRecipient();
            startProcessLocked(app, "bind fail", processName);
            return false;
        }

      ......
            //上面创建Application后再进一步操作Serivice,一会反回来分析
             if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }
        return true;
    }

v3.6、attachApplicationLocked的代码非常的多,我们只看相关代码
,这里调用了刚刚传进来的ActivityThread内部类ApplicationThread的
bindApplication方法,我们再返回ActivityThread中看
源码路径:
/frameworks/base/core/java/android/app/ActivityThread.java

    public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
                Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
                Bundle 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.enableOpenGlTrace = enableOpenGlTrace;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            //发送消息到Handler中
            sendMessage(H.BIND_APPLICATION, data);
        }

v3.7、我们上面也分析过消息会发送到ActivityThread中的内部类Handler中,我们找一个这个常量指定的处理

   case BIND_APPLICATION:
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
        //拿到刚才创建的绑定数据
        AppBindData data = (AppBindData)msg.obj;
        //调用了handleBindApplication方法
        handleBindApplication(data);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        break;

v3.8、我们再去看一下handleBindApplication

 private void handleBindApplication(AppBindData data) {

        ....

    //创建上下文对象
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);

        ....

        //准备初始化的数据
        if (data.instrumentationName != null) {
            InstrumentationInfo ii = null;
            try {
                ii = appContext.getPackageManager().
                    getInstrumentationInfo(data.instrumentationName, );
            } catch (PackageManager.NameNotFoundException e) {
            }
            if (ii == null) {
                throw new RuntimeException(
                    "Unable to find instrumentation info for: "
                    + data.instrumentationName);
            }

            mInstrumentationPackageName = ii.packageName;
            mInstrumentationAppDir = ii.sourceDir;
            mInstrumentationSplitAppDirs = ii.splitSourceDirs;
            mInstrumentationLibDir = ii.nativeLibraryDir;
            mInstrumentedAppDir = data.info.getAppDir();
            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
            mInstrumentedLibDir = data.info.getLibDir();

            //准备创建Application的数据
            ApplicationInfo instrApp = new ApplicationInfo();
            instrApp.packageName = ii.packageName;
            instrApp.sourceDir = ii.sourceDir;
            instrApp.publicSourceDir = ii.publicSourceDir;
            instrApp.splitSourceDirs = ii.splitSourceDirs;
            instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
            instrApp.dataDir = ii.dataDir;
            instrApp.nativeLibraryDir = ii.nativeLibraryDir;
            //LoadedApk对象是APK文件在内存中的表示。 //Apk文件的相关信息,诸如Apk文件的代码和资源,甚至代码里面的Activity,Service等四大组件的信息我们都可以通过此对象获取

            LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                    appContext.getClassLoader(), false, true, false);

            //创建新进程的Context
            ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

            try {

            //创建Instrumentation对象
                java.lang.ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {
                throw new RuntimeException(
                    "Unable to instantiate instrumentation "
                    + data.instrumentationName + ": " + e.toString(), e);
            }
            //初始化Instrumentation
            mInstrumentation.init(this, instrContext, appContext,
                   new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
                   data.instrumentationUiAutomationConnection);

        ....

        } else {
            mInstrumentation = new Instrumentation();
        }

       ....

        try {

          //通过创建Application并回调Application的attach方法
          Application app = data.info.makeApplication(data.restrictedBackupMode, null);
          mInitialApplication = app;
           ....

            try {
                //回调Application的OnCreate方法
                mInstrumentation.callApplicationOnCreate(app);
            } 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);
        }
    }

v3.9、这里不要蒙啊,这里是创建了新的进程,所以应该也就知道了每个进程都会创建一个Application对象,到这里新进程的创建就完了,我们总结一下

总结进程启动:新进程通过调用Process.start的方法启动一个进程,然后因为指定了android.app.ActivityThread的这个类,所以在创建进程之后会调用android.app.ActivityThread类中的main方法,在main方法中会开启消息循环,然后创建了一个ActivityThread实例,调用attach方法,在attach方法中,通过AMS.attachApplication方法,将ActivityThread当中的内部类ApplicationThread和AMS绑定,之后这个进程的所有通信全部都是靠ApplicationThread和AMS和ActivityThread中的Handler来进行,希望本能能对大家有所帮助,从一个启动的过程可以窥视Android的通信机制及运行原理。

好了,我们在返回到v3.5中AMS中的attachApplicationLocked方法,我们在贴一下代码

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

        .....

            ApplicationInfo appInfo = app.instrumentationInfo != null
                    ? app.instrumentationInfo : app.info;
            app.compat = compatibilityInfoForPackageLocked(appInfo);
            if (profileFd != null) {
                profileFd = profileFd.dup();
            }
            ProfilerInfo profilerInfo = profileFile == null ? null
                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);

                    //调用了传进来的ActivityThread的内部类ApplicationThread的bindApplication方法

            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
            updateLruProcessLocked(app, false, null);
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {

            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);

            app.resetPackageList(mProcessStats);
            app.unlinkDeathRecipient();
            startProcessLocked(app, "bind fail", processName);
            return false;
        }

      ......
            //上面创建Application后再进一步操作Serivice,一会反回来分析
             if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }
        return true;
    }

在上面我们都已经分析了bindApplication方法,也就是创建Application对象回调相应生命周期等,然后代码接着往下走到mServices.attachApplicationLocked,mServices就是上面分析过的ActiveServices,所有启动service的操作都在这个类里,我们进去看看这个方法。
源码路径:
/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

boolean attachApplicationLocked(ProcessRecord proc, String processName)
            throws RemoteException {
        boolean didSomething = false;
        // Collect any services that are waiting for this process to come up.
        if (mPendingServices.size() > ) {
            ServiceRecord sr = null;
            try {
                for (int i=; i<mPendingServices.size(); i++) {
                    sr = mPendingServices.get(i);
                    if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                            || !processName.equals(sr.processName))) {
                        continue;
                    }

                    mPendingServices.remove(i);
                    i--;
                    proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
                            mAm.mProcessStats);
                            //又调用了上面分析过的方法,这个方法曾经在出现三种情况的方法里出现过,当
                            //时是第二种情况:如果service没有启动,但是service所在进程已经启动会调用这个方法
                    realStartServiceLocked(sr, proc, sr.createdFromFg);
                    didSomething = true;
                }
            } catch (RemoteException e) {

                throw e;
            }
        }

        ....
        return didSomething;
    }

这个方法又调用了当时在第9步中的第二种情况的方法,就是service没有启动,但是service所在进程已经存在的情况,当时我们这个方法没有具体分析,现在我们再去看看
源码路径:
/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {

        ....

        //启动创建service
        app.thread.scheduleCreateService(r, r.serviceInfo,

        ....

        //绑定service,
        requestServiceBindingsLocked(r, execInFg);

       ....

        //调用service的onStartCommand方法,上边分析过这个方法了
        sendServiceArgsLocked(r, execInFg, true);

       ....
    }

这里我们继续分析service创建的过程,其他的步骤都是一个原理,创建service调用了ActivityThread中的scheduleCreateService
源码路径:

        public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;
            //发消息到Handler
            sendMessage(H.CREATE_SERVICE, s);
        }

到Handler中找到常量CREATE_SERVICE对应的处理

                case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
 //调用    handleCreateService               handleCreateService((CreateServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

再看一下handleCreateService方法

 private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        //LoadedApk是LoadedApk对象是APK文件在内存中的表示。
        //Apk文件的相关信息,诸如Apk文件的代码和资源,
        //甚至代码里面的Activity,Service等四大组件的信息我们都可以通过此对象获取。
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            //加载service类
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {

            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
            //判断Application是否创建,没有创建会创建Application对象,
            //但是在上面创建进程的时候已经创建,所以会直接返回
            Application app = packageInfo.makeApplication(false, mInstrumentation);

            //初始化service
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());

            //调用service的    onCreate方法
            service.onCreate();

            //存储service的信息
            mServices.put(data.token, service);
            try {
                //通知AMS已经创建完毕
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                // nothing to do.
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }

handleCreateService方法主要是加载Service类,初始化Service,调用Service的onCreate方法,保存Service信息,方便下次使用。这个方法结束后Service就启动起来,realStartServiceLocked中的方法会继续向下走,但是几乎都是这个逻辑,通过ApplicationThread发送消息到ActivityThread的Handler中处理,处理后通过AMS在通知ActivityThread中的处理完毕等。

下面我们总结一下:
1。首先startService方法在ContextWrapper中,ContextWrapper又调用了Context中的startService,Context的实现类是ContextImpl

2。在ContextImpl在构造方法中创建了一个叫ActiveServices的类,在ContextImpl的startService方法中调用了ActiveServices中的startServiceLocked,后续到了ActiveServices的bringUpServiceLocked方法中出现了三种情况

2.1 service已经启动,直接通过ActivityThread发送消息到Handler中调用startCommand方法

2.2 Service没有启动,但是service所属进程已经创建,调用realStartServiceLocked方法。发送消息到Handler中,加载Service类,初始化Service,调用Service的onCreate方法,保存Service信息,然后realStartServiceLocked方法将继续执行绑定,调用startCommand的方法,逻辑和启动一样类似

2.3 Service没有启动,而且Service所属进程也没有创建,这时会通过AMS的startProcessLocked方法中通过Process.start方法创建一个新的进程,然后调用新进程的ActivityThread的main方法,在main方法中将绑定AMS,在AMS的bindApplicationLocked中新创建Application后调用了ActiveServices.attachApplicationLocked方法,然后调用了realStartServiceLocked方法相应的创建Service,绑定Service,调用startCommand方法。

OK,到这里就分析完了,后续会有其他组件源码分析,敬请期待

猜你喜欢

转载自blog.csdn.net/yulong0809/article/details/77772683