浅谈binder机制

前段时间一直在看有关Binder的知识,最近刚好有时间,总结一些一些知识,希望和大家交流学习。

说起Binder我相信大家学android开发的多多少少都对binder有些了解,binder机制作为android进程间通信的一种机制,在Android底层中应用的非常多。我们都知道Android系统是基于LInux内核开发的,Linux内核提供了丰富的进程间通信的机制,如:管道、信号、消息队列、共享内存和套接字等,但是Android系统并没有采用传统的进程间通信机制,而是开发了一套新的进程间通信的机制BInder,当然采用Binder肯定有一些优势,与传统的进程间通信相比,BInder进程通信机制在进程间传输数据的时候,只需要执行一次拷贝操作,因此,在效率和内存节省方面有一定的优势。

接下来我们就开始谈谈Binder了,Binder说白了就是Android中的一个类,它实现了Ibinder接口,从Android-Framework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager、WindowManager等)和相应的Manager_Service的桥梁;下面有一张他们之间的图

Binder在进行进程间通信的时候,每一个Server进程和Client进程都维护一个Binder线程池来处理进程间的通信要求,Service组件在启动时,会将自己注册到一个Service Manager组件中,以便Client组件可以通过Service Manager组件找到它。上图中Binder驱动程序和Service
Manager由系统提供,Client和Service由应用程序实现,接下来我已我们Android中最常用的AIDL为例讨论一下

编写一个AIDL程序需要以下几步:

首先我们看看服务端程序需要的步骤:

(1)首先编写你的类(book.java)文件,这个类必须实现Parcelable接口进行序列化。

(2)编写与该类相同的名的aidl文件(book.aidl)

(3)编写接口文件(IBookManager.aidl),此接口即客户端请求时的接口

(4)实现服务端的service(BookManagerService),该service为客户端实际进行服务(主要实现Stub类)

接下来我们看看客户端要实现的步骤:

客户端其实与服务端很多地方相似:

(1)我们这一块需要将服务端的所有AIDL文件拷贝带客户端,这里的报名必须与服务端一致,因为存在序列化与反序列化问题

(2)编写客户端Activity,绑定服务端service

(3)实现ServiceConnection,在onServiceConnected方法中,将讲IBinder转化为AIDL接口类型,然后调用远程服务

(4)如果远程服务比较耗时,可以将调用方法从主线程中分离出来,开一个子线程,这样程序就不会崩溃

好吧,大家现在估计也是很懵逼的吧,我再给大家理一遍然后就上代码了:

首先大家可以看到,当我们新建一个AIDL文件之后,在gen文件夹下会生成一个对应的AIDL文件,他是系统为我们自动生成的一个接口类,继承自android.os.IInterface接口,其中有几个比较重要的类和方法这里我给大家一一说明:

首先是stub类,这个Stub类继承BInder实现了我们定义的AIDL接口,这个类也是我们客户端在实际要用到的类,在这个类中有一个asInterface方法,他的参数是一个IBinder接口,他返回了另一个Stub的内部类proxy,这个proxy类真正实现了AIDL接口,每当客户端通过Stub的asInterface方法获取到该类时,调用具体的接口方法时,proxy类里面会调用transact,当客户端和服务端都位于一个进程时,方法调用就不会走跨进程的transact过程,如果不在同一个进程的话将会交给Proxy的处理,这里transact有几个参数第一个参数为请求的方法类型,接下来_data与_reply他们两个是一个parcel类型,其中分别封装客户端的请求信息和服务端反馈的信息,然后底层通过Bindler传送到onTransact方法中,他会从客户端传过来的参数中判断客户端请求的是那个方法,里面的请求信息是什么,接下来会将数据写入,返回到客户端。

上面就是BInder跨进程的的整个流程,下面就是上代码了:

AIDL文件

Book.java
package com.binderpro.aidl;

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

public class Book implements Parcelable{
	private String name;
	private int price;
	private int bookId;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public Book(String name, int price) {
		super();
		this.name = name;
		this.price = price;
	}
	@Override
	public String toString() {
		return "Book [name=" + name + ", price=" + price + "]";
	}
	@Override
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public void writeToParcel(Parcel arg0, int arg1) {
		// TODO Auto-generated method stub
		arg0.writeInt(bookId);
		arg0.writeString(name);
		arg0.writeInt(price);
	}
	public static final Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>(){

		@Override
		public Book createFromParcel(Parcel arg0) {
			// TODO Auto-generated method stub
			return new Book(arg0);
		}

		@Override
		public Book[] newArray(int arg0) {
			// TODO Auto-generated method stub
			return new Book[arg0];
		}

	};
	private Book(Parcel in){
		bookId = in.readInt();
		name = in.readString();
		price = in.readInt();
	}
}
Book.aidl
package com.binderpro.aidl;

parcelable Book;

IBookManager

package com.binderpro.aidl;

import java.util.List;
import com.binderpro.aidl.Book;
interface IBookManager {
	List<Book> getBookList();
	void addBook(in Book book);

}

BookManagerService

package com.example.binderpro;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;

