binderService()方法的调用过程

bindService()在绑定Service主要经历一下几个过程:

  • Activity向ActivityManagerService发送一个绑定xxxService组件的进程间的请求。
  • ActivityManagerService在接到请求后检查运行XXXService组件的进程是否处于运行状态,如果没有运行就启动这个进程。
  • 在运行XXXService的进程启动后,ActivityManagerService就请求它返回一个Binder的本地(代理)对象,以便于Activity通过这个Binder对象和Service建立连接。
  • AMS将从XXXService中获得本地(代理)Binder对象发送给Activity。
  • Activity在获得Binder对象后就可以去访问XXXService中实现的接口。

Service实例

我通过一个AnimalService的实例来分析bindService()的过程。首先通过AIDL定义服务接口:

package com.cike.firstkotlin;

import com.cike.firstkotlin.model.Animal;
// Declare any non-default types here with import statements
//定义动物管理接口
interface IAnimalManager {
    //添加动物
    void addAnimal(in Animal animal);
    //获取动物列表
    List<Animal> getAnimals();
}

Animal类的定义如下:


import android.os.Parcel
import android.os.Parcelable

open class Animal(val name : String) : Parcelable {
    constructor(parcel: Parcel) : this(parcel.readString())

    override fun writeToParcel(p0: Parcel?, p1: Int) {
        if (p0 != null) {
            p0.writeString(name);
        }
    }

    override fun describeContents(): Int {
        return 0;
    }

    companion object CREATOR : Parcelable.Creator<Animal> {
        override fun createFromParcel(parcel: Parcel): Animal {
            return Animal(parcel)
        }

        override fun newArray(size: Int): Array<Animal?> {
            return arrayOfNulls(size)
        }
    }
}

实现了IAnimalManager接口的Service的内容:

package com.cike.firstkotlin.activity

import android.app.Service
import android.content.Intent
import android.os.IBinder
import com.cike.firstkotlin.IAnimalManager
import com.cike.firstkotlin.model.Animal

class AnimalManagerService : Service() {
    val store : MutableList<Animal> = ArrayList<Animal>()

    override fun onBind(p0: Intent?): IBinder? {
        println(this.toString() + "onBind()")
        return  object : IAnimalManager.Stub() {
            override fun getAnimals(): MutableList<Animal> {
                return store
            }

            override fun addAnimal(animal: Animal?) {
                if(animal != null)  {
                    store.add(animal)
                }
                println( "有多少动物:${store?.size} 新添加的动物是${animal?.name}")
            }
        }
    }
}

在MainActivty中绑定服务:

    //创建ServiceConnection对象
    object mServiceConnection : ServiceConnection {
        var animalMS: IAnimalManager? = null

        override fun onServiceDisconnected(p0: ComponentName?) {
            animalMS = null
        }

        override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
            animalMS = IAnimalManager.Stub.asInterface(p1)
        }
    }
    
    val bindIntent = Intent()
        bindIntent.setClass(this, AnimalManagerService::class.java)
        //绑定AnimalManagerService服务
        bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE)

先从Activity的bindService()方法开始分析。Activity继承自ContextWrapper类bindService()方法就定义在这里:

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

    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
            //这里的mBase实际上是ContextImpl的实例
        return mBase.bindService(service, conn, flags);
    }

在bindService()方法中直接调用了mBase的bindService()方法,这里的mBase是ContextImpl的实例,所以调用了ContextImpl的bindService():

.../aosp/frameworks/base/core/java/android/app/ContextImpl.java
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        warnIfCallingFromSystemProcess();
        //交给bindServiceCommon()继续处理
        return bindServiceCommon(service, conn, flags, Process.myUserHandle());
    }
    
    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
            UserHandle user) {
        IServiceConnection sd;
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (mPackageInfo != null) {
            //1.IServiceConnection服务的本地Binder对象
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
                    mMainThread.getHandler(), flags);
        } else {
            throw new RuntimeException("Not supported in system context");
        }
        validateServiceIntent(service);
        try {
            IBinder token = getActivityToken();
            if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
                    && mPackageInfo.getApplicationInfo().targetSdkVersion
                    < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                flags |= BIND_WAIVE_PRIORITY;
            }
            service.prepareToLeaveProcess();
            //调用ActivityManagerProxy的bindService()方法
            int res = ActivityManagerNative.getDefault().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
            if (res < 0) {
                throw new SecurityException(
                        "Not allowed to bind to service " + service);
            }
            return res != 0;
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
    }

