首页 > 代码库 > Android Service组件在进程内绑定(bindService)过程

Android Service组件在进程内绑定(bindService)过程

      本文参考Android应用程序绑定服务(bindService)的过程源代码分析http://blog.csdn.net/luoshengyang/article/details/6745181和《Android系统源代码情景分析》,作者罗升阳

一、Android Service组件在进程内绑定(bindService)过程

      0、总图流程图如下:



       1、Counter和CounterService所在应用程序主线程向ActivityManagerService进程发送BIND_SERVICE_TARNSATION

       如下图:



      如图:第一步

      ~/Android/frameworks/base/core/java/android/app

      ----ActivityManagerNative.java

class ActivityManagerProxy implements IActivityManager
{
	......

	public int bindService(IApplicationThread caller, IBinder token,
			Intent service, String resolvedType, IServiceConnection connection,
			int flags) throws RemoteException {
		Parcel data = http://www.mamicode.com/Parcel.obtain();>
       其中connection.asBinder()为InnerConnection对象。还有intent,主要关注这两个参数。



      如图:第二步,省略binder_transaction传输过程,因为上面已经分析过了。


       如图:第二步,省略binder_transaction传输过程,因为上面已经分析过了。


       如图:第三步

      ~/Android/frameworks/base/core/java/android/app

      ----ActivityManagerNative.java

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    ......
    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();
            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();
            IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
            int res = bindService(app, token, service, resolvedType, conn, fl); 
            reply.writeNoException();
            reply.writeInt(res);
            return true;
        }   
    .......
}
       其中conn为上图中IServiceConnection.Stub.Proxy对象,引用了InnerConnection对象还有intent,主要关注这两个参数。

       如图:第四步

       ~/Android/frameworks/base/services/java/com/android/server/am

       ----ActivityManagerService.java

public final class ActivityManagerService extends ActivityManagerNative
		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
	......

	public int bindService(IApplicationThread caller, IBinder token,
			Intent service, String resolvedType,
			IServiceConnection connection, int flags) {
		......

		synchronized(this) {
			......
			final ProcessRecord callerApp = getRecordForAppLocked(caller);
			......

			ActivityRecord activity = null;
			if (token != null) {
				int aindex = mMainStack.indexOfTokenLocked(token);
				......
				activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
			}
			
			......

			ServiceLookupResult res =
				retrieveServiceLocked(service, resolvedType,
				Binder.getCallingPid(), Binder.getCallingUid());
			
			......

			ServiceRecord s = res.record;

			final long origId = Binder.clearCallingIdentity();

			......

			AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
			ConnectionRecord c = new ConnectionRecord(b, activity,
				connection, flags, clientLabel, clientIntent);

			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);
			.......

			if ((flags&Context.BIND_AUTO_CREATE) != 0) {
				......
				if (!bringUpServiceLocked(s, service.getFlags(), false)) {
					return 0;
				}
			}

			......
		}

		return 1;
	}			

	......
}

       主要做了以下几件事:

     (1)创建ServiceRecord对象,并初始化它bindings变量,这个变量主要用来描述传递过来的intent。

     (2)初始化它connections变量,这个变量主要用来描述传递过来的IServiceConnection.Stub.Proxy对象。

     (3)ActivityManagerService进程向Counter和CounterService子线程发送SCHEDULE_CREATE_SERVICE_TRANSACTION。


       2、ActivityManagerService进程向Counter和CounterService子线程发送SCHEDULE_CREATE_SERVICE_TRANSACTION

       如总图中的第2步,过程可参考Android Activity组件的启动过程http://blog.csdn.net/jltxgcy/article/details/35984557中的第2步。

 

       3、在Counter和CounterService主线程创建CounterService,并调用了它的onCreate方法

       需要说明的一点是:

mServices.put(data.token, service);
       把刚创建的CounterService加入到mServices中了。
 

       4、返回到ActivityManagerService进程

   

       5、ActivityManagerService进程向Counter和CounterService子线程发送SCHEDULE_BIND_SERVICE_TRANSACTION



        如图:第一步

        ~/Android/frameworks/base/core/java/android/app

        ----ApplicationThreadNative.java,ApplicationThreadProxy类

class ApplicationThreadProxy implements IApplicationThread {
	......
	
	public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)
			throws RemoteException {
		Parcel data = http://www.mamicode.com/Parcel.obtain();>

        其中token为ServiceRecord对象,如下图,还有intent,主要关注这两个参数。

 

                                                                                             图1

 
       如图:第二步,省略binder_transaction传输过程,因为上面已经分析过了。


       如图:第三步
       ~/Android/frameworks/base/core/java/android/app

       ----ApplicationThreadNative.java

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
    ........
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case SCHEDULE_BIND_SERVICE_TRANSACTION: {
            data.enforceInterface(IApplicationThread.descriptor);
            IBinder token = data.readStrongBinder();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            boolean rebind = data.readInt() != 0;
            scheduleBindService(token, intent, rebind);
            return true;
        } 
   .......
}
      其中token为上图中的BinderProxy对象,引用了ServiceRecord。还有intent,主要关注这两个参数。


      如图:第四步

      ~/Android/frameworks/base/core/java/android/app

      ----ActivityThread.java

