通过分析点击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的过程的了.







更多相关文章

  1. Android视图绘制流程解析(二)
  2. Android(安卓)MediaPlayer和VideoView的使用
  3. Android退出整个应用的方法
  4. Android(安卓)ADB超简单的安装教程(推荐)
  5. Android闪屏页动画不起作用的解决方法
  6. 子控件相对于父控件规则显示且不被拉伸的方法
  7. Android中解析xml的几种方式
  8. kotlin开发Android入门篇一
  9. Android学习杂记(二):异步任务AsyncTask详解

随机推荐

  1. [图解]Android(安卓)View的事件分发机制
  2. Android(安卓)APP存活检测方式
  3. Android点9图的运用
  4. Android混淆从入门到精通
  5. Android白盒测试情况
  6. Android(安卓)7.0动态权限大总结
  7. android-屏幕适配(一)
  8. 传智播客揭秘Android(安卓)6.0之Direct S
  9. 从Android(安卓)L默认ART虚拟机看国内手
  10. 将Android(安卓)Studio的设置恢复到初始