在注解1.处mPackageInfo是一个LoadedApk的对象,在LoadedApk中存储了当前应用的信息(如应用androidMainfase.xml解析后的信息)。这里通过mPackageInfo.getServiceDispatcher(conn,getOuterContext(),mMainThread.getHandler(), flags)获取了一个InnerConnection类对象。InnerConnection类继承自IServiceConnection.Stub类,是接口IServiceConnection的Binder的本地通信对象。IServiceConnection接口是在IServicConnection.aidl中定义。


public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
        synchronized (mServices) {
            //ServiceDispatcher类中封装了InnerConnection、ServiceConnection、Handler等属性。
            LoadedApk.ServiceDispatcher sd = null;
            /**
            * mServices这个Map以Context为Key,这里的context 指的就是Activity. 所以mServices存储的是当前Activity绑定的service。
            * 1.一个Activity可能会绑定多个Service,所以mServices的key对应的Value是一个集合ArrayMap.
            * 2.做为Value的ArrayMap以绑定service使用的ServiceConnection为key,以ServiceDispatcher为Value
            */
            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
            if (map != null) {
                sd = map.get(c);
            }
            if (sd == null) {
                /**
                 * c serviceConnection
                 * handler 是应用程序进程ActivityThread中的mH
                 */
                sd = new ServiceDispatcher(c, context, handler, flags);
                if (map == null) {
                    map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
                    mServices.put(context, map);
                }
                map.put(c, sd);
            } else {
                sd.validate(context, handler);
            }
            return sd.getIServiceConnection();
        }
    }

在LoadedApk的getServiceDispatcher()方法中首先定义了一个ServiceDispatcher类型的对象sd,ServiceDispatcher中封装了IServiceConnecation的Binder本地对象和ActivityThread的主线程中的Handler–mH(这个Handler在后边绑定服务时会用到)。然后从mServices变量中获取ServiceDispatcher实例,mServices是一个以Context为key,ArrayMap为value的ArrayMap类型的变量。这里作为Key的Context指的就是Activity,用于标示那个Ativity要绑定服务。因为一个Activity可以绑定多个Service所以Services的Value又使用了一个ArrayMap。在ServiceDispatcher类中封装了ServiceConnection的binder通信的本地对象、绑定服务的Activity的主进程的Handler(mH)等信息。在最后通过getIServiceConnection()返回一个IServiceConncection的Binder的本地对象。

我们继续回到ContextImpl的bindServiceCommon()方法中,通过ActivityManagerNative.getDefault()获取一个ActivityManagerService的代理对象ServiceManagerProxy,然后调用了代理对象的bindServcie()通过Binder驱动程序将绑定服务调用传递给AMS继续处理。

···/frameworks/base/core/java/android/app/ActivityManagerProxy.java
    public int bindService(IApplicationThread caller, IBinder token,
            Intent service, String resolvedType, IServiceConnection connection,
            int flags,  String callingPackage, int userId) throws RemoteException {
        //创建序列化容器
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        //将参数吸入到Parcel对象data中
        data.writeInterfaceToken(IActivityManager.descriptor);
        //将ApplicationThread的Binder机制的本地对象下入data
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        //将要绑定Activity的token写入data
        data.writeStrongBinder(token);
        service.writeToParcel(data, 0);
        data.writeString(resolvedType);
        //将InnerConnection的Binder机制中的本地对象下入Data
        data.writeStrongBinder(connection.asBinder());
        data.writeInt(flags);
        data.writeString(callingPackage);
        data.writeInt(userId);
        // 通过binder将请求发送给AMS
        mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        int res = reply.readInt();
        data.recycle();
        reply.recycle();
        return res;
    }

mRemote.transact(…)方法通过Binder驱动程序最终会调用到ActivityManagerNative.java的onTransact()方法中:

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

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
  switch (code) {
    case BIND_SERVICE_TRANSACTION: {
      data.enforceInterface(IActivityManager.descriptor);
      IBinder b = data.readStrongBinder();
      //在AMP的bindService()中传入的是ApplicationThread的binder机制的本地对象,
      //此处b为ApplicationThread的, 转换后生成即ApplicationThreadProxy对象。
      //我一直不太理解明明传入的是本地对象为什么在AMS中接受时怎么就转化为了代理对象,
      //后来才明白这个转化过程是在Binder驱动程序中完成的。转换过程可以看一下Binder机制的文章
      IApplicationThread app = ApplicationThreadNative.asInterface(b);
      IBinder token = data.readStrongBinder();
      Intent service = Intent.CREATOR.createFromParcel(data);
      String resolvedType = data.readString();
      b = data.readStrongBinder();
      int fl = data.readInt();
      String callingPackage = data.readString();
      int userId = data.readInt();
      //生成InnerConnectiond的代理对象
      IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
      //通过bindService()方法继续处理
      int res = bindService(app, token, service, resolvedType, conn, fl,
              callingPackage, userId);
      reply.writeNoException();
      reply.writeInt(res);
      return true;
    }
    ...
  }
}

