这篇文章主要介绍Android中AIDL怎么用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
AIDL,即Android Interface Definition Language,Android接口定义语言。这门语言是为了实现进程间通信。每一个进程都有自己的一块独立的内存,都在自己的内存上存储自己的数据,执行自己的操作,每个进程之间你不知我,我不知你,而AIDL,就是两个进程之间沟通的桥梁。
AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写,对于小白来说,AIDL的作用是让你可以在自己的APP里绑定一个其他APP的service,这样你的APP可以和其他APP交互。
aidl文件支持的数据类型包括:
八种基本数据类型:byte、char、short、int、long、float、double、boolean
String、CharSequence
实现了Parcelable接口的数据类型
List类型。List承载的数据必须是AIDL支持的类型,或者是其他声明的AIDL对象
Map类型。Map承载的数据必须是AIDL支持的类型,或者是其他声明的AIDL对象
在使用其他声明的AIDL对象的时候必须要导包,即使要使用的AIDL对象文件和当前正在编辑的aidl文件在同一个文件夹下。
aidl文件可以分为两类,一类用来声明实现了Parcelable接口的数据类型,以供其他AIDL文件使用那些非默认支持的数据类型。还有一类是用来定义接口方法,声明要暴露哪些接口给客户端调用。
AIDL的具体使用步骤是:
1、如果aidl文件中涉及到实现了Parcelable接口的数据类型,则先将该aidl文件定义出来。在src文件夹下右键,选择新建aidl文件,这里新建了一个Book.aidl文件。
新建完以后,会在main文件下生成一个aidl的文件夹,aidl文件夹下的目录结构和java文件夹下的目录结构一样。
Book.aidl文件中会有一个默认方法。
我们删除掉这个默认方法,只声明一个parcelable数据类型,这个文件就成为声明Parcelable数据类型的AIDL文件。注意这里的parcelable中的p是小写的。
2、这个时候我们来定义Book类并实现Parcelable接口,注意Book类在java文件夹下的目录与Book.aidl文件在aidl文件夹下的目录保持一致。
public class Book implements Parcelable { private String name; public Book(String name) { this.name=name; } protected Book(Parcel in) { this.name = in.readString(); } 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]; } }; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); } /** * 这个方法是自己写上去的,并不是根据错误提示自动生成的代码 * 默认生成的模板类的对象只支持为in的定向tag。因为默认生成的类里面只有 writeToParcel() 方法。 * 而如果要支持为out或者inout的定向tag的话,还需要实现readFromParcel()方法。 * 而这个方法其实并没有在 Parcelable 接口里面,所以需要我们从头写。 */ public void readFromParcel(Parcel dest){ name=dest.readString(); } }
这里需要注意的一点是如果要支持为out或inout的定向tag的话,需要我们手写readFromParcel()方法。
3、然后我们开始写BookController.aidl文件来定义能被客户端调用的接口。
package com.example.service; import com.example.service.Book; // Declare any non-default types here with import statements interface BookController { int getInt();//int类型 String getString();//String类型 List<Book> getBookList();//aidl对象 void addBook(inout Book book);//aidl对象 }
这里需要注意的是,虽然Book.aidl文件和BookController.aidl文件在同一个包下,还是需要手动导入一下。
4、至此,我们的aidl文件写完了,然后我们Rebuild project,系统会帮我们生成一个与AIDL文件同名的java文件,这个java文件才是与我们跨进程通信密切相关的东西。
5、定义一个Service,通过这个Service将接口暴露给外部。
public class AIDLService extends Service { private List<Book> bookList; public AIDLService() { } @Override public void onCreate() { super.onCreate(); bookList = new ArrayList<>(); initData(); } private void initData() { Book book1 = new Book("花千骨"); Book book2 = new Book("公主小妹"); Book book3 = new Book("仙剑奇侠传"); Book book4 = new Book("飘"); Book book5 = new Book("茶花女"); Book book6 = new Book("解忧杂货铺"); Book book7 = new Book("活着"); Book book8 = new Book("三生三世十里桃花"); bookList.add(book1); bookList.add(book2); bookList.add(book3); bookList.add(book4); bookList.add(book5); bookList.add(book6); bookList.add(book7); bookList.add(book8); } private final BookController.Stub stub = new BookController.Stub() { @Override public int getInt() throws RemoteException { return bookList == null ? 0 : bookList.size(); } @Override public String getString() throws RemoteException { return bookList == null ? "" : bookList.get(0).getName(); } @Override public List<Book> getBookList() throws RemoteException { return bookList; } @Override public void addBook(Book book) throws RemoteException { if (book != null) { bookList.add(book); } else { Log.i("ruxing", "接收到了一个空对象 Inout"); } } }; @Nullable @Override public IBinder onBind(Intent intent) { return stub; } }
6、在清单文件中注册服务。
<service android:name=".AIDLService" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.example.service.action"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </service>
至此,服务端开发完成了。
1、新建一个custom工程,把服务端的aidl文件夹下的内容全部拷贝到新项目中,如果aidl中有用到bean实体类,把实体类也拷贝过来,然后Rebuild Project。
2、在客户端的activity中连接远程服务,实现aidl通信。
public class MainActivity extends AppCompatActivity { private BookController bookController; private boolean connected; private List<Book> bookList; private Button mBtnGetBookList; private Button mBtnAddBook; private Button mBtnGetBookSize; private Button mBtnGetFirstBookName; private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { bookController = BookController.Stub.asInterface(service); connected = true; } @Override public void onServiceDisconnected(ComponentName name) { bookController = null; connected = false; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtnGetBookList = findViewById(R.id.btn_get_book_list); mBtnAddBook = findViewById(R.id.btn_add); mBtnGetBookSize = findViewById(R.id.btn_get_book_size); mBtnGetFirstBookName = findViewById(R.id.btn_first_book_name); mBtnGetBookList.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (connected) { try { bookList = bookController.getBookList(); for (int i = 0; i < bookList.size(); i++) { Log.i("ruxing", "name=" + bookList.get(i).getName()); } } catch (RemoteException e) { e.printStackTrace(); } } } }); mBtnAddBook.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (connected) { Book book = new Book("新书"); try { bookController.addBook(book); Log.i("ruxing", "向服务器添加了一本新书==="+book.getName()); } catch (RemoteException e) { e.printStackTrace(); } } } }); mBtnGetBookSize.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (connected) { try { int size = 0; size = bookController.getInt(); Log.i("ruxing", "共有" + size + "本书"); } catch (RemoteException e) { e.printStackTrace(); } } } }); mBtnGetFirstBookName.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (connected) { try { String name = bookController.getString(); Log.i("ruxing", "第一本书的书名是:" + name); } catch (RemoteException e) { e.printStackTrace(); } } } }); Intent intent = new Intent(); intent.setPackage("com.example.service"); intent.setAction("com.example.service.action"); bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); if (connected) { unbindService(serviceConnection); } } }
以上是“Android中AIDL怎么用”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。