import com.binderpro.aidl.Book;
import com.binderpro.aidl.IBookManager;

public class BookManagerService extends Service {
	private static final String TAG = "BMS";
	private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<Book>();
	public BookManagerService() {
		// TODO Auto-generated constructor stub
	}
	private  Binder mBinder = new IBookManager.Stub() {

		@Override
		public List<Book> getBookList() throws RemoteException {
			// TODO Auto-generated method stub
			return mBookList;
		}

		@Override
		public void addBook(Book book) throws RemoteException {
			// TODO Auto-generated method stub
			mBookList.add(book);
		}
	};

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		mBookList.add(new Book("android", 1));
		mBookList.add(new Book("ios", 2));
	}
	public IBinder onBind(Intent intent){
		return mBinder;
	}
}

接下来是客户端代码,aidl文件同上

MainActivity.java

package com.example.binderpro;

import java.util.List;

import com.binderpro.aidl.Book;
import com.binderpro.aidl.IBookManager;

import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {

	private ServiceConnection mConnection = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onServiceConnected(ComponentName arg0, IBinder arg1) {
			// TODO Auto-generated method stub
			IBookManager bookManager = IBookManager.Stub.asInterface(arg1);
			List<Book> list;
			try {
				list = bookManager.getBookList();
				Log.i("Tag", list.toString());
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	};

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Intent intent = new Intent("com.example.binderpro.BookManagerService");

		bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		unbindService(mConnection);

	}

}

最后是系统根据AIDL文件生成的java代码;

IBookManager代码比较长,我删除了一部分

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: G:\\android_code\\Binderpro\\src\\com\\binderpro\\aidl\\IBookManager.aidl
 */
package com.binderpro.aidl;

public interface IBookManager extends android.os.IInterface {
	/** Local-side IPC implementation stub class. */
	public static abstract class Stub extends android.os.Binder implements
			com.binderpro.aidl.IBookManager {
		private static final java.lang.String DESCRIPTOR = "com.binderpro.aidl.IBookManager";

		/** Construct the stub at attach it to the interface. */
		public Stub() {
			this.attachInterface(this, DESCRIPTOR);
		}

		/**
		 * Cast an IBinder object into an com.binderpro.aidl.IBookManager
		 * interface, generating a proxy if needed.
		 */
		public static com.binderpro.aidl.IBookManager asInterface(
				android.os.IBinder obj) {
			if ((obj == null)) {
				return null;
			}
			android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
			if (((iin != null) && (iin instanceof com.binderpro.aidl.IBookManager))) {
				return ((com.binderpro.aidl.IBookManager) iin);
			}
			return new com.binderpro.aidl.IBookManager.Stub.Proxy(obj);
		}

		@Override
		public android.os.IBinder asBinder() {
			return this;
		}

		@Override
		public boolean onTransact(int code, android.os.Parcel data,
				android.os.Parcel reply, int flags)
				throws android.os.RemoteException {
			switch (code) {
			case INTERFACE_TRANSACTION: {
				reply.writeString(DESCRIPTOR);
				return true;
			}
			case TRANSACTION_getBookList: {
				data.enforceInterface(DESCRIPTOR);
				java.util.List<com.binderpro.aidl.Book> _result = this
						.getBookList();
				reply.writeNoException();
				reply.writeTypedList(_result);
				return true;
			}
			case TRANSACTION_addBook: {
				data.enforceInterface(DESCRIPTOR);
				com.binderpro.aidl.Book _arg0;
				if ((0 != data.readInt())) {
					_arg0 = com.binderpro.aidl.Book.CREATOR
							.createFromParcel(data);
				} else {
					_arg0 = null;
				}
				this.addBook(_arg0);
				reply.writeNoException();
				return true;
			}
			}
			return super.onTransact(code, data, reply, flags);
		}

		private static class Proxy implements com.binderpro.aidl.IBookManager {
			private android.os.IBinder mRemote;

			@Override
			public java.util.List<com.binderpro.aidl.Book> getBookList()
					throws android.os.RemoteException {
				android.os.Parcel _data = android.os.Parcel.obtain();
				android.os.Parcel _reply = android.os.Parcel.obtain();
				java.util.List<com.binderpro.aidl.Book> _result;
				try {
					_data.writeInterfaceToken(DESCRIPTOR);
					mRemote.transact(Stub.TRANSACTION_getBookList, _data,
							_reply, 0);
					_reply.readException();
					_result = _reply
							.createTypedArrayList(com.binderpro.aidl.Book.CREATOR);
				} finally {
					_reply.recycle();
					_data.recycle();
				}
				return _result;
			}

			@Override
			public void addBook(com.binderpro.aidl.Book book)
					throws android.os.RemoteException {
				android.os.Parcel _data = android.os.Parcel.obtain();
				android.os.Parcel _reply = android.os.Parcel.obtain();
				try {
					_data.writeInterfaceToken(DESCRIPTOR);
					if ((book != null)) {
						_data.writeInt(1);
						book.writeToParcel(_data, 0);
					} else {
						_data.writeInt(0);
					}
					mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0);
					_reply.readException();
				} finally {
					_reply.recycle();
					_data.recycle();
				}
			}
		}