这些调用过程都是在需要绑定服务的Activity所在的进程进程中完成的,调用AMS的代理对象的方法后通过Binder机制进入到AMS中继续处理。真正处理bindService()请求的逻辑在下面:

    public 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");
        }

        if (callingPackage == null) {
            throw new IllegalArgumentException("callingPackage cannot be null");
        }

        synchronized(this) {
            //调用ActiveService的bindServiceLocked()方法继续处理
            return mServices.bindServiceLocked(caller, token, service,
                    resolvedType, connection, flags, callingPackage, userId);
        }
    }

在AMS的bindService()中直接调用了ActiveServices类的对象mServices的bindServiceLocked()方法继续处理。ActiveService类内部封装了对Service的绑定状态保存等。具体看一下AtiveServices的bindService():

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags,
            String callingPackage, int userId) throws TransactionTooLargeException {
        
        //通过ApplicationThread获取需要绑定service的应用是否已经运行
        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
        if (callerApp == null) {
            throw new SecurityException(
                    "Unable to find app for caller " + caller
                    + " (pid=" + Binder.getCallingPid()
                    + ") when binding service " + service);
        }

        ActivityRecord activity = null;
        if (token != null) {
            //通过token找到需要绑定服务的activity,这里使用的是token的标示作用
            activity = ActivityRecord.isInStackLocked(token);
            if (activity == null) {
                Slog.w(TAG, "Binding with unknown activity: " + token);
                return 0;
            }
        }

        ·································
        
        //检索出需要绑定的Service的ServiceRecord的包装类;如果ServiceRecord不存在则创建一个新的并被包装成ServiceLookUpResult对象。
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType, callingPackage,
                    Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
        if (res == null) {
            return 0;
        }
        if (res.record == null) {
            return -1;
        }
        //要绑定的ServiceRecord
        ServiceRecord s = res.record;

        final long origId = Binder.clearCallingIdentity();

        try {
            ················

            mAm.startAssociationLocked(callerApp.uid, callerApp.processName,
                    s.appInfo.uid, s.name, s.processName);
            //检索出一个Service和一个App的关联信息
            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
            //绑定记录,这里边包含了那个应用进程的那个activity要绑定ServiceRecord的信息
            ConnectionRecord c = new ConnectionRecord(b, activity,
                    connection, flags, clientLabel, clientIntent);
            //connection是IServiceConnection的代理对象
            IBinder binder = connection.asBinder();
            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
            if (clist == null) {
                clist = new ArrayList<ConnectionRecord>();
                s.connections.put(binder, clist);
            }
            clist.add(c);
            b.connections.add(c);
            if (activity != null) {
                if (activity.connections == null) {
                    activity.connections = new HashSet<ConnectionRecord>();
                }
                activity.connections.add(c);
            }
            b.client.connections.add(c);
            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
                b.client.hasAboveClient = true;
            }
            if (s.app != null) {
                updateServiceClientActivitiesLocked(s.app, c, true);
            }
            clist = mServiceConnections.get(binder);
            if (clist == null) {
                clist = new ArrayList<ConnectionRecord>();
                mServiceConnections.put(binder, clist);
            }
            clist.add(c);

            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
                s.lastActivity = SystemClock.uptimeMillis();
                //启动service
                if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
                    return 0;
                }
            }

            if (s.app != null) {
                if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
                    s.app.treatLikeActivity = true;
                }
                // This could have made the service more important.
                mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
                        || s.app.treatLikeActivity, b.client);
                mAm.updateOomAdjLocked(s.app);
            }

            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
                    + ": received=" + b.intent.received
                    + " apps=" + b.intent.apps.size()
                    + " doRebind=" + b.intent.doRebind);

            if (s.app != null && b.intent.received) {
                // Service is already running, so we can immediately
                // publish the connection.
                try {
                    c.conn.connected(s.name, b.intent.binder);
                } catch (Exception e) {
                    Slog.w(TAG, "Failure sending service " + s.shortName
                            + " to connection " + c.conn.asBinder()
                            + " (in " + c.binding.client.processName + ")", e);
                }

                // If this is the first app connected back to this binding,
                // and the service had previously asked to be told when
                // rebound, then do so.
                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                    requestServiceBindingLocked(s, b.intent, callerFg, true);
                }
            } else if (!b.intent.requested) {
                requestServiceBindingLocked(s, b.intent, callerFg, false);
            }

            getServiceMap(s.userId).ensureNotStartingBackground(s);

        } finally {
            Binder.restoreCallingIdentity(origId);
        }

        return 1;
    }

