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

}

}

相关推荐
李新_26 分钟前
Android 画中画避坑指北
android
一一Null1 小时前
Android studio—socketIO库return与emit的使用
android·java·网络·ide·websocket·网络协议·android studio
ansondroider2 小时前
Android RK356X TVSettings USB调试开关
android·adb·usb·otg·rk356x
全栈极简2 小时前
Android串口通信
android
jiaxingcode2 小时前
MAC系统下完全卸载Android Studio
android·macos·android studio
张力尹2 小时前
「架构篇 1」认识 MVC / MVP / MVVM / MVI
android·面试·架构
张力尹3 小时前
「架构篇 2」认识 MVC / MVP / MVVM / MVI
android·面试·架构
不穿铠甲的穿山甲3 小时前
Android-KeyStore安全的存储系统
android·安全
dora4 小时前
Flutter的屏幕适配
android·flutter