在Activity中使用bindService绑定Service时,会调用ContextWrapper的bindService方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/content/ContextWrapper.java@Overridepublic boolean bindService(Intent service, ServiceConnection conn,        int flags) {    return mBase.bindService(service, conn, flags);}

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

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ContextImpl.java@Overridepublic boolean bindService(Intent service, ServiceConnection conn,        int flags) {    warnIfCallingFromSystemProcess();    return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser());}private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler        handler, UserHandle user) {    IServiceConnection sd;    if (conn == null) {        throw new IllegalArgumentException("connection is null");    }    if (mPackageInfo != null) {        // 关键代码        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);    } else {        throw new RuntimeException("Not supported in system context");    }    validateServiceIntent(service);    try {        // ...// 关键代码        int res = ActivityManager.getService().bindService(            mMainThread.getApplicationThread(), getActivityToken(), service,            service.resolveTypeIfNeeded(getContentResolver()),            sd, flags, getOpPackageName(), user.getIdentifier());        // ...    }    // ...}

在bindServiceCommon方法中,先调用LoadedApk类型的变量mPackageInfo.getServiceDispatcher方法,获取一个IServiceConnection类型的对象sd,下面看看LoadedApk类中的这个方法的具体实现:

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/LoadedApk.javapublic final IServiceConnection getServiceDispatcher(ServiceConnection c,        Context context, Handler handler, int flags) {    synchronized (mServices) {        LoadedApk.ServiceDispatcher sd = null;        ArrayMap map = mServices.get(context);        if (map != null) {            if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);            sd = map.get(c);        }        if (sd == null) {    // 关键代码            sd = new ServiceDispatcher(c, context, handler, flags);                        if (map == null) {                map = new ArrayMap<>();                mServices.put(context, map);            }            map.put(c, sd);        } else {            sd.validate(context, handler);        }// 关键代码        return sd.getIServiceConnection();    }}ServiceDispatcher(ServiceConnection conn,        Context context, Handler activityThread, int flags) {    // 关键代码    mIServiceConnection = new InnerConnection(this);    // ...}private static class InnerConnection extends IServiceConnection.Stub {// ...}

从LoadedApk类的getServiceDispatcher方法内部的逻辑主要是创建其内部类ServiceDispatcher对象,在ServiceDispatcher对象的创建过程中,又创建了ServiceDispatcher的静态内部类InnerConnection的实例。InnerConnection其实是继承IServiceConnection.Stub,所以它是一个Binder。在getServiceDispatcher方法的最后一行,通过sd.getIServiceConnection();返回的就是InnerConnection这类的实例。继续看ContextImpl类的bindServiceCommon方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ContextImpl.javaprivate boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler        handler, UserHandle user) {    IServiceConnection sd;    if (conn == null) {        throw new IllegalArgumentException("connection is null");    }    if (mPackageInfo != null) {        // 关键代码        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);    } else {        throw new RuntimeException("Not supported in system context");    }    validateServiceIntent(service);    try {        // ...// 关键代码        int res = ActivityManager.getService().bindService(            mMainThread.getApplicationThread(), getActivityToken(), service,            service.resolveTypeIfNeeded(getContentResolver()),            sd, flags, getOpPackageName(), user.getIdentifier());        // ...    }    // ...}

这个方法内部,通过ActivityManager.getService()获取到system_servier进程中的ActivityManagerService(后面简称AMS)在app进程中的代理对象,然后调用代理对象的bindService方法,并将前面获取的InnerConnection这个Binder对象作为参数传入,
这个过程就是进程间通信,下面看看AMS中的bindService方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javapublic int bindService(IApplicationThread caller, IBinder token, Intent service,        String resolvedType, IServiceConnection connection, int flags, String callingPackage,        int userId) throws TransactionTooLargeException {    enforceNotIsolatedCaller("bindService");    // Refuse possible leaked file descriptors    if (service != null && service.hasFileDescriptors() == true) {        throw new IllegalArgumentException("File descriptors passed in Intent");    }    // ...    synchronized(this) {    //关键代码        return mServices.bindServiceLocked(caller, token, service,                resolvedType, connection, flags, callingPackage, userId);    }}

这个方法内调用了mServices对象的bindServiceLocked方法,mServices是ActiveSerivces类型的,下面看看ActiveServices类的bindServiceLocked方法的具体实现:

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.javaint bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,            String resolvedType, final IServiceConnection connection, int flags,            String callingPackage, final int userId) throws TransactionTooLargeException {        //...        try {    // ...            if ((flags&Context.BIND_AUTO_CREATE) != 0) {//关键代码                if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,                        permissionsReviewRequired) != null) {                    return 0;                }            }            // ...            if (s.app != null && b.intent.received) {                try {//关键代码                    c.conn.connected(s.name, b.intent.binder, false);                } // ...            }     // ...        } // ...        return 1;    }private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,          boolean whileRestarting, boolean permissionsReviewRequired)          throws TransactionTooLargeException {      // ...      if (!isolated) {          app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);  // 如果要启动的Service所在 进程已经创建,并且进程的ActivityThread也不为null,则直接启动Service          if (app != null && app.thread != null) {              try {                  app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);                  realStartServiceLocked(r, app, execInFg);                  return null;              }               // ...          }      }       // ...      //要启动的Service所在的进程还未创建      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;  }

bindServiceLocked这个方法内部,会调用bringUpServiceLocked方法,bringUpServiceLocked内部会根据要绑定的Service所在的进程是否创建,如果进程创建了并且ActivityThread也不为null,则直接走绑定Service流程,否则,要先创建Service所在的进程,然后在走绑定Service的流程。为了分析过程尽量全面,我们就按照Service是在一个新的进程中这种情况分析,下面看mAm.startProcessLocked()这个方法,这里的mAm就是AMS,在AMS中,通过调用几次startProcessLocked()的重载方法后,调用到startProcess方法,接着调用了Process类的start方法,接着调用了ZygoteProcess类的start方法,Process类的start方法调用是system_server进程和ZygoteProcess进程进行进程间通信,他们是通过socket方式进行进程间通信的。ZygoteProcess内部,通过调用start方法,接着调用startViaZygote方法,最终调用zygoteSendArgsAndGetResult方法,完成Servcie所在的进程的创建工作,这样Servcie所在的进程就创建了,执行ActivityThread的main方法,在main方法中,主要完成了主线程的Looper的创建,并创建ActivityThread对象,并调用其attach方法,如果sMainHandler对象为null,则给这个对象赋值,并调用Looper.loop()方法进行消息的抽取。ActivityThread的attach方法中,在次获取system_server进程在app进程的代理对象,然后调用这个代理对象attachApplication方法,这个方法中,将ApplicationThread对象作为参数传入,这样system_servier进程就可以获取到app进程的ApplicationThread这个binder对象在system_server进程中的代理对象。方便后续system_server进程(客户端)向app进程(服务端)发起进程间通信。AMS的attachApplication方法内部又调用了attachApplicationLocked方法,
这个方法内部通过调用ApplicationThread这个对象的bindApplication方法,这个时候是进程间通信(system_server作为客户端,app进程作为服务端),ApplicationThread的bindApplication方法内部,调用了sendMessage(H.Execute_Bind)方法,接着又执行了handleBindApplication方法,handleBindApplication方法内部主要做了三件事:
1.创建Instrumentation对象
2.调用LoadedApk的makeApplication方法,创建Application对象
3.调用Instrumentation的callApplicationOnCreate方法,完成Application的OnCreate方法的执行。
到这里,AMS的attachApplicationLocked方法中的ApplicationThread的bindApplication方法执行过程分析完毕,这个过程的具体分析,可以看Android 9.0 点击桌面应用图标,启动Activity的过程分析
接着继续看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;}

上面已经分析了thread.bindApplication方法,下面继续看mServices.attachApplicationLocked方法,mServices是ActivieServices类型的,所以代码执行到ActivieServices类的attachApplicationLocked方法

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;    if (mPendingServices.size() > 0) {        ServiceRecord sr = null;        try {            for (int i=0; i 0) {        try {            // ...            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,                    r.app.repProcState);            // ...        } // ...    }    return true;}

attachApplicationLocked方法内部会r.app.thread.scheduleCreateService方法,r表示ServcieRecord对象,可以理解为是Servcie, r.app其实就是ProcessRecord类型的对象,可以理解为Process,r.app.thread是一个IApplicationThread类型的对象。
所以r.app.thread.scheduleBindService最终会执行到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);            break;}private void handleCreateService(CreateServiceData data) {        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);        } // ...        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);            // ...        }// ...}

handleCreateService方法内部做了如下事情:
1.通过类加载的方式创建Service实例对象
2.调用LoadedApk类的makeApplication方法,返回一个Application对象
3.调用servcie的attach方法,这个方法内部主要是调用了attachBaseContext方法,将servcie与ContextImpl对象关联
4.调用Servcie的onCreate方法
至此,Servcie被创建,并且OnCreate方法也得到执行。

下面继续看ActiveServices类的realStartServiceLocked方法

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);// ...    }    // ...    // 关键代码    requestServiceBindingsLocked(r, execInFg);    updateServiceClientActivitiesLocked(app, null, true);    // ...}private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)            throws TransactionTooLargeException {        for (int i=r.bindings.size()-1; i>=0; i--) {            IntentBindRecord ibr = r.bindings.valueAt(i);    //关键代码            if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {                break;            }        }}private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,        boolean execInFg, boolean rebind) throws TransactionTooLargeException {    //在前面的分析中,Service所在的进程已经创建,并且ActivityThread也创建了,所以这里的判断不成立    if (r.app == null || r.app.thread == null) {        return false;    }    if ((!i.requested || rebind) && i.apps.size() > 0) {        try {            // ...            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,                    r.app.repProcState);            // ...        } // ...    }    return true;}

这方法内部继续调用到requestServiceBindingLocked的重载方法,这个重载方法内部,
调用r.app.thread,这个对象的scheduleBindService方法,r.app.thread是一个IApplicationThread类型的对象。所以r.app.thread.scheduleBindService最终会执行到ApplicationThread的scheduleBindService方法,这里其实是进程间通信。下面看看这个方法的具体实现

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityThread.javapublic final void scheduleBindService(IBinder token, Intent intent,        boolean rebind, int processState) {    updateProcessState(processState, false);    // ...    // 关键代码    sendMessage(H.BIND_SERVICE, s);} public void handleMessage(Message msg) {   case BIND_SERVICE:        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");        handleBindService((BindServiceData)msg.obj);        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);        break;}private void handleBindService(BindServiceData data) {        Service s = mServices.get(data.token);        if (s != null) {            try {                data.intent.setExtrasClassLoader(s.getClassLoader());                data.intent.prepareToEnterProcess();                try {                        if (!data.rebind) {    // 关键代码                        IBinder binder = s.onBind(data.intent);// 关键代码                        ActivityManager.getService().publishService(                                data.token, data.intent, binder);                    } else {                        s.onRebind(data.intent);                        ActivityManager.getService().serviceDoneExecuting(                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);                    }                    // ...                } // ...            }    // ...        }}

scheduleBindService方法最终调用到了handleBindService方法,最终调用了s.onBind()方法,这里的s就是Service,所以,至此Service的onBind方法执行。

接着调用了AMS的publishService方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javapublic void publishService(IBinder token, Intent intent, IBinder service) {        // Refuse possible leaked file descriptors        if (intent != null && intent.hasFileDescriptors() == true) {            throw new IllegalArgumentException("File descriptors passed in Intent");        }        synchronized(this) {            if (!(token instanceof ServiceRecord)) {                throw new IllegalArgumentException("Invalid service token");            }    // 关键代码            mServices.publishServiceLocked((ServiceRecord)token, intent, service);        }}

这个方法中mServices是ActiveServices类型的,下面看看ActiveServices类的publishServiceLocked方法

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.javavoid publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {        final long origId = Binder.clearCallingIdentity();        try {            if (r != null) {                Intent.FilterComparison filter                        = new Intent.FilterComparison(intent);                IntentBindRecord b = r.bindings.get(filter);                if (b != null && !b.received) {                    b.binder = service;                    b.requested = true;                    b.received = true;                    for (int conni=r.connections.size()-1; conni>=0; conni--) {                        ArrayList clist = r.connections.valueAt(conni);                        for (int i=0; i

这个方法内部c.conn.connected(r.name, service, false);其中c.conn是LoadedApk类的静态内部类ServiceDispatcher的静态内部类InnerConnection类型对象,而InnerConnection 是继承 IServiceConnection.Stub,所以,c.conn其实就是app进程的InnerConnection这个binder对象在system_server进程中的代理,此时,system_server进程作为客户端,通过这个代理对象向app进程(作为服务端)发起进程间通信,这样,InnerConnection的onConnected方法就得到执行,下面看看InnerConnection的connected的具体实现

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/LoadedApk.javapublic final class LoadedApk {     static final class ServiceDispatcher {    private static class InnerConnection extends IServiceConnection.Stub {            final WeakReference mDispatcher;            InnerConnection(LoadedApk.ServiceDispatcher sd) {                mDispatcher = new WeakReference(sd);            }            public void connected(ComponentName name, IBinder service, boolean dead)                    throws RemoteException {                LoadedApk.ServiceDispatcher sd = mDispatcher.get();                if (sd != null) {    // 关键代码                    sd.connected(name, service, dead);                }            }    public void connected(ComponentName name, IBinder service, boolean dead) {if (mActivityThread != null) {   // 关键代码    mActivityThread.post(new RunConnection(name, service, 0, dead));} else {    doConnected(name, service, dead);}    }     }}

InnerConnection的connected这个方法内部会调用ServiceDispatcher类的connected方法,
ServiceDispatcher类的connected方法又会调用
mActivityThread.post(new RunConnection(name, service, 0, dead));
这里mActivityThread其实就是个handler,下面看看这个RunConnection类,它是LoadedApk的静态内部类ServiceDispatcher的一个内部类

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/LoadedApk.javaprivate final class RunConnection implements Runnable {            RunConnection(ComponentName name, IBinder service, int command, boolean dead) {                mName = name;                mService = service;                mCommand = command;                mDead = dead;            }            public void run() {                if (mCommand == 0) {// 关键代码                    doConnected(mName, mService, mDead);                } else if (mCommand == 1) {                    doDeath(mName, mService);                }            }            final ComponentName mName;            final IBinder mService;            final int mCommand;            final boolean mDead;}public void doConnected(ComponentName name, IBinder service, boolean dead) {            ServiceDispatcher.ConnectionInfo old;            ServiceDispatcher.ConnectionInfo info;            synchronized (this) {                if (mForgotten) {                    return;                }                old = mActiveConnections.get(name);                if (old != null && old.binder == service) {                    return;                }                if (service != null) {                    // A new service is being connected... set it all up.                    info = new ConnectionInfo();                    info.binder = service;                    info.deathMonitor = new DeathMonitor(name, service);                    try {                        service.linkToDeath(info.deathMonitor, 0);                        mActiveConnections.put(name, info);                    } catch (RemoteException e) {                        // This service was dead before we got it...  just                        // don't do anything with it.                        mActiveConnections.remove(name);                        return;                    }                } else {                    // The named service is being disconnected... clean up.                    mActiveConnections.remove(name);                }                if (old != null) {                    old.binder.unlinkToDeath(old.deathMonitor, 0);                }            }            // If there was an old service, it is now disconnected.            if (old != null) {                mConnection.onServiceDisconnected(name);            }            if (dead) {                mConnection.onBindingDied(name);            }            if (service != null) {    // 关键代码                mConnection.onServiceConnected(name, service);            } else {                // The binding machinery worked, but the remote returned null from onBind().                mConnection.onNullBinding(name);            }}

run方法中,有调用了doConnected方法,doConnected方法中,mConnection.onServiceConnected方法,这里的mConnection就是我们bindServcie方法中传入的ServiceConnection类型的变量,所以至此,onServiceConnected方法得到回调。

以上便是bindService的整个过程分析

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. Android(安卓)通知的基本用法示例代码
  5. Android(安卓)SQLite是线程安全的吗?
  6. Android学习笔记之mainfest文件中android属性
  7. 四十七、实现调用Android手机的拍照功能
  8. android颜色设使用方法
  9. Android(安卓)APK安装过程及原理详解

随机推荐

  1. python 3.8.6初学笔记
  2. 0108-JSON二个函数,get,post发起ajax请求
  3. php运算符实例|分支与循环结构|替代语法|
  4. PHP基础:运算符,分支结构,循环以及文件包
  5. 新的一年对自己的希望
  6. PHP基础知识:常见运算符、语句分支(模板写
  7. php流程控制和循环结构
  8. 数值运算常用途径;字符串拼接注意事项;流程
  9. CentOS中的"resolv.conf"文件被重置的解
  10. 函数作用域与闭包-回调与参数-函数多值返