该方法主要功能:

  • 通过AMS的getRecordForAppLocked()方法根据ApplicationThread参数获取要绑定的service所在的进程是否启动。
  • 通过retrieveServiceLocked()方法根据Intent检查或创建Service记录。
  • 通过retrieveAppBindingLoced()方法检索出一个Service和要绑定service的app相关的信息,并将这些信息封装到AppBindRecord中。
  • 创建ConnectionRecord对象用于封装那个应用绑定那个进程的服务的相关信息。
  • 通过bringUpServiceLocked()方法启动服务。根据启动的service是否运行在独立进程中返回不同的值。如果service运行在独立进程中则此方法返回值为null;
  • 在bringUpServiceLocked()方法返回null时(即Service单独一个进程时)继续调用requestServiceBindingLocked()方法绑定服务。

在bindServiceLocked()方法中主要用于检查并创建Service相关的ServiceRecord和要绑定此Service的APP的相关信息,最终调用bringUpServiceLocked()方法启动服务。

private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting) throws TransactionTooLargeException {
            
        ....................................
        
        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
        final String procName = r.processName;
        ProcessRecord app;
        //isolated标示Service是不是运行在独立进程中
        if (!isolated) {
            //获取ProcessRecord对象。如果app不为null则说明service要运行的进程已经创建。
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                    //重要; 进一步处理
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } catch (TransactionTooLargeException e) {
                    throw e;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
                }
            }
        } else {
            app = r.isolatedProc;
        }

        if (app == null) {
            //启动这个Service所在的进程, 进程创建成功后会返回ProcessRecord
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {
                //重启seivice绑定
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }

        if (!mPendingServices.contains(r)) {
            //将serivice添加到等待启动队列中,等进程启动后再启动这个Service
            mPendingServices.add(r);
        }

.......................................................

        return null;
    }

bringUpServiceLocked()方法主要功能是通过r.serviceInfo.flags属性值判断Service是不是运行在独立进程中,如果不是运行在独立进程中则说明要绑定的Service和Activity运行在同一个进程中。如果isolated = false则通过mAm.getProcessRecordLocked()检查当前进程是否存在,如果存在则调用realStartServiceLocked(r, app, execInFg)方法继续处理服务启动的工作。如果要绑定的Service运行在独立的进程中且这个独立的进程还没有运行则调用AMS的startProcessLocked()方法启动这个进程并让bringUpServiceLocked()方法返回null。在我分析的场景中将Service设置为运行在独立进程中,所以调用startProcessLocked()方法从Zygote进程中fork()出一个新进程同时返回null后继续回到bindServiceLocked()方法中。

在startProcessLocked()方法会从Zygote进程中fork()五一个新的进程,在新进程创建出来后会间接的调用到realStartServiceLocked()方法来启动服务。下面看看它是怎么启动服务的吧。

private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        if (app.thread == null) {
            throw new RemoteException();
        }
        //这个service在那个进程中
        r.app = app;
        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();

        final boolean newService = app.services.add(r);
        bumpServiceExecutingLocked(r, execInFg, "create");
        mAm.updateLruProcessLocked(app, false, null);
        mAm.updateOomAdjLocked();

        boolean created = false;
        try {
            ...................
            mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            //重要。通过ApplicationThread从AMS中回到Client。
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
            Slog.w(TAG, "Application dead when creating service " + r);
            mAm.appDiedLocked(app);
            throw e;
        } finally {
            if (!created) {
                // Keep the executeNesting count accurate.
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);

                // Cleanup.
                if (newService) {
                    app.services.remove(r);
                    r.app = null;
                }

                // Retry.
                if (!inDestroying) {
                    scheduleServiceRestartLocked(r, false);
                }
            }
        }
        //在Service本创建后继续处理
        requestServiceBindingsLocked(r, execInFg);

        updateServiceClientActivitiesLocked(app, null, true);

        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null));
        }

        sendServiceArgsLocked(r, execInFg, true);

        if (r.delayed) {
            if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
            getServiceMap(r.userId).mDelayedStartList.remove(r);
            r.delayed = false;
        }

        if (r.delayedStop) {
            // Oh and hey we've already been asked to stop!
            r.delayedStop = false;
            if (r.startRequested) {
                if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
                        "Applying delayed stop (from start): " + r);
                stopServiceLocked(r);
            }
        }
    }

