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 = Parcel.obtain();
		Parcel reply = Parcel.obtain();
		data.writeInterfaceToken(IActivityManager.descriptor);
		data.writeStrongBinder(caller != null ? caller.asBinder() : null);
		data.writeStrongBinder(token);
		service.writeToParcel(data, 0);
		data.writeString(resolvedType);
		data.writeStrongBinder(connection.asBinder());
		data.writeInt(flags);
		mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
		reply.readException();
		int res = reply.readInt();
		data.recycle();
		reply.recycle();
		return res;
	}

	......
}

其中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 = Parcel.obtain();
		data.writeInterfaceToken(IApplicationThread.descriptor);
		data.writeStrongBinder(token);
		intent.writeToParcel(data, 0);
		data.writeInt(rebind ? 1 : 0);
		mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
			IBinder.FLAG_ONEWAY);
		data.recycle();
	}

	......
}

其中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 = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(token);
        intent.writeToParcel(data, 0);
        data.writeStrongBinder(service);
        mRemote.transact(PUBLISH_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    } 

	......
}

其中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");
		}
		......
	};  

	......
}

Android Service组件在进程内绑定(bindService)过程,布布扣,bubuko.com

时间: 2024-12-11 16:58:08

Android Service组件在进程内绑定(bindService)过程的相关文章

Android 子Activity组件在进程内的启动过程 &amp;&amp; 子Activity组件在新进程中的启动过程

1.子Activity组件在进程内的启动过程 在Android Activity组件的启动过程http://blog.csdn.net/jltxgcy/article/details/35984557一文中,我们已经详细分析了Activity的启动过程,对于子Activity组件在进程内的启动过程,我们只分析它们之间的不同. 主要是2处,1是不需要创建新的任务栈,2是不需要创建新进程和子线程. 第1点,体现在如下代码上: -/Android/frameworks/base/services/ja

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

1.首先看两个例子 (1)进程内 Client端 public class CounterService extends Service implements ICounterService { ...... public class CounterBinder extends Binder { public CounterService getService() { return CounterService.this; } } ...... } Server端 public class Ma

Android Service组件在新进程中的启动过程

1.startService 在Android系统匿名共享内存(Anonymous Shared Memory)Java调用接口分析,http://blog.csdn.net/jltxgcy/article/details/31414509一文,Client调用了如下代码: public class Client extends Activity implements OnClickListener { public void onCreate(Bundle savedInstanceState

Android Bound Service(一) ----- Extending Binder Service(进程内绑定Service的简单例子)

ref:http://developer.android.com/guide/components/bound-services.html? 前言 重新学习这一项技术,主要的原因,是因为以前没有好好的学,那时总觉得作品能动,能完成工作就好了,而这种得过且过的想法,大大地影响了我的技术程度,也因此,在这个这个博客里,有许多的复习心得.有幸得到一位前辈的指导,指出,若只是学习,而无实际应用,这样进步会较少,因此,最好要多看源码,并且自己多尝试多实践,这样学习一万小时,应该能有小进步,因此开始了 Bo

Android学习笔记:Android Service组件深入解析

在android开发系统(http://www.maiziedu.com/course/android-px/)中,service与activity一样是android的四大组件之一,他们不仅长得像,而且行为也比较类似.可是Service不像Activity在前台运行,而是与之呼应进行后台运行的服务:如果把 Activity当成下载软件的用户交互界面,而Service就是那个默默在后台运行的下载线程,所以Service的应用场景就是那些我们不需要它常驻前台但需要它一直在后台工作的时候,例如下载.

Android -- Service绑定解绑和aidl

Service是安卓四大组件之一,先前讲到了Service的生命周期,以及非绑定类型的生命周期的例子,这次来分享一下绑定形式的. 应用组件(客户端)可以调用bindService()绑定到一个service.Android系统之后调用service的onBind()方法,它返回一个用来与service交互的IBinder. 绑定是异步的,bindService()会立即返回,它不会返回IBinder给客户端.要接收IBinder,客户端必须创建一个ServiceConnection的实例并传给b

Win32 COM组件 x Android Service

有些书在介绍和讲解android的Service组件时,会使用后台服务一词,并且与运行在主线程的Activity相对.因为后台一词很容易误解,服务一直运行在后台?什么线程在运行?服务一直有条线程在运行?而且后台在不同语境有不同理解.但是如果你开发过COM应用的话,这个Service组件就很容易理解. 我们回顾是如何使用COM的,先实例一个CoInstance,然后通过IUnknown接口QueryInterface查询出我们想要的接口,然后调用接口的方法访问COM组件提供的服务.COM组件可能实

Android 四大组件之再论service

service常见的有2种方式,本地service以及remote service. 这2种的生命周期,同activity的通信方式等,都不相同. 关于这2种service如何使用,这里不做介绍,只是介绍一些被遗漏的地方 1.远程Service(AIDL方式) package com.joyfulmath.samples.basecontrol; import android.app.Activity; import android.content.ComponentName; import a

Android 四大组件(Activity、Service、BroadCastReceiver、ContentProvider)

转载于:http://blog.csdn.net/byxdaz/article/details/9708491 http://blog.csdn.net/q876266464/article/details/19641251 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,Broadcast Receiver广播接收器. 一.了解四大基本组件 Activity : 应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以