android进阶-AIDL

参考:Android进阶------AIDL详解_android aidl-CSDN博客

AIDL(Android 接口定义语言),可以使用它定义客户端与服务端进程间通信(IPC)的编程接口,在 Android 中,进程之间无法共享内存(用户空间),不同进程之间的通信一般使用 AIDL 来处理。

使用流程:

在 .aidl 文件中定义 AIDL 接口,并将其添加到应用工程的 src 目录下,创建完成之后 rebuil

Android SDK 工具会自动生成基于该 .aidl 文件的 IBinder 接口,具体的业务对象实现这个接口,这个具体的业务对象也是 IBinder 对象,当绑定服务的时候会根据实际情况返回具体的通信对象(本地还是代理)

将客户端绑定到该服务上,之后就可以调用 IBinder 中的方法来进行进程间通信(IPC)实际起作用的并不是AIDL文件,而是据此而生成的一个IInterface的实例代码,AIDL其实是为了避免我们重复编写代码而出现的一个模板

在实现AIDL的过程中服务端APP和客户端APP中要包含结构完全相同的AIDL接口文件,包括AIDL接口所在的包名及包路径要完全一样,否则就会报错,这是因为客户端需要反序列化服务端中所有和AIDL相关的类,如果类的完整路径不一致就无法反序列化成功。

小技巧:为了更加方便的创建AIDL文件,我们可以新建一个lib工程,让客户端APP和服务端APP同时依赖这个lib,这样只需要在这个lib工程中添加AIDL文件就可以了!

如果不需要跨不同程序,使用Binder来创建接口,如果不需要处理多线程,使用Messenger来处理,使用AIDL务必理解绑定服务。

抽象类stub,其继承了android.os.Binder、实现IaidlData接口故,我们实际需要实现的是Stub抽象类。

package com.yqw.servicedemo;

import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

import android.os.RemoteException;

import com.yqw.mylibrary.IMyAidlInterface;

public class MyService extends Service {

public static final String TAG = "MyService";

public MyService() {

}

@Override

public IBinder onBind(Intent intent) {

// Return the communication channel to the service.

return binder;

}

private IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {

@Override

public int borrowBook(String bookName) throws RemoteException {

//TODO 实现一系列 借书 的逻辑后,返回结果码,比如:0为失败,1为成功

return 1;

}

@Override

public int returnBook(String bookName) throws RemoteException {

//TODO 实现一系列 还书 的逻辑后,返回结果码,比如:0为失败,1为成功

return 1;

}

};

}


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/you943047219/article/details/109493490

package com.yqw.aidldemo;

import android.content.ComponentName;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle;

import android.os.IBinder;

import android.os.RemoteException;

import android.util.Log;

import android.view.View;

import android.widget.Toast;

import com.yqw.mylibrary.IMyAidlInterface;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

private String TAG = "MainActivity>>";

private IMyAidlInterface iMyAidlInterface;

private boolean isConnected = false;//是否连接服务

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

@Override

protected void onStart() {

super.onStart();

if (!isConnected) {

mBindService();

}

}

@Override

protected void onStop() {

super.onStop();

if (isConnected) {

unbindService(mServiceConnection);

isConnected = false;

}

}

private void mBindService() {

Intent intent = new Intent();

intent.setAction("com.yqw.servicedemo.MyService");

intent.setPackage("com.yqw.servicedemo");

bindService(intent, mServiceConnection, BIND_AUTO_CREATE);

}

private final ServiceConnection mServiceConnection = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName componentName, IBinder iBinder) {

Log.d(TAG, "onServiceConnected");

//获得 aidl定义的接口持有类

iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);

isConnected = true;

}

@Override

public void onServiceDisconnected(ComponentName componentName) {

Log.d(TAG, "onServiceDisconnected");

isConnected = false;

}

};

private void showToast(String str) {

Toast.makeText(this, str, Toast.LENGTH_SHORT).show();

}

public void borrowBook(View view) {

if (!isConnected) {

showToast("未连接服务");

return;

}

try {

int resultCode = iMyAidlInterface.borrowBook("流浪地球");

showToast(resultCode == 1 ? "借书成功" : "借书失败");

} catch (RemoteException e) {

e.printStackTrace();

}

}

public void returnBook(View view) {

if (!isConnected) {

showToast("未连接服务");

return;

}

try {

int resultCode = iMyAidlInterface.returnBook("流浪地球");

showToast(resultCode == 1 ? "还书成功" : "还书失败");

} catch (RemoteException e) {

e.printStackTrace();

}

}

}

AIDL支持实体类,但必须是实现了Parcelable接口,支持序列化。

  1. // Book.aidl

  2. package com.yqw.mylibrary;

  3. parcelable Book;

package com.yqw.mylibrary;

public class Book {

String name;

int num;

public Book(String name, int num) {

this.name = name;

this.num = num;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getNum() {

return num;

}

public void setNum(int num) {

this.num = num;

}

}

然后实现 Parcelable接口,按Alt+Enter自动补充好需要的代码

package com.yqw.mylibrary;

import android.os.Parcel;

import android.os.Parcelable;

public class Book implements Parcelable {

String name;

int num;

public Book(String name, int num) {

this.name = name;

this.num = num;

}

protected Book(Parcel in) {

name = in.readString();

num = in.readInt();

}

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;

}

public int getNum() {

return num;

}

public void setNum(int num) {

this.num = num;

}

@Override

public int describeContents() {

return 0;

}

@Override

public void writeToParcel(Parcel dest, int flags) {

dest.writeString(name);

dest.writeInt(num);

}

}

// IMyAidlInterface.aidl

package com.yqw.mylibrary;

import com.yqw.mylibrary.Book;

interface IMyAidlInterface {

int borrowBook(String bookName);

int returnBook(String bookName);

List<Book> getBookList();

}

然后调用:

public void getBooksNum(View view) {

checkConnected();

try {

int booksNum = iMyAidlInterface.getBookList().size();

showToast("剩余图书数量:" + booksNum);

} catch (RemoteException e) {

e.printStackTrace();

}

}

相关推荐
zhangphil21 分钟前
Android简洁缩放Matrix实现图像马赛克,Kotlin
android·kotlin
m0_5127446421 分钟前
极客大挑战2024-web-wp(详细)
android·前端
lw向北.38 分钟前
Qt For Android之环境搭建(Qt 5.12.11 Qt下载SDK的处理方案)
android·开发语言·qt
不爱学习的啊Biao1 小时前
【13】MySQL如何选择合适的索引?
android·数据库·mysql
Clockwiseee1 小时前
PHP伪协议总结
android·开发语言·php
mmsx8 小时前
android sqlite 数据库简单封装示例(java)
android·java·数据库
众拾达人11 小时前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
吃着火锅x唱着歌11 小时前
PHP7内核剖析 学习笔记 第四章 内存管理(1)
android·笔记·学习
_Shirley13 小时前
鸿蒙设置app更新跳转华为市场
android·华为·kotlin·harmonyos·鸿蒙
hedalei15 小时前
RK3576 Android14编译OTA包提示java.lang.UnsupportedClassVersionError问题
android·android14·rk3576