在realStartServiceLocked()方法中主要有一下几点:

  • 通过app.thread.scheduleCreateService()方法通知ApplicationThread去创建Service。
  • 通过requestServiceBindingsLocked()方法在Service创建后绑定服务。

在这里app.thread是AppliactionThreadProxy的对象,调用他的scheduleCreateService()方法会通过Binder通信机制最终调用到ApplicationThread的scheduleCreateService()方法。

.../aosp/frameworks/base/core/java/android/app/ActivityThread.java
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;
            //发送消息
            sendMessage(H.CREATE_SERVICE, s);
        }

在ApplicationThread的scheduleCreateService()方法中痛殴sendMessage()发送东西到mH 的Handler中进一步处理:

.../aosp/frameworks/base/core/java/android/app/ActivityThread.java
private class H extends Handler {
    public void handleMessage(Message msg) {
    
    ..................................
    
        case CREATE_SERVICE:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
            //继续处理
            handleCreateService((CreateServiceData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
            .....................
        }
}

在Handler的handleMessage()方法的switch case CREATE_SERVICE分支中直接调用了handleCreateService()方法继续处理:

.../aosp/frameworks/base/core/java/android/app/ActivityThread.java
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实例
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {   .............     }
        try {
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            //调用service的attach()方法
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
            //调用onCreate()方法
            service.onCreate();
            mServices.put(data.token, service);
            try {
                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实例。
  • 通过LoadApk.makeApplication()方法创建Application实例。
  • 调用Service实例的attach()方法和onCreate()方法。
  • 调用ActivityManagerProxy.ServiceDoneExecuting()方法通知AMS服务已经创建完成。

分析到这里我们已经知道了Service的创建过程,现在我们继续回到ActiveService的bindServiceLocked()方法中。上边分析看到bindServiceLocked()方法有两个要点:一个是realStartServiceLocked()方法(已经分析过了)。现在继续另外一个要requestServiceBindingLocked()方法:

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

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
            //如果要绑定的service所以进程不存在直接返回。
        if (r.app == null || r.app.thread == null) {
            return false;
        }
        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind");
                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                //通过ApplicationThread代理对象回到客户端
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
                if (!rebind) {
                    i.requested = true;
                }
                i.hasBound = true;
                i.doRebind = false;
            } catch (TransactionTooLargeException e) {
                ..................................
            } catch (RemoteException e) {
                ..................................
            }
        }
        return true;
    }

requestServiceBindingLocked()方法直接通过ApplicationThread的代理对象ApplicationThreadProxy的scheduleBindService()方法通过Binder通信机制调用到要绑定Service的activity的ApplicationThread的scheduleBindService()方法中;下面的操作就进入了Client端继续处理:

.../aosp/frameworks/base/core/java/android/app/ActivityThread.java的内部类ApplicationThread中
public final void scheduleBindService(IBinder token, Intent intent,
                boolean rebind, int processState) {
            updateProcessState(processState, false);
            BindServiceData s = new BindServiceData();
            s.token = token;
            s.intent = intent;
            s.rebind = rebind;
            //绑定服务
            sendMessage(H.BIND_SERVICE, s);
        }

在ApplicationThread类的scheduleBindService()方法中通过sendMessage()方法发送消息给H类型的mH Handler继续处理。

.../aosp/frameworks/base/core/java/android/app/ActivityThread.java
private class H extends Handler {
    public static final int BIND_SERVICE = 121;
    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;
    
    .........................
    }

在ActivityThread的H hander的handleMessage()方法中switch BIND_SERVICE:分支中直接调用了handleBindService()方法继续处理:

.../aosp/frameworks/base/core/java/android/app/ActivityThread.java
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) {
                        //调用service的onBind()对象
                        IBinder binder = s.onBind(data.intent);
                        //通知AMS服务的onBind()已经执行了
                        ActivityManagerNative.getDefault().publishService(
                                data.token, data.intent, binder);
                    } else {
                        s.onRebind(data.intent);
                        ActivityManagerNative.getDefault().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
                    ensureJitEnabled();
                } catch (RemoteException ex) {
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to bind to service " + s
                            + " with " + data.intent + ": " + e.toString(), e);
                }
            }
        }
    }

