在Activity中使用startService启动Service时,会调用ContextWrapper的startService方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/content/ContextWrapper.java@Overridepublic ComponentName startService(Intent service) {    return mBase.startService(service);}

这个方法的mBase就是一个ContextImpl类型的对象。所以这里调用了ContextImpl类的startService方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ContextImpl.java@Overridepublic ComponentName startService(Intent service) {    warnIfCallingFromSystemProcess();    //注意传入的第二个参数是 false ,表示启动的服务不是前台服务    return startServiceCommon(service, false, mUser);}private ComponentName startServiceCommon(Intent service, boolean requireForeground,        UserHandle user) {    try {    //  Android 5.0后强制要求Service必须通过显式Intent启动5,否则会直接抛出异常        validateServiceIntent(service);        service.prepareToLeaveProcess(this);//关键代码        ComponentName cn = ActivityManager.getService().startService(            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(                        getContentResolver()), requireForeground,                        getOpPackageName(), user.getIdentifier());        // ...        return cn;    } catch (RemoteException e) {        throw e.rethrowFromSystemServer();    }}

这个方法内部通过先调用validateServiceIntent方法进行Intent检查,Android 5.0后强制要求Service必须通过显式Intent启动5,否则会直接抛出异常,接着调用 ActivityManager.getService()获取到了ActivityManagerService(后面简称AMS)在app进程的代理对象,并调用了这个代理对象的startService方法,下面看看AMS中的startService方法的具体实现:

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java@Overridepublic ComponentName startService(IApplicationThread caller, Intent service,        String resolvedType, boolean requireForeground, String callingPackage, int userId)        throws TransactionTooLargeException {    enforceNotIsolatedCaller("startService");    // ...    synchronized(this) {        // ...        ComponentName res;        try {    // 关键代码            res = mServices.startServiceLocked(caller, service,                    resolvedType, callingPid, callingUid,                    requireForeground, callingPackage, userId);        } finally {            Binder.restoreCallingIdentity(origId);        }        return res;    }}

这个方法内部通过mServices.startServiceLocked方法,mServices是ActiveServices类型的,所以调用了ActiveServices类的startServiceLocked方法,下面看看这个方法具体实现:

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.javaComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,        int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)        throws TransactionTooLargeException {    // ...    // 关键代码    ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);    return cmp;}ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,        boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {    // ...    //关键代码    String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);    // ...    return r.name;}private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,        boolean whileRestarting, boolean permissionsReviewRequired)        throws TransactionTooLargeException {       //...    if (app == null && !permissionsReviewRequired) {    // 关键代码        if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,                hostingType, 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";            bringDownServiceLocked(r);            return msg;        }// ...    }    // ...    return null;}

这个方法中的mAm.startProcessLocked(),mAm这个变量是AMS,代码跳转到AMS类中执行,下面看看这个方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java@GuardedBy("this")final ProcessRecord startProcessLocked(String processName,        ApplicationInfo info, boolean knownToBeDead, int intentFlags,        String hostingType, ComponentName hostingName, boolean allowWhileBooting,        boolean isolated, boolean keepIfLarge) {    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,            null /* crashHandler */);}

接着调用了startProcessLocked的几个重载方法后,最终调用了startProcess方法,startProcess方法内部会调用Process类的start方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/Process.javapublic static final ProcessStartResult start(final String processClass,                              final String niceName,                              int uid, int gid, int[] gids,                              int runtimeFlags, int mountExternal,                              int targetSdkVersion,                              String seInfo,                              String abi,                              String instructionSet,                              String appDataDir,                              String invokeWith,                              String[] zygoteArgs) {    return zygoteProcess.start(processClass, niceName, uid, gid, gids,                runtimeFlags, mountExternal, targetSdkVersion, seInfo,                abi, instructionSet, appDataDir, invokeWith, zygoteArgs);}

这个方法内部又调用了ZygoteProcess类的start方法。这个过程是SystemServer进程和ZygoteProcess进程进行通信的过程,它们之间通信是通过Socket进行通信的。

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/ZygoteProcess.javapublic final Process.ProcessStartResult start(final String processClass,                                              final String niceName,                                              int uid, int gid, int[] gids,                                              int runtimeFlags, int mountExternal,                                              int targetSdkVersion,                                              String seInfo,                                              String abi,                                              String instructionSet,                                              String appDataDir,                                              String invokeWith,                                              String[] zygoteArgs) {    try {        return startViaZygote(processClass, niceName, uid, gid, gids,                runtimeFlags, mountExternal, targetSdkVersion, seInfo,                abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,                zygoteArgs);    } catch (ZygoteStartFailedEx ex) {        Log.e(LOG_TAG,                "Starting VM process through Zygote failed");        throw new RuntimeException(                "Starting VM process through Zygote failed", ex);    }}private Process.ProcessStartResult startViaZygote(final String processClass,                                                  final String niceName,                                                  final int uid, final int gid,                                                  final int[] gids,                                                  int runtimeFlags, int mountExternal,                                                  int targetSdkVersion,                                                  String seInfo,                                                  String abi,                                                  String instructionSet,                                                  String appDataDir,                                                  String invokeWith,                                                  boolean startChildZygote,                                                  String[] extraArgs)                                                  throws ZygoteStartFailedEx {    ArrayList argsForZygote = new ArrayList();    // ...    synchronized(mLock) {    //关键代码        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);    }}

zygoteSendArgsAndGetResult方法创建一个App进程。至此,app进程总算创建完成。接着会执行app进程的ActivityThread的main方法。这个main方法是app进程的入口。下面看看ActivityThread类的main方法。

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityThread.javapublic static void main(String[] args) {    // ...    Process.setArgV0("");    Looper.prepareMainLooper();    // ...    ActivityThread thread = new ActivityThread();    thread.attach(false, startSeq);    if (sMainThreadHandler == null) {        sMainThreadHandler = thread.getHandler();    }   // ...    Looper.loop();    throw new RuntimeException("Main thread loop unexpectedly exited");}

这个方法内部, 主要是准备一个Looper对象,并准备一个消息列表,用于存在主线程的handler发送的消息。并创建一个ActivityThread对象。并调用attach方法,并且,如果sMainThreadHandler为null,给sMainThreadHandler赋值,
并且调用Looper.loop方法循环到从消息队列中抽取消息。下面来看看attach方法的具体实现:

private void attach(boolean system, long startSeq) {    sCurrentActivityThread = this;    mSystemThread = system;    if (!system) {        // ...        final IActivityManager mgr = ActivityManager.getService();        try {            mgr.attachApplication(mAppThread, startSeq);        }         // ...    } else {        // ...    }    // ...}

这个方法中,获取了ActivityManagerServcie在app客户端的代理对象,调用代理对象的attachApplication方法,这时,app进程挂起,SystemServer进程的AMS类的attachApplication方法执行。

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java@Overridepublic final void attachApplication(IApplicationThread thread, long startSeq) {    synchronized (this) {        // ...    //关键代码        attachApplicationLocked(thread, callingPid, callingUid, startSeq);        Binder.restoreCallingIdentity(origId);    }}@GuardedBy("this")private final boolean attachApplicationLocked(IApplicationThread thread,        int pid, int callingUid, long startSeq) {// ...    try { // ...        if (app.isolatedEntryPoint != null) {            thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);        } else if (app.instr != null) {            thread.bindApplication(processName, appInfo, providers,                    app.instr.mClass,                    profilerInfo, app.instr.mArguments,                    app.instr.mWatcher,                    app.instr.mUiAutomationConnection, testMode,                    mBinderTransactionTrackingEnabled, enableTrackAllocation,                    isRestrictedBackupMode || !normalMode, app.persistent,                    new Configuration(getGlobalConfiguration()), app.compat,                    getCommonServicesLocked(app.isolated),                    mCoreSettingsObserver.getCoreSettingsLocked(),                    buildSerial, isAutofillCompatEnabled);        } else {            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);        }        // ...    }// ...        // 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;            }        }    // ...    return true;}

attachApplication方法内部,又继续调用了attachApplicationLocked方法,attachApplicationLocked方法内部,通过IApplicationThread的bindApplication方法,IApplicationThread内部的bindApplication方法内,通过sendMessage(H.BIND_APPLICATION, data),这样ActivityThread内的内部类H,它是继承了Handler的,这样H类的handleMessage方法中的代码执行,这样handleBindApplication()方法就执行了,handleBindApplication()方法主要
做了三件事:
1.创建Instrumentation对象;
2.调用LoadedApk类的makeApplication方法创建Application对象
3.调用Instrumentation对象的callApplicationOnCreate方法
经过上面三个步骤,Application就创建了,并且它的OnCreate方法也执行了。

继续看AMS类的attachApplicationLocked方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java@GuardedBy("this")private final boolean attachApplicationLocked(IApplicationThread thread,        int pid, int callingUid, long startSeq) {// ...    try { // ...        if (app.isolatedEntryPoint != null) {            thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);        } else if (app.instr != null) {            thread.bindApplication(processName, appInfo, providers,                    app.instr.mClass,                    profilerInfo, app.instr.mArguments,                    app.instr.mWatcher,                    app.instr.mUiAutomationConnection, testMode,                    mBinderTransactionTrackingEnabled, enableTrackAllocation,                    isRestrictedBackupMode || !normalMode, app.persistent,                    new Configuration(getGlobalConfiguration()), app.compat,                    getCommonServicesLocked(app.isolated),                    mCoreSettingsObserver.getCoreSettingsLocked(),                    buildSerial, isAutofillCompatEnabled);        } else {            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);        }        // ...    }// ...        // 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;            }        }    // ...    return true;}

这个方法内部,还会继续执行mServices.attachApplicationLocked(app, processName);
mServices是ActiveServices类型的,所以跳转到ActivieServices类中执行

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.javaboolean 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() > 0) {        ServiceRecord sr = null;        try {            for (int i=0; i

这个方法中的app.thread对象就是ApplicationThread类型的对象,所以跳转到 ApplicationThread类的scheduleCreateService方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityThread.javapublic final void scheduleCreateService(IBinder token,        ServiceInfo info, CompatibilityInfo compatInfo, int processState) {    updateProcessState(processState, false);    // ...    // 关键代码    sendMessage(H.CREATE_SERVICE, s);}public void handleMessage(Message msg) {// ...        case CREATE_SERVICE:            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));            handleCreateService((CreateServiceData)msg.obj);            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);// ...}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 packageInfo = getPackageInfoNoCheck(                data.info.applicationInfo, data.compatInfo);        Service service = null;        try {            java.lang.ClassLoader cl = packageInfo.getClassLoader();            service = packageInfo.getAppFactory()                    .instantiateService(cl, data.info.name, data.intent);        } 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 app = packageInfo.makeApplication(false, mInstrumentation);            service.attach(context, this, data.info.name, data.token, app,                    ActivityManager.getService());            service.onCreate();            mServices.put(data.token, service);            try {                ActivityManager.getService().serviceDoneExecuting(                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);            } catch (RemoteException e) {                throw e.rethrowFromSystemServer();            }        } catch (Exception e) {            if (!mInstrumentation.onException(service, e)) {                throw new RuntimeException(                    "Unable to create service " + data.info.name                    + ": " + e.toString(), e);            }        }}

scheduleCreateService方法内部最终会调用到handleCreateService方法,
handleCreateService方法内部主要做了如下事情:
1.通过类加载方式创建Service的实例对象
2.调用LoadedApk的makeApplication方法创建Application对象,由于在前面的步骤中已经创建了
Application对象,所在这个方法中,就直接返回之前创建的Application对象。
3.调动Service的attach方法,attach方法内部,主要是调用attachBaseContext,将ContextImpl对象赋值给Service父类的mBase对象。`

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/Service.javapublic final void attach(        Context context,        ActivityThread thread, String className, IBinder token,        Application application, Object activityManager) {    //关键代码    attachBaseContext(context);    // ...}

4.调用Servcie的onCreate方法,这样Service的OnCreate方法就执行了
至此,Servcie创建了并且调用了OnCreate方法,下面继续看看ActiveServices类的realStartServiceLocked方法中的sendServiceArgsLocked方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.javaprivate final void realStartServiceLocked(ServiceRecord r,        ProcessRecord app, boolean execInFg) throws RemoteException {// ...    boolean created = false;    try {        // ...//关键代码        app.thread.scheduleCreateService(r, r.serviceInfo,                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),                app.repProcState);        r.postNotification();        created = true;    }     // ...    // 关键代码    sendServiceArgsLocked(r, execInFg, true);    // ...}private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,        boolean oomAdjusted) throws TransactionTooLargeException {    // ...    try {        r.app.thread.scheduleServiceArgs(r, slice);    }     // ...}

sendServiceArgsLocked方法中的r.app.thread其实就是IApplicationThread类型的对象,所以最终会执行
ApplicationThread类中的scheduleServiceArgs方法,下面来看这个方法具体实现:

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityThread.javapublic final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {    List list = args.getList();    for (int i = 0; i < list.size(); i++) {        //...// 关键代码        sendMessage(H.SERVICE_ARGS, s);    }}public void handleMessage(Message msg) {    case SERVICE_ARGS:        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));        handleServiceArgs((ServiceArgsData)msg.obj);        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);        break;}private void handleServiceArgs(ServiceArgsData data) {   Service s = mServices.get(data.token);   if (s != null) {       try {           // ...           int res;           if (!data.taskRemoved) {   // 关键代码               res = s.onStartCommand(data.args, data.flags, data.startId);           } else {               s.onTaskRemoved(data.args);               res = Service.START_TASK_REMOVED_COMPLETE;           }           // ...       }        // ...   }}

handleServiceArgs方法中,执行了Servcie的onStartCommand方法,至此,Service的onStartCommand方法得到执行。

以上便是startServcie启动Servcie的过程分析。

更多相关文章

  1. Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.
  2. Android两种播放视频的方法(SurfaceView、MediaPlayer、SeekBar)
  3. Android 解屏代码
  4. android去掉标题的方法
  5. Android 4.0 HttpUrlConnection的getInputStream()方法总是返回
  6. eclipse中安装android ADT插件及无法下载ADT解决方法
  7. android 实现代码关机
  8. Android BaseWebLoad组件使用及与js方法互调
  9. [置顶] Android Studio Eclipse运行时出现 finished with non-ze

随机推荐

  1. Android内存泄漏检查利器——LeakCanary
  2. [Skill]Android版本兼容器
  3. 基于 Android(安卓)NDK 的学习之旅-----
  4. 最强理解:Android对EditText输入时设置监
  5. Android实现仿QQ登录可编辑下拉菜单
  6. Android画布canvas rotate,translate的理
  7. Android(安卓)Broadcast Receiver 基础详
  8. 第27章、流动视图ScrollView(从零开始学An
  9. Android中线程同步
  10. Android核心分析 分析方法论探讨之设计意