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();

}

}

相关推荐
鸿蒙布道师5 小时前
鸿蒙NEXT开发Base64工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
jiet_h6 小时前
Android adb 的功能和用法
android·adb
美狐美颜sdk6 小时前
美颜SDK兼容性挑战:如何让美颜滤镜API适配iOS与安卓?
android·深度学习·ios·美颜sdk·第三方美颜sdk·视频美颜sdk
居然是阿宋6 小时前
深入理解 YUV 颜色空间:从原理到 Android 视频渲染
android·音视频
KevinWang_7 小时前
DialogFragment 不适合复用
android
古鸽100868 小时前
Audio Hal 介绍
android
小叶不焦虑9 小时前
关于 Android 系统回收站的实现
android
木西9 小时前
从0到1搭建一个RN应用从开发测试到上架全流程
android·前端·react native
小橙子207710 小时前
一条命令配置移动端(Android / iOS)自动化环境
android·ios·自动化
和煦的春风10 小时前
案例分析 | SurfaceFlinger Binder RT 被降级到CFS
android