在handleBindService()方法中主要是调用了Service的onBind()方法然后通过ActivityManagerProxy的publishService()方法通知AMS Service的onBind()方法已经调用可以继续处理了。下面看一下AMS的publishService():

.../aosp/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void publishService(IBinder token, Intent intent, IBinder service) {
        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");
            }
            //重要,调用了ActiveServices的publishServiceLocked()方法继续处理
            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
        }
    }

在AMS的publishService()方法中直接调用了ActiveServices的pulishServiceLocked()继续处理:

void 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;         //service的Binder本地对象
                    b.requested = true;
                    b.received = true;
                    //循环遍历所有要绑定这个service的进程
                    for (int conni=r.connections.size()-1; conni>=0; conni--) {
                        //在一个进程中可能有多个组件Activity绑定这个service
                        ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                        for (int i=0; i<clist.size(); i++) {
                            ConnectionRecord c = clist.get(i);
                            if (!filter.equals(c.binding.intent.intent)) {
                                ..................................
                                continue;
                            }
                            try {
                                //调用IServiceConnection代理对象的connected()方法
                                c.conn.connected(r.name, service);
                            } catch (Exception e) {}
                        }
                    }
                }
                serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

在publishServiceLocked()方法中通过Intent从ServiceRecord中查找出要绑定Service的所用ServiceConnecation。要绑定这个Service的进程可能又多个而每个进程中也可能会用多个组件Activity来绑定这个Service所以这里用了循环迭代的方式调用ServiceConnection的代理对象ServiceConnectionProxy的connected()方法,通过Binder驱动程序connected()方法最终会调用到本地对象InnerConnection类的connected()方法:

.../aosp/frameworks/base/core/java/android/app/LoadedApk.java
    //IServiceConnection的binder本地对象。
        private static class InnerConnection extends IServiceConnection.Stub {
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
            
            InnerConnection(LoadedApk.ServiceDispatcher sd) {
                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
            }
            //通过binder驱动程序调用到这里
            public void connected(ComponentName name, IBinder service) throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service);
                }
            }
        }

在InnerConnection的connected()方法中直接调用了ServiceDispatcher的connected()方法:

.../aosp/frameworks/base/core/java/android/app/LoadedApk.java内部类的ServiceDispatcher类
public void connected(ComponentName name, IBinder service) {
            //这个的mActivityThread即使ActivityThread中穿件H handler 
            if (mActivityThread != null) {
                //向H handler发送一个Runable对象RunConnection
                mActivityThread.post(new RunConnection(name, service, 0));
            } else {
                doConnected(name, service);
            }
        }

在ServiceDispatcher的connected()方法中mAtivityThread指的就是ActivityThread中的H handler.这里直接向Handler中发送了一个RunConnection类型的runable。

private final class RunConnection implements Runnable {
            RunConnection(ComponentName name, IBinder service, int command) {
                mName = name;
                mService = service;
                mCommand = command;
            }

            public void run() {
                if (mCommand == 0) {
                //根据ServiceDispatcher的connected()方法中构建RunConnection时传入的参数command = 0
                //所以会执行doConnected()方法
                    doConnected(mName, mService);
                } else if (mCommand == 1) {
                    doDeath(mName, mService);
                }
            }

            final ComponentName mName;
            final IBinder mService;
            final int mCommand;
        }

在RunConnection的run()方法通过属性mCommand = 0,这里会继续执行doConnected()方法:

public void doConnected(ComponentName name, IBinder service) {
            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.
                    mDied = false;
                    info = new ConnectionInfo();
                    info.binder = service;
                    //设置service死亡监听
                    info.deathMonitor = new DeathMonitor(name, service);
                    try {
                        service.linkToDeath(info.deathMonitor, 0);
                        //将ServiceConnection保存
                        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 not disconnected.
            if (old != null) {
                mConnection.onServiceDisconnected(name);
            }
            // If there is a new service, it is now connected.
            if (service != null) {
                //调用ServiceConnection的onServiceConnected()方法
                mConnection.onServiceConnected(name, service);
            }
        }

在doConnect()方法中首先检查有没有旧的ServiceConnection的信息,如果有则终止服务并通知绑定此service的activiy已经终止了。然后最后调用mConnection.onServiceConnected()。onServiceConnected()方法的实现就是我们在绑定服务时创建的。
到此bindService()的过程已经全部完成

你可能感兴趣的:(移动开发)