		static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
		static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
	}
}

今天大概就讲这么多,最近我也正在研究一些关于Binder底层的东西,可能后续感觉自己能力到了会写一些关于Binder底层的东西,因为Binder实在太复杂了,在linux驱动层好多都是C代码,在底层都是以好多结构体和一些红黑树,hash表,引用链组织起来,其中一些Binder线程池、同步、缓冲区、死亡通知之间的关联十分复杂,有兴趣的可以看看罗升阳的《Android系统源码情景分析》这本书对于Binder底层机制讲的非常好。

				
时间: 2024-10-09 17:18:03

浅谈binder机制的相关文章

浅谈 Attention 机制的理解

什么是注意力机制? 注意力机制模仿了生物观察行为的内部过程,即一种将内部经验和外部感觉对齐从而增加部分区域的观察精细度的机制.例如人的视觉在处理一张图片时,会通过快速扫描全局图像,获得需要重点关注的目标区域,也就是注意力焦点.然后对这一区域投入更多的注意力资源,以获得更多所需要关注的目标的细节信息,并抑制其它无用信息. 图片来源:深度学习中的注意力机制,其中红色区域表示更关注的区域. Encoder-Decoder 框架 目前大多数的注意力模型都是依附在 Encoder-Decoder 框架下,

浅谈Binder的基本原理

网上有一堆关于Binder原理的文章,都很长,我希望能尽量把这个问题讲得简短些. 1)关于binder驱动 Binder在Android里被设计成了一个驱动,安装在/dev/binder,这也是Android和linux的重要区别之一:Android提出了一个新的进程间通信方式(IPC).另外,这种方式是通过远程过程调用(RPC)实现的. 对Binder的操作和对其它驱动的操作是一样的,看这个结构体: static const struct file_operations binder_fops

Android IPC机制(三):浅谈Binder的使用

一.前言 在上一篇博客Android IPC机制(二):AIDL的基本用法中,笔者讲述了安卓进程间通讯的一个主要方式.利用AIDL进行通讯.并介绍了AIDL的基本用法. 事实上AIDL方式利用了Binder来进行跨进程通讯.Binder是Android中的一种跨进程通讯方式.其底层实现原理比較复杂.限于笔者水平,不能展开详谈.所以这篇文章主要谈谈以AIDL为例,谈谈Binder的用法. 二.原理 上一篇文章中创建了一个IMyAidl.aidl文件,即接口文件,随即编译了该文件.生成了一个.jav

浅谈多态机制的意义及实现

转自:http://blog.hesey.net/2010/12/significance-and-implementation-of-polymorphism.html: 在面向对象编程(Object-Oriented Programming, OOP)中,多态机制无疑是其最具特色的功能,甚至可以说,不运用多态的编程不能称之为OOP.这也是为什么有人说,使用面向对象语言的编程和面向对象的编程是两码事. 多态并没有一个严格的定义,维基百科上给它下的定义比较宽松: Subtype polymorp

【C#】:浅谈反射机制

什么是反射? 反射提供了封装程序集.模块和类型的对象(Type 类型).可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性.如果代码中使用了属性,可以利用反射对它们进行访问. 反射机制是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:'程序集(Assembly)'.'模块(Module)'.'类型(class)'组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息. 通俗的来讲,就是反射是通过

[转载]浅谈多态机制的意义及实现

http://blog.hesey.net/2010/12/significance-and-implementation-of-polymorphism.html 在面向对象编程(Object-Oriented Programming, OOP)中,多态机制无疑是其最具特色的功能,甚至可以说,不运用多态的编程不能称之为OOP.这也是为什么有人说,使用面向对象语言的编程和面向对象的编程是两码事. 多态并没有一个严格的定义,维基百科上给它下的定义比较宽松: Subtype polymorphism

【C#】:浅谈反射机制 【转】

http://blog.csdn.net/lianjiangwei/article/details/47207875 什么是反射? 反射提供了封装程序集.模块和类型的对象(Type 类型).可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性.如果代码中使用了属性,可以利用反射对它们进行访问. 反射机制是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’.‘模块(Module)’.‘类型(class

浅谈闭包机制

var foo = "Hello"; var c =(function a() { function b(){ var bar = " World"; alert(foo + bar); return bar; } return b; })()(); alert(foo + c); 本实例弹出两次hello world: 一.什么是闭包? “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式

浅谈项目管理机制

一.项目及项目管理 1.什么是项目 要讨论项目管理,就必须首先理解项目这个概念.项目是为完成某一独特的产品或服务所做的一次性努力.项目一般要涉及一些人员,由这些人员完成一些相互关联的活动,项目发起人通常希望能够在最有效地利用资源的基础上,及时.高效地完成项目任务. 2.什么是项目管理 项目管理是指"在项目活动中运用专门的知识.技能.工具和方法,使项目能够实现或超过项目干系人的需要和期望."这一定义不仅仅是强调使用专门的知识和技能,还强调项目管理中各参与人的重要性.项目经理不仅仅要努力实