public final class ActivityThread {
	......

	public final void scheduleBindService(IBinder token, Intent intent,
			boolean rebind) {
		BindServiceData s = new BindServiceData();
		s.token = token;
		s.intent = intent;
		s.rebind = rebind;

		queueOrSendMessage(H.BIND_SERVICE, s);
	}

	......
}

      6、在Counter和CounterService主线程绑定CounterService,并调用了它的onBind方法     

      主要做了以下几件事:

    (1)获取了刚刚创建的service,并且调用onBind获取了CounterBinder对象,如下图:

                                                                                      图2 

  

   (2)Counter和CounterService主线程向ServiceManager进程发送PUBLISH_SERVICE_TRANSACTION

      代码如下:

      ~/Android/frameworks/base/core/java/android/app

      ----ActivityThread.java

public final class ActivityThread {
	......

	private final void handleBindService(BindServiceData data) {
		Service s = mServices.get(data.token);
		if (s != null) {
			try {
				data.intent.setExtrasClassLoader(s.getClassLoader());
				try {
					if (!data.rebind) {
						IBinder binder = s.onBind(data.intent);
						ActivityManagerNative.getDefault().publishService(
							data.token, data.intent, binder);
					} else {
						......
					}
					......
				} catch (RemoteException ex) {
				}
			} catch (Exception e) {
				......
			}
		}
	}

	......
}
public class CounterService extends Service implements ICounterService {
	......

	private final IBinder binder = new CounterBinder();  

	public class CounterBinder extends Binder {  
		public CounterService getService() {  
			return CounterService.this;  
		}  
	}  

	@Override  
	public IBinder onBind(Intent intent) {  
		return binder;  
	}  

	......
}

       7、Counter和CounterService主线程向ServiceManager进程发送PUBLISH_SERVICE_TRANSACTION

      如图:第一步

      ~/Android/frameworks/base/core/java/android/app

      ----ActivityManagerNative.java

class ActivityManagerProxy implements IActivityManager
{
	......

	public void publishService(IBinder token,
            Intent intent, IBinder service) throws RemoteException {
        Parcel data = http://www.mamicode.com/Parcel.obtain();>
       其中service为刚刚创建的CounterBinder对象,如图2。其中token为其中token为上图中的BinderProxy对象,引用了ServiceRecord对象。如图1。


       如图:第二步,省略binder_transaction传输过程,因为上面已经分析过了。


       如图:第三步

      ~/Android/frameworks/base/core/java/android/app

      ----ActivityManagerNative.java

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    ......
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case PUBLISH_SERVICE_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder token = data.readStrongBinder();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            IBinder service = data.readStrongBinder();
            publishService(token, intent, service);
            reply.writeNoException();
            return true;
        }  
    .......
}
       其中service为BinderProxy对象,引用了CounterBinder对象,如图2。token为ServiceRecord对象,如图1。


       如图:第四步

       ~/Android/frameworks/base/services/java/com/android/server/am

       ----ActivityManagerService.java

public final class ActivityManagerService extends ActivityManagerNative
		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
	......

	public void publishService(IBinder token, Intent intent, IBinder service) {
		......
		synchronized(this) {
			......
			ServiceRecord r = (ServiceRecord)token;
			......

			......
			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;
					if (r.connections.size() > 0) {
						Iterator<ArrayList<ConnectionRecord>> it
							= r.connections.values().iterator();
						while (it.hasNext()) {
							ArrayList<ConnectionRecord> clist = it.next();
							for (int i=0; i<clist.size(); i++) {
								ConnectionRecord c = clist.get(i);
								......
								try {
									c.conn.connected(r.name, service);
								} catch (Exception e) {
									......
								}
							}
						}
					}
				}

				......
			}
		}
	}

	......
}

        主要是获取ServiceRecord里面的ConnectionRecord对象,它的成员变量conn为IServiceConnection.Stub.Proxy对象,引用了InnerConnection对象。调用connected函数。


      8、ActivityManagerService进程向Counter和CounterService主线程发送connected命令



      经过一系列的传递,最终执行:

      ~/Android/frameworks/base/core/java/android/app

      ----LoadedApk.java

final class LoadedApk {
	......

	static final class ServiceDispatcher {
		......

		private static class InnerConnection extends IServiceConnection.Stub {
			......

			public void connected(ComponentName name, IBinder service) throws RemoteException {
				LoadedApk.ServiceDispatcher sd = mDispatcher.get();
				if (sd != null) {
					sd.connected(name, service);
				}
			}
			......
		}

		......
	}

	......
}

       由于执行了进程间通信,此时service为CounterBinder对象,如图2。所以可以向下转型。

public class MainActivity extends Activity implements OnClickListener {  
	......

	private ServiceConnection serviceConnection = new ServiceConnection() {  
		public void onServiceConnected(ComponentName className, IBinder service) {  
			counterService = ((CounterService.CounterBinder)service).getService();  

			Log.i(LOG_TAG, "Counter Service Connected");  
		}  
		......
	};  
	
	......
}