Android-Binder

青春须早为,岂能长少年。这篇文章主要讲述Android-Binder相关的知识,希望能为你提供帮助。
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有一个更清晰的认知,所以我们来看一看系统的分层

Android-Binder

文章图片

我们来依次看一下各层的职责:
  • 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。其调用关系如下:
Android-Binder

文章图片

从AIDL开始
AIDL(Android Interface Definition Language) Androd 接口定义语言,通过AIDL可以实现IPC,通过AIDL定义的接口我们可以完成客户端和服务的跨进程通信,使用了AIDL的话在编译的时候系统会自动帮我们生成 Binder .
建立AIDL相关的文件建立需要的实体类 Book 实现Parcelable接口
package top.littledavid.studyipc.beansimport 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目录,随便输入一名称,建立起目录解构即可,然后把文件删掉,我们自家定义我们自己的文件
Android-Binder

文章图片

建立实体类映射文件 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); }

整体目录解构如下
Android-Binder

文章图片

编译成功后会在 项目路径appuildgeneratedsourceaidldebug oplittledavidstudyipc (包名可能不同)下生成一个 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 [email  protected]() }override fun addBook(book: Book) { [email  protected](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? = nullprivate 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() + " " ) } this.bookInfoTV.text = stringBuilder.toString() }override fun onDestroy() { super.onDestroy() this.unbindService(mConn) } }

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

    推荐阅读