Android AIDL的使用

AIDL(Android Interface Definition Language):Android接口定义语言。用来实现Android进程间通信(IPC),通俗点说就是一个APP可以被另一个APP调用,该APP向另一个APP提供数据。

官方文档(感兴趣的可以看看)

使用步骤(这里使用的是Android Studio)

第一步 在服务端定义一个AIDL接口

在一个.aidl文件中使用java编程语言语法定义你的AIDL接口,然后在提供service的应用中和任何绑定到这个service的应用中的源代码中(在src目录下)保存它
1、创建一个Service文件RemoteService。
在这里插入图片描述
在AndroidManifest配置文件中配置该Service的action标签:
在这里插入图片描述
2、创建指定Service对应的.aidl文件
AIDL文件要和Service的包名一致。选中要提供的服务类,右键 -> New -> AIDL -> AIDL File文件,如图所示在main文件夹下的aidl文件夹下创建了一个名为RemoteInterface.aidl的文件,Service和该AIDL文件的包名也是一样的,
在这里插入图片描述在这里插入图片描述
3、在该.aid文件下添加AIDL的方法。
默认情况下,AIDL 支持下列数据类型:

  1. Java 编程语言中的所有原语类型(如 int、long、char、boolean 等等)
  2. String
  3. CharSequence
  4. List
    List 中的所有元素都必须是以上列表中支持的数据类型、其他 AIDL 生成的接口或您声明的可打包类型。 可选择将 List 用作“通用”类(例如,List)。另一端实际接收的具体类始终是 ArrayList,但生成的方法使用的是 List 接口。
  5. Map
    Map 中的所有元素都必须是以上列表中支持的数据类型、其他 AIDL 生成的接口或您声明的可打包类型。 不支持通用 Map(如 Map<String,Integer> 形式的 Map)。 另一端实际接收的具体类始终是 HashMap,但生成的方法使用的是 Map 接口。

定义服务接口时,请注意:
方法可带零个或多个参数,返回值或空值。
所有非原语参数都需要指示数据走向的方向标记。可以是 in、out 或 inout(见以下示例)。
原语默认为 in,不能是其他方向。

注意:您应该将方向限定为真正需要的方向,因为编组参数的开销极大。

.aidl 文件中包括的所有代码注释都包含在生成的 IBinder 接口中(import 和 package 语句之前的注释除外)
只支持方法;您不能公开 AIDL 中的静态字段。
在这里插入图片描述
5、重新编译一下项目,如果成功编译那么会生成一个名为RemoteInterface.java的接口文件,并且声明了.aidl中所有的方法,该文件中还有一个名为Stub的抽象静态内部类,继承RemoteInterface接口继承Binder类。
6、向客户端公开该接口
要为您的服务公开该接口,请扩展第一步中的 Service 并实现 onBind(),并返回一个Stub类实例。

public class RemoteService extends Service {
    public RemoteService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Return the interface
        return mBinder;
    }

    private final RemoteInterface.Stub mBinder = new RemoteInterface.Stub() {

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }
		
        @Override
        public void setString(String str) throws RemoteException {
        }

        @Override
        public String getString() throws RemoteException {
			return "成功调用远程服务";
        }
    };
}

现在,当客户端(如 Activity)调用 bindService() 以连接此服务时,客户端的 onServiceConnected() 回调方法会接收该服务 onBind() 方法返回的 mBinder 实例。

第二步 在客户端调用接口

1、在客户端的aidl文件夹下面要有和服务端相同目录结构的.aidl文件。一般我们直接从服务端拷贝过来即可,然后Rebuild Project,结束后会生成和服务端一模一样的接口文件本例中为RemoteInterface.java。
2、调用服务端暴露的方法


public class MainActivity extends AppCompatActivity {
    private Button btCallAIDL;
    private RemoteInterface aidlService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btCallAIDL = (Button) findViewById(R.id.bt_call_aidl);
        // 点击按钮绑定服务端的服务
        btCallAIDL.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.dtcdkl.aidlservice.remote"); // 参数为服务端的Service的action的name参数的值
                intent.setPackage("com.dtcdkl.aidlservice"); // 参数为服务端的包名
                bindService(intent, new MyConnection(), BIND_AUTO_CREATE);// 绑定Service
            }
        });
    }

    private class MyConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            aidlService = RemoteInterface.Stub.asInterface(service);// 获得服务端的RemoteInterface的对象。
            try {
                String str = aidlService.getString();// 调用服务端暴露的方法
                Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }
}

Android AIDLAndroid Interface Definition Language)是一种用于定义客户端和服务之间通信接口的语言。AIDL 是一个 Android 特有的 RPC(远程过程调用)机制。 下面是使用 AIDL 的基本步骤: 1. 定义 AIDL 接口 在服务端创建一个 AIDL 文件,定义服务的接口方法。例如,创建一个名为 IMyService.aidl 的文件,其中包含以下内容: ``` interface IMyService { void sayHello(); } ``` 2. 实现 AIDL 接口 在服务端实现 AIDL 接口,例如: ``` public class MyService extends Service { private final IMyService.Stub binder = new IMyService.Stub() { @Override public void sayHello() throws RemoteException { Log.i("MyService", "Hello World"); } }; @Nullable @Override public IBinder onBind(Intent intent) { return binder; } } ``` 3. 绑定服务 在客户端绑定服务,例如: ``` private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { IMyService myService = IMyService.Stub.asInterface(service); try { myService.sayHello(); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; private void bindService() { Intent intent = new Intent(this, MyService.class); bindService(intent, connection, Context.BIND_AUTO_CREATE); } ``` 通过上述步骤,就可以实现客户端与服务端之间的通信。需要注意的是,AIDL 接口中定义的方法必须是可序列化的。如果方法参数或返回值类型不支持序列化,可以通过 Parcelable 接口实现序列化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值