`
zhy20045923
  • 浏览: 155816 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Binder机制分析【二】-Binder服务/客户端实现举例

阅读更多
前一章说了下Binder机制的实现分析,这章就主要通过实际的例子来看看,具体的服务端创建。一般而言,同一个进程里的沟通称之为短程沟通,进程间的沟通称之为远程沟通,短程沟通的效率远高于远程沟通,但是Android提供的Binder机制就提供了高效率的远程沟通。
下面通过Activity与Service之间的沟通为例,列举出2种实现方式。
例子一:通过直接继承Binder实现
1. 实现Binder类
public class MyBinder extends Binder {
	private Context mContext;
	public MyBinder(Context context){
		mContext = context;
	}
	@Override
	protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
			throws RemoteException {
		reply.writeString(data.readString()+" mp3");
		switch(code){
			case 1:
				MyMediaPlayer.getIntance(mContext).play();
				break;
			case 2:
				MyMediaPlayer.getIntance(mContext).stop();
				break;
			default:
				break;
		}
		return true;
	}
}

该类继承了Binder类,就必须实现onTransact方法,与客户端的transact方法相对应。其中参数code代表客户端调用码,决定在服务器端调用哪个方法,和transact端的保持一致,data是请求参数,由客户端设置,reply为返回参数,服务器端设置。Flags表示ipc通信方式。0表示双向,1表示单向。
2. 实现service类
public class MyService extends Service {
	private Binder mBinder = null;
	@Override
	public IBinder onBind(Intent arg0) {
		Log.e("XXX", "onBind");
		return mBinder;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		mBinder = new MyBinder(this);
		Log.e("XXX", "onCreate");
	}
}

Service相对简单,主要是初始化Binder对象,并且在onBind中返回。
3. Activity与service之间的沟通
首先需要创建ServiceConnection对象,并且在bind时返回Binder对象
private ServiceConnection mServiceConnection = new ServiceConnection() {
		@Override
		public void onServiceDisconnected(ComponentName name) {
			Log.e("XXX", "onServiceDisconnected");
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			mIBinder = service;
			Log.e("XXX", "onServiceConnected");
		}
	};

其次,调用bindService绑定服务。
Intent intent = new Intent("com.eric.ipc.binder");
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);

最后,在需要调用服务器端方法的地方,通过transact进行沟通,这里传递的参数必须是Parcel的。
Parcel send_data = Parcel.obtain();
				send_data.writeString("play");
				Parcel reply_data = Parcel.obtain();
					mIBinder.transact(1, send_data, reply_data, 0);

由此可见,这种方法提供的沟通手段比较单一,只能通过transact进行沟通,如果服务器端的接口很多,这样调用起来不太方便,所以Android提供了一种更为简单的方式来实现-AIDL。
AIDL定义了Proxy/Stub封装了IBinder接口,提供了更加方便的新接口。
例子二:通过AIDL实现
1. 单一aidl文件接口
package com.eric.ipc.aidl;
interface IMediaPlayer {
	void play();
	void stop();
}

该接口文件以aidl结尾,中间封装了2个方法,该文件生成后,会在gen目录下自动生成对应的java文件,里面包含了具体的类别继承,反向呼叫等实现。
2. 实现Binder类
public class MyBinder extends IMediaPlayer.Stub {
	private Context mContext;
	public MyBinder(Context context){
		mContext = context;
	}
	@Override
	public void play() throws RemoteException {
		MyMediaPlayer.getIntance(mContext).play();
	}
	@Override
	public void stop() throws RemoteException {
		MyMediaPlayer.getIntance(mContext).stop();
	}
}

现在的实现继承接口改为了aidl类文件的Stub,此处需要实现接口中的2个接口方法
3. 实现service类
此处同例一保持一致
4. activity与service之间的沟通
首先,需要实现ServiceConnection对象,注意返回binder对象时与例一之间的差别。
private ServiceConnection mServiceConnection = new ServiceConnection() {
	   @Override
	   public void onServiceDisconnected(ComponentName name) {
		   Log.e("XXX", "onServiceDisconnected");
	   }
	   
	   @Override
	   public void onServiceConnected(ComponentName name, IBinder service) {
		   mIBinder = IMediaPlayer.Stub.asInterface(service);
		   Log.e("XXX", "onServiceConnected");
	   }
   };

其次,需要绑定服务,方法同例一
最后,具体调用服务器端接口
mIBinder.play();

总结:
2种方法都可以实现跨进程通信,但是aidl实现相对简单,接口直接调用。
问题:
1.如果我们想保持和 Service 的通信,又不想让 Service 随着 Activity 退出而退出呢?你可以先 startService() 然后再 bindService() 。当你不需要绑定的时候就执行 unbindService() 方法,执行这个方法只会触发 Service 的 onUnbind() 而不会把这个 Service 销毁。这样就可以既保持和 Service 的通信,也不会随着 Activity 销毁而销毁了。
2.Activity has leaked ServiceConnection异常
这个异常是由于在启动应用时绑定了service,退出时没有接触绑定导致,可以在退出时调用unbindService()方法解决。
3.在先startService(),然后bindService()的情况下,在退出时
1).如果只调用unbindService(),在第一次会调用onUnbind,然后再次绑定时,通过start启动,再退出是不会调用onUnbind。
2).如果调用unbindService()和stopService,整个service会调用ondestory进行销毁。
3.在通过MediaPlayer播放音乐时,网上都说如果在activity中播放,在activity退出时,音乐播放会停止,这个纯粹是他妈的扯淡,我以前还对此坚信不疑。MediaPlayer播放音乐,会重新启动一个service进行播放,如果你的activity或service已经destory了,是不影响播放service的生命周期的。


例子源码见附件

本章介绍了Binder服务器的实现及举例说明了binder客户端与服务端的交互,下一章介绍下Service是如何绑定Binder的
分享到:
评论
2 楼 zhy20045923 2012-03-13  
nanapoleon 写道
Flags表示ipc通信方式。0表示双向,1表示单向。   这个和aidl的oneway是不是一样的。

这个是不一样的,aidl其实默认的也是0.
oneway的意思是在ipc过程中,如果调用者和被调用者在2个不同的进程,调用者不必等到被调用者返回就继续执行。

以下是引用:The oneway keyword means that if that call results in an IPC (i.e. the caller and callee are in different processes) then the calling process will not wait for the called process to handle the IPC. If it does not result in an IPC (i.e. they're both in the same process), the call will be synchronous. It's an unfortunate detail that simplifies the implementation of binder IPC a lot. If they're in the same process, the call is just a regular java method call.
1 楼 nanapoleon 2012-03-13  
Flags表示ipc通信方式。0表示双向,1表示单向。   这个和aidl的oneway是不是一样的。

相关推荐

    CogNex Binder1 - VP6 - Standard

    根据给定文件的信息,我们可以提炼出与CogNex Binder1 - VP6 - Standard相关的多个重要知识点,主要包括: ### 一、课程概述 **标题:** CogNex Binder1 - VP6 - Standard **描述:** 该描述实际上与标题相同,...

    Android NDK实现Binder服务和客户端

    需要在系统源码下编译,或者提取出对应的头文件亦可。这里需要注意Android4.x以后系统SeLinux如果打开,系统级需要配置对应的sepolicy才能使用。测试阶段推荐直接setenforce 0关闭鉴权即可

    Android Binder机制

    - **Binder原理**:Binder机制基于C/S架构,服务端(Server)在自己的进程中提供服务,客户端(Client)通过Binder接口请求服务。Binder在用户空间和内核空间之间传递数据,实现进程间的通信。 - **三角色模型**:...

    MediaPlayerService Binder机制源码分析及详解

    【MediaPlayerService Binder机制源码分析及详解】 在Android系统中,多媒体播放功能是通过`MediaPlayerService`实现的,它是一个核心服务,负责管理和控制多媒体资源的播放。`Binder`机制是Android系统中进程间...

    AndroidBinder机制总结[归纳].pdf

    在Android系统中,Binder机制是实现进程间通信(IPC)的核心工具,尤其在跨应用程序组件交互时至关重要。本文将深入探讨Android Binder机制及其在组件化思想中的应用。 1. Android组件化思想 Android应用的组件化...

    Android底层源码分析_Binder

    - **通信依赖**:Server与Client之间的交互依赖于Binder驱动程序,通过内核提供的`/dev/binder`设备文件建立通信渠道。 **ServiceManager的作用**: - Service组件启动时需向ServiceManager注册,以便Client组件可...

    Android Binder机制完全解析

    Binder并非简单的数据传输工具,而是一个完整的消息传递系统,包含客户端、服务端和服务代理三部分,其中服务代理在客户端和服务器之间起到了桥梁作用。 二、Binder架构 1. 进程间通信模型:Binder通信模型包括...

    Binder面试系列00-binder爱情例子.md

    Binder面试系列00-binder爱情例子.md

    android2.3源码-binder机制.doc

    媒体播放器的服务端(MediaServer)和服务客户端分别运行在不同的进程中,它们之间的通信是通过 Binder 实现的。具体的交互包括: 1. **控制指令**:客户端向服务端发送播放、暂停等控制命令。 2. **事件通知**:...

    Android进程间通信-Binder机制详解

    **二、Binder机制实现流程** 1. **Service Manager成为Binder守护进程之路** - Service Manager在系统启动时自动运行,初始化Binder驱动并监听Binder通信。 - Server通过Binder驱动向Service Manager注册服务,...

    Android Binder设计与实现

    通过对Binder的设计与实现进行详细分析,我们可以清楚地看到Binder在Android系统中的重要地位。它不仅解决了传统IPC机制存在的问题,还提供了更高效、更安全的进程间通信解决方案。对于Android开发者来说,理解...

    SwaggerAPI框架binder-swagger-java.zip

    Binder-swagger-java 的功能很简单,就是帮助构建 swagger.json 所对应的 swagger 对象,并让它可以被 swagger ui 等客户端访问。 注:binder-swagger-java 直接基于 form-binder-java / swagger-models...

    Android系统的Binder机制之一——Service_Manager

    1. **Binder驱动**:Binder驱动是内核中的一个字符设备,位于`/dev/binder`。它是Android系统IPC的核心,负责传递客户端和服务端之间的消息。客户端和服务端都通过这个设备进行通信。尽管本文不会深入讨论Binder驱动...

    android 的binder机制在java、c++层的实现

    Android的Binder机制是其独特的进程间通信(IPC)方式,主要负责Android系统中服务与服务、应用与服务之间的通信。本文将深入解析Binder在Java层和C++层的实现,并通过一个简单的模拟示例来阐述如何在不同进程中进行...

    Binder机制.pdf

    1. **Binder驱动**:这是Android IPC的核心组件,位于内核层,通过/dev/binder字符设备实现进程间的通信。客户端和服务端通过该设备进行数据交换。 2. **ServiceManager**:作为服务的管理中心,负责注册和管理所有...

    Android binder C++ service/client 实现. 共享内存

    二、C++实现Binder服务 1. 创建服务接口:首先定义一个服务接口类,继承自`IBinder`。这个接口将包含服务需要提供的所有方法。例如: ```cpp class IMyService : public android::BBinder { public: virtual void ...

Global site tag (gtag.js) - Google Analytics