Android-Binder(一)

学习自

《Android开发艺术探索》

https://www.jianshu.com/p/bdef9e3178c9

https://blog.csdn.net/u011240877/article/details/72765136

Binder漫谈

Binder是IBinder接口的一个实现类,inder是连接系统的各种Manager和其对应的Service的桥梁,Binder主要用于Service中。

Android系统的分层

对Android系统的分层了解了之后,我们会对IPC有一个更清晰的认知,所以我们来看一看系统的分层

我们来依次看一下各层的职责:

  • Linux Kernel(Linux内核层), 这一层中主要是各种硬件的驱动,Binder IPC的驱动也是在此层的
  • HAL(硬件抽象层),对内核层的封装,为系统服务层提提供可调用的接口,以JNI的方式。
  • Android System Service(Android 系统服务层), Android系统的核心服务,为应用层提供调用的接口
  • Binder IPC Proxys(Binder IPC的代理层),是应用层和系统服务层之间的桥梁,实现跨进程通信
  • Application Freamwork(应用程序框架层), 这一程就是我们的SDK,提供我们日常开发所用到的类库

其中Linux内核层好硬件抽象层,都是以C/C++来实现,硬件抽象层会编译为so文件,已JNI的方式提供给系统服务层调用,系统服务层通过Java实现,该层中的服务随着手机的开机而启动(不关机就会一直运行),这些服务负责Activity的管理,Window的管理等等。因为系统服务层是通过Java实现的所以,他们肯定是运行与一个独立的 Dalvik 中。

因为我们程序员自己开发的程序和系统的服务都分别运行在不同的虚拟机中,之间的通信就只能靠 IPC技术来完成了,为了方便Coder调用系统服务接口Google提供了一系统服务相对应的Manager。其调用关系如下:

从AIDL开始

AIDL(Android Interface Definition Language) Androd 接口定义语言,通过AIDL可以实现IPC,通过AIDL定义的接口我们可以完成客户端和服务的跨进程通信,使用了AIDL的话在编译的时候系统会自动帮我们生成 Binder .

AIDL支持的数据类型

  1. Java 的基本数据类型
  2. List 和 Map
    • 元素必须是 AIDL 支持的数据类型
    • Server 端具体的类里则必须是 ArrayList 或者 HashMap
  3. 其他 AIDL 生成的接口
  4. 实现 Parcelable 的实体

建立AIDL相关的文件

建立需要的实体类 Book 实现Parcelable接口

package top.littledavid.studyipc.beans

import android.os.Parcel
import android.os.Parcelable /**
* Created by IT on 7/30/2018.
*/
class Book(val bookId: Int, val bookName: String, val author: String) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readString(),
parcel.readString()) {
} override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(bookId)
parcel.writeString(bookName)
parcel.writeString(author)
} override fun describeContents(): Int {
return 0
} override fun toString(): String {
return "Book(bookId=$bookId, bookName='$bookName', author='$author')"
} companion object CREATOR : Parcelable.Creator<Book> {
override fun createFromParcel(parcel: Parcel): Book {
return Book(parcel)
} override fun newArray(size: Int): Array<Book?> {
return arrayOfNulls(size)
}
}
}

建立AIDL目录,随便输入一名称,建立起目录解构即可,然后把文件删掉,我们自家定义我们自己的文件

建立实体类映射文件 Book.aidl 要在aidl 下与Book 实体类相同的包下才行,否则会报错,无法通过编译,实体类的包接口是 top.littledavid.studyipc.beans->beans 所以aidl下的 Book.aidl包也要一样才行

//实体映射包名一定要和实体定义的包名相同
package top.littledavid.studyipc.beans;
//定义映射
parcelable Book;

定义 IBookManager.aidl 其中定义了IPC操作的方法

// IBookManager.aidl
package top.littledavid.studyipc; // Declare any non-default types here with import statements
import top.littledavid.studyipc.beans.Book; interface IBookManager {
List<top.littledavid.studyipc.beans.Book> getBookList();
//这是如果不是使用的基础数据类型,一定要使用方向类型标识 : in ,out ,inout
void addBook(in Book book);
}

整体目录解构如下

编译成功后会在 项目路径\app\build\generated\source\aidl\debug\top\littledavid\studyipc (包名可能不同)下生成一个 IBookManager.java ,其中实现了IPC相关的代码。

建立Service

class BookService : Service() {
private lateinit var mBookList: MutableList<Book> override fun onBind(intent: Intent?): IBinder {
mBookList = mutableListOf()
Log.e("TAG", "OnBind")
return mIBinder
} //实现AIDL定义的接口
private val mIBinder = object : IBookManager.Stub() {
override fun getBookList(): List<Book> {
return this@BookService.mBookList.toList()
} override fun addBook(book: Book) {
this@BookService.mBookList.add(book)
}
}
}

在Minefast文件中配置服务

<service
android:name=".BookService"
android:enabled="true"
android:exported="true"
android:process=":remote" />

进行IPC

在Activity中进行IPC

