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 Booksize;

}

};

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 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台5 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone5 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc6 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo8 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077008 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼9 小时前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone10 小时前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen10 小时前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone10 小时前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui