android Binder讲解

Binder用于完成进程间通信(IPC),即把多个进程“别”在一起,从线程的角度来讲,Binder驱动代码运行在内核态,客户端程序调用Binder是通过系统调用完成的。Binder是一种架构,这种架构提供了服务端接口、Binder驱动、客户端接口三个模块。

重载onTransactO函数的主要内容是把onTmnSact()函数的参数转换为服务函数的参数,而onTransact()函数的参数来源是客户端调用transact()函数时输入的。

任意一个服务端Binder对象被创建时,同时会在Binder驱动中创建一个

mRemote对象,该对象的类型也是Binder类。客户端要访问远程服务时,都是通过mRemote对象。客户端似乎是直接调用远程服务对应的Binder,而事实上则是通过Binder驱动进行了中转。即存在两个Binder对象,一个是服务端的Binder对象,另一个则是Binder驱动中的Binder对象,所不同的是Binder驱动中的对象不会再额外产生一个线程。

服务端设计

Public class MusicPlayService extends Binder{
/**
* MusicPlayServicemusicPlayService=newMusicPlayService();会开启一个新线程
* code:是客户端与服务端约定的,代表变量存取的编号(多个变量公用一个编号)
* data:客户端数据存放
* replay:服务端返回的数据存放
* flag:IPC调用的模式
* 一种是双向,用常量0表示,其含义是服务端执行完指定服务后会返回一定的数据;
* 一种是单向,用常量1表示,其含义是不返回任何数据。
*/
@Override
Protected boolean onTransact(int code,Parcel data,Parcel reply,int flags) throws RemoteException{
switch(code){
case1000:
//为了某种校验,它与客户端的writeInterfaceToken()对应
data.enforceInterface("MusicPlayService");
String arg=data.readString();
String arg1 = data.readString();
break;
case2000:
data.enforceInterface("MusicPlayService");
arg=data.readString();
break;
}
returnsuper.onTransact(code,data,reply,flags);
}
publicvoidstart(){
}
publicvoidstop(){
}

}

Binder驱动

当创建一个Binder对象时,服务端进程内部创建一个Binder对象,Binder驱动中也会创建一个Binder对象。如果从远程获取服务端的Binder,则只会返回Binder驱动中的Binder对象,而如果从服务端进程内部获取Binder对象,则会获取服务端本身的Binder对象。

客户端设计

publicclassMusicPlayClient{

/**

* 两个问题:

* 1、客户端如何获得服务端的Binder对象引用?

*为什么使用Binder?为了提供一个全局服务,系统的任何应用程序都可以使用,解决方案就是用service服务

*  2、客户端和服务端必须事先约定好两件事情:服务端函数的参数在包裹中的顺序、服务端不同函数的int型标识

*

*service是如何解决上述两个问题

*第一个问题:

*客户端通过binderService和startService来启动服务

*bindService(service,conn,flags)和StartService(service)

*ServiceConnection{

*onServiceConnected(ComponentNamename,IBinderservice);

*}

*通过bind来绑定服务,如果service启动成功,ActivityManagerService就会调用ActivityThread类中的ApplicationThread对象,调用的参数中会包含service的Binder引用,然后再ApplicationThread中回调bindService中的conn接口,客户端可将其设为全局变量。

*第二个问题:

*Androidsdk中提供了aidl工具,可以把一个aidl文件转化成java类,其重载了transact和onTransact方法,统一了包裹存放和包裹读取的参数

*Proxy:客户端访问服务端的代理,统一包裹参数写入的顺序

*Stub:由服务端使用

*当创建一个Binder对象时,服务端进程内部创建一个Binder对象,Binder驱动中也会创建一个Binder对象。如果从远程获取服务端的Binder,则只会返回Binder驱动中的Binder对象,而如果从服务端进程内部获取Binder对象,则会获取服务端本身的Binder对

*/

Public void sendPacket()throwsRemoteException{

IBinde rmRemote=null;

String arg="agr0";

Parcel data=Parcel.obtain();

Parcel reply=Parcel.obtain();

data.writeInterfaceToken("MusicPlayService");//标注远程服务名称

data.writeString(arg);

Int flags=0;

/**

*客户端线程进入Binder驱动,Binder驱动就会挂起当前线程,并向远程服务发送一个消息,

*消息中包含了客户端传进来的包裹。服务端拿到包裹后,会对包裹进行拆解,然后执行指定的服务函数,

*执行完毕后,再把执行结果放入客户端提供的reply包裹中。然后服务端向Binder驱动发送一个notify的消息,

*从而使得客户端线程从Binder驱动代码区返回到客户端代码区。

*/

mRemote.transact(1,data,reply,flags);

IBinderbinder=reply.readStrongBinder();

data.recycle();

reply.recycle();

}

}

