Android – Binder (a)

Learning from the

“Android development art exploration” www.jianshu.com/p/bdef9e317… Blog.csdn.net/u011240877/…

Binder rambling

Binder is an implementation class of the IBinder interface that Bridges the various managers of a system to their corresponding Services. Binder is primarily used in services.

Android system layering

With an understanding of the Android system’s layers, we’ll have a clearer picture of IPC, so let’s take a look at the system’s layers

Let’s look at the responsibilities of each layer in turn:

  • The Linux Kernel(Linux Kernel layer), which is the main hardware drivers, Binder IPC drivers are also in this layer
  • HAL(Hardware Abstraction Layer), which encapsulates the kernel layer, provides a callable interface to the system service layer, in the form of JNI.
  • Android System Service(Android System Service layer) is the core Service of the Android System. It provides an interface for calling applications
  • Binder IPC Proxys(proxy layer of Binder IPC) serve as a bridge between the application layer and the system service layer, enabling cross-process communication
  • Application Freamwork(Application Framework layer), which is our SDK, provides the libraries we use for our daily development

The Linux kernel layer is the hardware abstraction layer, which is implemented by C/C++. The hardware abstraction layer will be compiled into so file, which has been provided to the system service layer in the way of JNI. The system service layer is implemented by Java. These services manage activities, Windows, and so on. Since the system services layer is implemented in Java, they must run in a separate Dalvik.

Because the programs developed by our programmers and the services of the system are respectively running in different virtual machines, the communication between them can only be completed by IPC technology. In order to facilitate the Coder to call the system service interface, Google provides a Manager corresponding to the system service. The call relationship is as follows:

Starting from the AIDL

Android Interface Definition Language (AIDL) Androd Interface Definition Language, through AIDL can realize IPC, through the Interface defined by AIDL we can complete the cross-process communication between clients and services. With AIDL, Binder is automatically generated at compile time.

Data types supported by AIDL

  1. Java basic data types
  2. The List and Map
    • The element must be an AIDL-supported data type
    • The specific class on the Server side must be ArrayList or HashMap
  3. Other AIDL-generated interfaces
  4. The entity that implements Parcelable

Create aiDL-related files

Set up the entity class Book to implement the Parcelable interface

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(a): Int {
        return 0
    }
    
    override fun toString(a): 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)
        }
    }
}
Copy the code

Create an AIDL directory, enter a name, create a directory to deconstruct, and then delete the files, we define our own files

Create entity class mapping file book. aidl under the same package as the Book entity class. Complains that won’t be able to compile, entity class package interface is top littledavid. Studyipc. Beans – > beans. So the Book under the aidl aidl package should also be the same

// The entity mapping package name must be the same as the package name defined by the entity
package top.littledavid.studyipc.beans;
// Define the mapping
parcelable Book;
Copy the code

Define iBookManager.aidl where IPC operations are defined

// 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();
    // If this is not the base data type to use, be sure to use the direction type identifier: in,out,inout
    void addBook(in Book book);
}

Copy the code

The whole catalog is deconstructed as follows

Ibookmanager.java will be generated in the project path \app\build\generated\source\aidl\debug\top\ littleDavid \studyipc (package name may vary). IPC related code is implemented.

Set up the Service

class BookService : Service() {
    private lateinit var mBookList: MutableList<Book>

    override fun onBind(intent: Intent?).: IBinder {
        mBookList = mutableListOf()
        Log.e("TAG"."OnBind")
        return mIBinder
    }

    // Implement the interface defined by AIDL
    private val mIBinder = object : IBookManager.Stub() {
        override fun getBookList(a): List<Book> {
            return this@BookService.mBookList.toList()
        }

        override fun addBook(book: Book) {
            this@BookService.mBookList.add(book)
        }
    }
}
Copy the code

Configure the service in the Minefast file

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

In the IPC

Conduct IPC in the Activity

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?). {
            // Convert IBinder to AIDL interface
            mIBookManager = IBookManager.Stub.asInterface(service)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // Start the service
        val serviceBindIntent = android.content.Intent(this, BookService::class.java)
        this.bindService(serviceBindIntent, mConn, Context.BIND_AUTO_CREATE)
    }

    // Add book information
    fun addBook(view: View) {
        val book = Book(1."The Art of Android Development"."Mr. Ren Yugang")
        this.mIBookManager!! .addBook(book) loadBookInfo() }private fun loadBookInfo(a) {
        valbookList = mIBookManager!! .bookListval stringBuilder = StringBuilder()
        bookList.forEach {
            stringBuilder.append(it.toString() + "\r\n")}this.bookInfoTV.text = stringBuilder.toString()
    }

    override fun onDestroy(a) {
        super.onDestroy()
        this.unbindService(mConn)
    }
}
Copy the code

conclusion

I finished the IPC of AIDL in a bumpy way. Thanks a lot to the Chinese bloggers for their selfless dedication. In the next chapter, we’ll look at how Binder works.