Android 中 startService()启动service的过程分析

通过分析点击android桌面app图标启动应用程序的过程这篇文章,我们了解启动activity的过程,再来分析启动android的另一个组件service的过程就比较容易了.因为流程差不多.

现在假设应用程序有一个activity和一个service,然后在activity中通过startService()启动service,清单文件中service的process属性没有设置.也就是activity和service在一个进程中.

startService()这个方法是Activty的父类ContextWrapper中的.

frameworks/base/core/java/android/content/ContextWrapper.java

 public ComponentName startService(Intent service) {
        return mBase.startService(service);
    }
这里mBase变量是ContextImpl类型,是在创建activity的时候,new 一个 ContextImpl对象,赋值给activity的.

frameworks/base/core/java/android/app/ActivityThread.java

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
   .....
            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);//创建contextImpl
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
          .....
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config);//传进去

             .....
        return activity;
    }

好了继续:

第一步:frameworks/base/core/java/android/app/ContextImpl.java

  public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceAsUser(service, mUser);
    }

    @Override
    public ComponentName startServiceAsUser(Intent service, UserHandle user) {
        try {
            service.setAllowFds(false);
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
           ....
            return cn;
        } catch (RemoteException e) {
            return null;
        }
    }

这里通过Binder通信,调用到ActivityManagerService的启动service方法.

mMainThread.getApplicationThread()是ApplicationThread类型的mAppThread对象,ApplicationThread其实是Binder类型.是用来和ActivityManagerService进程间通信的,它是在ActivityThread类中创建的.

service.resolveTypeIfNeeded(getContentResolver())获取这个intent的MIME类型,这里假设没有设置MIME类型  即AndroidManifest.xml没有设置Service的MIME类型,所以这里返回null.

第二步:

frameworks/base/core/java/android/app/ActivityManagerNative.java

 public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, int userId) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        service.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeInt(userId);
        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        ComponentName res = ComponentName.readFromParcel(reply);
        data.recycle();
        reply.recycle();
        return res;
    }

通过Binder驱动

 case START_SERVICE_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            Intent service = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            int userId = data.readInt();
            ComponentName cn = startService(app, service, resolvedType, userId);
            reply.writeNoException();
            ComponentName.writeToParcel(cn, reply);
            return true;
        }

上面就调用到了 ActivityManagerService中.

第三步:startService().

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java.

 public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, int userId) {
      .....
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            checkValidCaller(callingUid, userId);
            final long origId = Binder.clearCallingIdentity();
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }

第四步: startServiceLocked().

frameworks/base/services/java/com/android/server/am/ActiveServices.java

ComponentName startServiceLocked(IApplicationThread caller,
            Intent service, String resolvedType,
            int callingPid, int callingUid, int userId) {
    ....
        if (caller != null) {
            final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
            if (callerApp == null) {
           .....
            }
        }

        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType,
                    callingPid, callingUid, userId, true);
        if (res == null) {
           ...
        }
        if (res.record == null) {
          ...
        }
        ServiceRecord r = res.record;
    ......
        String error = bringUpServiceLocked(r, service.getFlags(), false);
  ....
        return r.name;
    }
 函数首先通过retrieveServiceLocked来解析service这个Intent,就是解析我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中.
第五步: bringUpServiceLocked().ActiveServices.java中

private final String bringUpServiceLocked(ServiceRecord r,
            int intentFlags, boolean whileRestarting) {
       ....
        if (r.app != null && r.app.thread != null) {
       ...
        }
.....
        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
        final String procName = r.processName;
        ProcessRecord app;

        if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid);//这里获取不为空,因为该service所在的进程已经启动起来了
           ....
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName);
                    realStartServiceLocked(r, app);
                    return null;
                } catch (RemoteException e) {
                  ...
                }
.....
            }
        } else {
      ...
        }

      ....
        return null;
    }
这里service所在的进程已经启动起来了,所以接下来直接在这个进程中启动service.

第六步:realStartServiceLocked().ActiveServices.java中

private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app) throws RemoteException {
     ...
        try {
        ....
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));//去创建service
            r.postNotification();
            created = true;
        } finally {
          ...
        }
.....
        sendServiceArgsLocked(r, true);
    }
首先看scheduleCreateService方法,
第七步: scheduleCreateService().

frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中,这里又是Binder进程间通信了.

  public final void scheduleCreateService(IBinder token, ServiceInfo info,
            CompatibilityInfo compatInfo) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeStrongBinder(token);
        info.writeToParcel(data, 0);
        compatInfo.writeToParcel(data, 0);
        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }

经过Binder驱动

 case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
            data.enforceInterface(IApplicationThread.descriptor);
            IBinder token = data.readStrongBinder();
            ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
            scheduleCreateService(token, info, compatInfo);
            return true;
        }

这样就调用到了应用程序中了

第八步:scheduleCreateService().

在frameworks/base/core/java/android/app/ActivityThread.java中

 public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo) {
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;

            queueOrSendMessage(H.CREATE_SERVICE, s);
        }

第九步:queueOrSendMessage().

在frameworks/base/core/java/android/app/ActivityThread.java中

 private void queueOrSendMessage(int what, Object obj) {
        queueOrSendMessage(what, obj, 0, 0);
    }
    private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
        synchronized (this) {
            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;
            mH.sendMessage(msg);
        }
    }

第十步:handleCreateService().

在frameworks/base/core/java/android/app/ActivityThread.java中

case CREATE_SERVICE:
                  ...
                    handleCreateService((CreateServiceData)msg.obj);
                  ...
                    break;
private void handleCreateService(CreateServiceData data) {
    ...
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();//创建一个service实例
        } catch (Exception e) {
          ...
        }

        try {
         ...
            ContextImpl context = new ContextImpl();
            context.init(packageInfo, null, this);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            context.setOuterContext(service);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
            service.onCreate();//回调service的onCreat()方法
            mServices.put(data.token, service);
            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, 0, 0, 0);
            } catch (RemoteException e) {
                // nothing to do.
            }
        } catch (Exception e) {
           ...
        }
    }

service.onCreate()这个方法最终会回调service的oncreate()方法,这个大家应该熟悉.这里service就创建起来了

接下来回到第六步,另外一个方法sendServiceArgsLocked();

第十一步:sendServiceArgsLocked().

frameworks/base/services/java/com/android/server/am/ActiveServices.java

private final void sendServiceArgsLocked(ServiceRecord r,
            boolean oomAdjusted) {
       .....
                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
        ....
    }

这里通过Binder通信到应用程序中去了,

这里我就省略中间的几步了,和第七步类似.

第十二步:sendServiceArgsLocked().

在frameworks/base/core/java/android/app/ActivityThread.java中

 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;

            queueOrSendMessage(H.SERVICE_ARGS, s);
        }

这里省略中间消息发送的几个步骤,和第九步类似.

第十三步:handleServiceArgs().

在frameworks/base/core/java/android/app/ActivityThread.java中

 private void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
             ...
                if (!data.taskRemoved) {
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
          .....
    }
s.onStartCommand()这个方法会先回调service的onStart()方法,这样onStart()和onStartCommand()就被相继调用了,这两个回调大家应该也熟悉吧.

这就是启动service的过程的了.







你可能感兴趣的:(startService)