class MainActivity : AppCompatActivity() {
private var mIBookManager: IBookManager? = null private val mConn = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName?) {
mIBookManager = null
} override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
//将IBinder转换为AIDL接口
mIBookManager = IBookManager.Stub.asInterface(service)
}
} override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//开启服务
val serviceBindIntent = android.content.Intent(this, BookService::class.java)
this.bindService(serviceBindIntent, mConn, Context.BIND_AUTO_CREATE)
} //添加书籍信息
fun addBook(view: View) {
val book = Book(1, "Android开发艺术探索", "任玉刚老师")
this.mIBookManager!!.addBook(book) loadBookInfo()
} private fun loadBookInfo() {
val bookList = mIBookManager!!.bookList
val stringBuilder = StringBuilder()
bookList.forEach {
stringBuilder.append(it.toString() + "\r\n")
}
this.bookInfoTV.text = stringBuilder.toString()
} override fun onDestroy() {
super.onDestroy()
this.unbindService(mConn)
}
}

总结

磕磕绊绊的总算完成了AIDL的IPC,非常感谢参考文档中国的博主的无私奉献。下一章我们来看一看Binder的原理。

Android-Binder(一)的更多相关文章

  1. [转]Android Binder设计与实现 - 设计篇

    摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder ...

  2. (转)Android Binder设计与实现 – 设计篇

    原文地址(貌似已打不开):Android Binder设计与实现 – 设计篇 ------------------------------------------------------------- ...

  3. 图解Android - Binder 和 Service

    在 Zygote启动过程 一文中我们说道,Zygote一生中最重要的一件事就是生下了 System Server 这个大儿子,System Server 担负着提供系统 Service的重任,在深入了 ...

  4. Android Binder设计与实现 - 设计篇

    要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具 ...

  5. Android Binder机制详解:手写IPC通信

    想要掌握一样东西,最好的方式就是阅读理解它的源码.想要掌握Android Binder,最好的方式就是写一个AIDL文件,然后查看其生成的代码.本文的思路也是来自于此. 简介 Binder是Andro ...

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

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  7. Android Binder IPC详解-Android学习之旅(96)

    linux内存空间与BInder Driver Android进程和linux进程一样,他们只运行在进程固有的虚拟空间中.一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间 ,用户空间是 ...

  8. ANDROID BINDER机制浅析

    Binder是Android上一种IPC机制,重要且较难理解.由于Linux上标准IPC在灵活和可靠性存在一定不足,Google基于OpenBinder的设计和构想实现了Binder. 本文只简单介绍 ...

  9. (原创)Android Binder设计与实现 - 实现篇(1)

    本文属于原创作品,转载请注明出处并放于明显位置,原文地址:http://www.cnblogs.com/albert1017/p/3849585.html 前言 在学习Android的Binder机制 ...

  10. 图文详解 Android Binder跨进程通信机制 原理

    图文详解 Android Binder跨进程通信机制 原理 目录 目录 1. Binder到底是什么? 中文即 粘合剂,意思为粘合了两个不同的进程 网上有很多对Binder的定义,但都说不清楚:Bin ...

随机推荐

  1. gtest简介及简单使用

    本文摘自 gtest简介及简单使用 ,在此感谢作者的分享. 具体使用教程 _______________________________________________________________ ...

  2. Docker下的Spring Cloud三部曲之一:极速体验

    版权声明:欢迎转载,请注明出处,谢谢. http://blog.csdn.net/boling_cavalry/article/details/79177930   目录(?)[+]   从本章开始, ...

  3. python数字前自动补零

    >>> '%d' % 23 #输出23 ' >>> '%5d' % 23 #输出的数字前有3个空位,共占5个字符 ' >>> '%05d' % 2 ...

  4. 人生效率手册:如何卓有成效地过好每一天--By张萌姐姐--读书笔记

    读书笔记:<人生效率手册>:如何卓有成效地过好每一天--By张萌姐姐... 整本书看完的感受: 这本书主要讲的是生活中我们需要给自己一个目标,然后通过自己的努力去实现这个目标,书中说的很多 ...

  5. webpack插件去除没用到的css

    去除没用到的css需要用到purifycss-webpack插件,而这个插件又依赖于purify-css 1.安装 npm i purifycss-webpack purify-css -D 2.加入 ...

  6. OpenStack中RabbitMQ高可用性配置

    采用镜像队列的方案进行配置 1. 网络拓扑 node1:10.10.11.1 node2:10.10.11.2 2. 配置hosts node1+node2: vim /etc/hosts >1 ...

  7. js基础回顾----原型链和原型

    所有的对象都可以自由扩展属性 (null 除外) 所有的引用类型(对象,数组,函数)都有一个_proto_属性 所有的函数都有一个prototype属性 所有引用类型对象的_proto_属性指向它的的 ...

  8. 数学:二次剩余与n次剩余

    二次剩余求的是这个东西 如果给定x,再给定若干个大的质数p,如果结果a相同,那么x是完全平方数? 给出别人的二次剩余的代码: /*poj 1808 题意: 判断平方剩余,即判断(x^2)%p=a是否有 ...

  9. 爬虫笔记之w3cschool注册页面滑块验证码破解(巨简单滑块位置识别,非鼠标模拟轨迹)

    一.背景介绍 最开始接触验证码破解的时候就是破解的w3cschool的使用手机号找回密码页面的验证码,详见:验证码识别之w3cschool字符图片验证码(easy级别),这次破解一下他们注册页面的滑块 ...

  10. ListView position

    在使用listview的时候,我们经常会在listview的监听事件中,例如OnItemClickListener(onItemClick)中,或listview的adapter中(getView.g ...