Skip to content

Latest commit

 

History

History
213 lines (165 loc) · 5.43 KB

aidl.md

File metadata and controls

213 lines (165 loc) · 5.43 KB

AIDL的使用

  1. 创建.aidl文件

必须使用 Java 编程语言构建.aidl文件。每个.aidl文件均须定义单个接口,并且只需要接口声明和方法签名。

// IMyAidlInterface.aidl
package com.example.aidl.aidl;

// Declare any non-default types here with import statements

interface IMyAidlInterface {
  /**
   * Demonstrates some basic types that you can use as parameters
   * and return values in AIDL.
   */
  void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
          double aDouble, String aString);
}

默认AIDL支持下列数据类型:

  • Java中的基本数据类型,包括 byte,short,int,long,float,double,boolean,char

  • String类型

  • CharSequence类型

  • List类型

    List中的所有元素必须是以上支持的类型之一,或者是一个其他AIDL生成的接口或者Parcelable类型。

  • Map类型

    Map中的所有元素必须是以上支持的类型之一,或者是一个其他AIDL生成的接口或者Parcelable类型

如需自定义数据类型,需要实现android.os.Parcelable 接口,如:

//Book.java
public class Book implements Parcelable {
     private int bookId;
     private String bookName;

     public int getBookId() {
 	return bookId;
     }

     public void setBookId(int bookId) {
 	this.bookId = bookId;
     }

     public String getBookName() {
 	return bookName;
     }

     public void setBookName(String bookName) {
 	this.bookName = bookName;
     }


     public Book(int bookId, String bookName) {
 	this.bookId = bookId;
 	this.bookName = bookName;
     }

     protected Book(Parcel in) {
 	bookId = in.readInt();
 	bookName = in.readString();
     }


     @Override
     public void writeToParcel(Parcel dest, int flags) {
 	dest.writeInt(bookId);
 	dest.writeString(bookName);
     }

     public static final Creator<Book> CREATOR = new Creator<Book>() {
 	@Override
 	public Book createFromParcel(Parcel in) {
 	    return new Book(in);
 	}

 	@Override
 	public Book[] newArray(int size) {
 	    return new Book[size];
 	}
     };

     @Override
     public int describeContents() {
 	return 0;
     }

}

然后为这个类单独建立一个aidl文件, 并使用parcelable关键字进行定义

//Book.aidl
package com.example.aidl.aidl;
parcelable Book;

在IMyAidlInterface.aidl中使用Book类型

// IMyAidlInterface.aidl
package com.example.aidl.aidl;
import com.example.aidl.aidl.Book;

interface IMyAidlInterface {

    void addBook(in Book book);

    List<Book> getBookList();
}
  1. 服务端实现AIDL接口

应用程序编译时会生成以.aidl文件命名的 .java 接口文件。生成的接口包含一个名为 Stub 的子类(例如,IMyAidlInterface.Stub),该子类是其父接口的抽象实现,并且会声明.aidl文件中的所有方法。

实现.aidl生成的接口,如下:

//AidlService.kt
package com.example.aidl.server

import android.app.Service
import android.content.Intent
import android.os.RemoteException
import java.util.*

class AidlService : Service() {

     private val list: MutableList<Book> = ArrayList()

     private val mStub: IMyAidlInterface.Stub = object : IMyAidlInterface.Stub() {

 	@Throws(RemoteException::class)
 	override fun addBook(book: Book) {
 	    list.add(book)
 	}

 	@Throws(RemoteException::class)
 	override fun getBookList(): List<Book> {
 	    return list
 	}
     }

     override fun onBind(intent: Intent): IBinder {
 	return mStub
     }
}
  1. 客户端绑定服务,调用IPC方法
  • 在项目的src目录中加入.aidl文件
  • 声明一个IMyAidlInterface接口实例(基于AIDL生成)
  • 创建ServiceConnection实例,实现android.content.ServiceConnection接口
  • 调用Context.bindService()绑定服务,传入ServiceConnection实例
  • 在onServiceConnected()实现中,调用IMyAidlInterface.Stub.asInterface(binder),将返回参数转换为IMyAidlInterface类型
  • 调用在接口上定义的方法
//MainActivity.kt
class MainActivity : AppCompatActivity() {

       private var mStub: IMyAidlInterface? = null

       private val serviceConnection = object : ServiceConnection {
    	   override fun onServiceConnected(name: ComponentName, binder: IBinder) {
  	      mStub = IMyAidlInterface.Stub.asInterface(binder)
            }

           override fun onServiceDisconnected(name: ComponentName) {
  	     mStub = null
           }
       }

       override fun onCreate(savedInstanceState: Bundle?) {
    	 super.onCreate(savedInstanceState)
    	 setContentView(R.layout.activity_main)
   	 button1.setOnClickListener {
    	     bindService()
           }
       }

       private fun bindService() {
  	 if (mStub != null) {
  	    return
  	 }
  	 val intent = Intent("com.example.aidl.server.AidlService")
  	 intent.setClassName("com.example.aidl.server","com.example.aidl.server.AidlService")

  	 try {
  	     val bindSucc = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
  	     if (bindSucc) {
  		 Toast.makeText(this, "bind ok", Toast.LENGTH_SHORT).show()
  	     } else {
  		 Toast.makeText(this, "bind fail", Toast.LENGTH_SHORT).show()
  	    }
  	 } catch (e: Exception) {
  	     e.printStackTrace()
  	 }
       }

       override fun onDestroy() {
  	 if(mStub!=null) {
             unbindService(serviceConnection)
  	 }
  	 super.onDestroy()
       }
 }