时间: 2024-11-08 19:22:21

android Binder讲解的相关文章

[gitbook] Android框架分析系列之Android Binder详解

请支持作者原创: https://mr-cao.gitbooks.io/android/content/android-binder.html Android Binder详解 Table of Contents 1. binder简介 2. binder的实现 2.1. IBinder类简介 2.2. IInterface类简介 2.3. BpBinder和BBinder简介 2.4. ProcessState和IPCThreadState简介 2.5. ServiceManager简介 2.

转:轻松理解 Android Binder,只需要读这一篇

转自http://www.jianshu.com/p/bdef9e3178c9 在 Android 系统中,Binder 起着非常重要的作用,它是整个系统 IPC 的基石.网上已经有很多文章讲述 Binder 的原理,有的讲的比较浅显,没有触及到关键,有的讲的太过于深入底层,难以理解,本文会比较全面,以一个比较轻松的方式,从面到点,大处着眼,小处着手的形式去讲述 Binder 在 Android 中是如何使用的.理解 Binder 的基本原理,对学习 Android 也有很大的帮助,很多问题也能

Android Binder进程间通信---ServiceManager代理对象的获取过程

本文参考<Android系统源代码情景分析>,作者罗升阳. 一.测试代码: -/Android/external/binder/server ----FregServer.cpp ~/Android/external/binder/common ----IFregService.cpp ----IFregService.h ~/Android/external/binder/client ----FregClient.cpp Binder库(libbinder)代码: ~/Android/fr

Android Binder机制分析(5) Binder_ioctl()分析

引言 在博客Android Binder机制(3)本地服务注册过程这篇博客中我们详细讲解了本地服务的注册过程,除了一个地方之外,那就是IPCThreadState::waitForResponse()方法中的talkWithDriver(),而在talkWithDriver()中调用了binder_ioctl(),由于内容太多,所以专门写一篇博客进行分析. 实际上,不只是在服务注册过程中会调用到Binder Driver中的binder_ioctl(),在服务检索.服务使用阶段都会调用到bind

Android Binder机制(3) 本地服务注册过程

本博客将讲解本地服务的注册过程,为了方便大家更好地理解,选择了MediaPlayer Service作为例子. 启动并注册MediaPlayer Service的代码在frameworks/base/media/mediaserver/main_mediaserver.cpp中,如下: main_mediaserver.cpp 1 2 3 4 5 6 7 8 9 10 11 12 int main(int argc, char** argv) { sp<ProcessState>proc(Pr

Android Binder机制(1):Binder架构分析

从这篇博客开始,将进入Binder机制的分析系列,顺序是先讲解Binder机制的框架,理解了整体思想后,再深入分析各层的细节实现,最后会实现一个自己的本地服务. 1.Binder的历史 BeOS是Be公司在1991年开发的运行在BeBOX硬件上的一款操作系统,与同期的其他操作系统不同,它是一款基于GUI设计的操作系统. George Hoffman(在LinkedIn上可以找到这哥们,简直是活着的传奇)当时任Be公司的工程师,他启动了一个名为OpenBinder的项目,该项目的宗旨是研究一个高效

Android Binder机制(2) ContextManager注册过程分析

引言 Context Manager对应的进程为servicemanager,它先于Service Server与服务客户端运行,首先进入接收IPC数据的状态,处理来自Service Server或服务客户端的请求.在init.rc脚本文件中也可以看到Context Manager在mediaserver与system_server之前运行了. 每当Service Server注册服务时,Context Manager都会把服务的名称与Binder节点编号注册到自身的服务目录中,该服务目录通过根

Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的)

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解Android 卷Ⅰ,Ⅱ,Ⅲ>中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!!另外,本系列文章知识可能需要有一定Android开发基础和项目经验的同学才能更好理解,也就是说该系列文章面向的是Android中高级开发工程师. 前言 我们在上一篇中比较详尽的介绍了Android的消息机

Android 实例讲解HorizontalScrollView实现左右滑动

本博文主要讲解怎么使用HorizontalScrollView实现左右滑动的效果. HorizontalScrollView实际上是一个FrameLayout ,一般通过只放置一个LinearLayout子控件.如果要使其添加其他的控件,就使用LinearLayout子控件来添加其他的控件,最后达到丰富其内容的效果.其中,LinearLayout设置的orientation布局为Horizontal.HorizontalScrollView不可以和ListView同时用,因为ListView有自