android binder入门(二)——手动实现

最近在学习binder原理,先从手动实现binder通信开始学习
代码实现参考:https://www.jianshu.com/p/37368fab05bf

几个概念:

IBinder:接口,实现了接口,就代表对象可以跨进程传输
IInterface:代表Server服务端进程对象提供什么样的能力
Binder:Binder本地对象,实现了IBinder,也是拥有跨进程传输的能力
Stub:继承了Binder本地对象,实现了IInterface接口,表明具有服务端提供给客户端的能力。是一个抽象类,具体的实现需要开发自己在服务Service内部取实现
Proxy:代理,IInterface的实现类,提供给客户端调用

具体实现的过程中的类:

Person
实体类,要序列化,否则传递数据过程中会异常
PersonManager
接口,需要继承IInterface,才能具备进程间通信的能力
内部提供具体的客户端操作方法
PersonManagerProxy
PersonManager方法实现类,实现具体的方法操作,具体的操作需要通过binder.transat实现
PersonManagerStub
1、继承Binder,实现PersonManager
2、继承Binder可以跨进程传输数据
3、实现PersonManager,可以远程操作服务端数据
4、构造方法调用this.attachInterface(this, DESCRIPTOR);作用就是向BinderService注册Binder服务。只有注册了binder,客户端才能查询到binder对象,并且使用内部必须有静态方法 asInterface(binder:IBinder),才能方便将binder对象转换成PersonManager,才能调用服务端定义好的方法。
5、onTransat:PersonManagerProxy类中调用的方法就是在方法内部进行实际处理,并通过跨进程传输到远程service

PersonManagerService
远程service,客户端调用过后才是绑定成功,并建立连接内部有PersonManagerStub对象,并实现了具体的数据操作,是数据操作的最后一步,也是可以和服务端主页面进行实际页面操作
还需要在manifest中进行注册,设置可以跨进程访问,设置intent-filter的action

其实可以理解为客户端启动服务,获取服务端的binder对象PersonManager,但是获取的时候,要先检查之前是否有对象,所以就通过PersonManagerStub检查一下,如果存在就返回之前的使用对象,不存在就返回PersonManager的实现代理类PersonManagerProxy。其他就是binder注册进入ServiceManager的内容了,固定写法。

服务端要实现上面的几个类Person、PersonManager、PersonManagerProxy、PersonManagerStub、PersonManagerService
客户端中,要将服务端的Person、PersonManager、PersonManagerProxy、PersonManagerStub拷贝过去,并且包名还要和服务端的一致

代码执行过程分析:

绑定操作代码执行流程:

1、客户端启动服务bindService ,将服务的信息和连接传入参数
2、服务端收到请求,启动服务,调用PersonManagerService的onCreate和onBind方法,连接成功之后,就会在连接中进行回调
3、客户端收到连接中连接成功的回调,binder获取成功,然后在PersonManagerStub的asInterface中,根据binder创建PersonManager的实现类PersonManagerProxy,命名为类变量mPersonManager,后面要进行操作就可以使用mService进行具体的服务端提供的函数进行操作
android binder入门(二)——手动实现_第1张图片

添加操作代码执行流程:

1、按钮监听回调
2、客户端的PersonManagerProxy调用addPerson方法,addPerson内部有一句代码remote?.transact(PersonManagerStub.TRANSAVTION_addperson,data,replay,0),其中remote就是远程的PersonManagerStub对象,进入server服务端的PersonManagerStub类中的onTransat方法
3、服务端的PersonManagerStub调用onTransact方法内部的addPerson方法,内部操作有this.addPerson(person = arg0!!),就会进入PersonManagerService类中binder变量中的实现方法addPerson
4、PersonManagerService调用stub的变量内部的实现方法addPerson。
流程到PersonManagerService就结束了,并且添加到service的ArrayList链表中
android binder入门(二)——手动实现_第2张图片

删除操作代码执行过程:

代码执行过程和添加时一致的
android binder入门(二)——手动实现_第3张图片

获取全部人员代码执行过程:

代码执行过程和添加时一致的
android binder入门(二)——手动实现_第4张图片

代码结构:

服务端module

android binder入门(二)——手动实现_第5张图片

客户端module

android binder入门(二)——手动实现_第6张图片

具体的实现过程代码如下:


```java
package com.example.binderserver.server

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

class Person():Parcelable {
   
    var name:String?=null
    constructor(parcel: Parcel) : this() {
   
        name = parcel.readString()
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
   
        parcel.writeString(name)
    }

    override fun describeContents(): Int {
   
        return 0
    }

    override fun toString(): String {
   
        return "PErson(name=$name)"
    }

    override fun equals(other: Any?): Boolean {
   
        if (this == other) return true
        if (javaClass!=other?.javaClass)
            return false
        other as Person
        if (name!=other.name){
   
            return false
        }
        return true
    }

    companion object CREATOR : Parcelable.Creator<Person> {
   
        override fun createFromParcel(parcel: Parcel): Person {
   
            return Person(parcel)
        }

        override fun newArray(size: Int): Array<Person?> {
   
            return arrayOfNulls(size)
        }
    }

}
interface PersonManager : IInterface{
   

    @Throws(RemoteException::class)
    fun addPerson(person: Person)
    
    @Throws(RemoteException::class)
    fun deletePerson(person: Person)
    
    @Throws(RemoteException::class)
    fun getPersons():List<Person>
}
package com.example.binderserver.server

import android.os.IBinder
import android.os.Parcel

class PersonManagerProxy:PersonManager {
   
    /**
     * 远程binder对象
     */
    var remote:IBinder?=null
    private companion object var DESCRIPTOR:String="com.example.binderserver.server.PersonManager"

    constructor(remote:IBinder){
   
        this.remote = remote
    }

    fun getInterfaceDescriptor

你可能感兴趣的:(android,binder,android,binder)