AIDL服务调用简单实践

本文通过一个简单的DEMO介绍了AIDL在Android中的应用,详细阐述了如何创建和关闭远程服务、绑定跨进程服务以及客户端如何进行远程调用。通过AIDL定义接口,服务端实现并暴露,客户端调用并转换接口类型,实现了进程间的通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近在看AMS中的源码,发现原理是AIDL进行IPC通讯,特此将基础回顾下,编写了一个简单的DEMO,方便理解。

客户端开启和关闭远程服务

创建两个App

  • ServiceApp:包含远程服务
  • ClientApp:调用远程服务

ServiceApp

  • 创建RemoteAppService服务
public class RemoteAppService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("RemoteAppService onCreate....");
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("RemoteAppService onDestroy....");
    }
}
  • 注册服务
<service  
	android:name="com.martin.lib.ipc.remote.RemoteAppService"
	android:enabled="true"
	android:exported="true"
/>

ClientApp

  • 调用ServiceApp的RemoteAppService服务
/**
* 包名为应用程序的报名
*/
private static final String PKG = "com.optimize.lib.ipc";
/**
* 需要启动的服务的全路径名称
*/
private static final String CLS = "com.martin.lib.ipc.remote.RemoteAppService";
Intent intent = new Intent();
intent.setComponent(new ComponentName(PKG,CLS));
findViewById(R.id.open_btn).setOnClickListener(v -> {
    startService(intent);
});
findViewById(R.id.close_btn).setOnClickListener(v -> {
    stopService(intent);
});

远程服务调用在5.0以后,需要使用显示调用。

  • 查看日志
    在这里插入图片描述

绑定跨进程服务

  • bindService:绑定服务
  • unbindService:解绑服务
ClientApp
   findViewById(R.id.bindRemoteServiceBtn).setOnClickListener(v -> {
            bindService(intent,this, Service.BIND_AUTO_CREATE);
        });
        findViewById(R.id.unBindRemoteServiceBtn).setOnClickListener(v -> {
            unbindService(this);
        });
  • 查看日志
    在这里插入图片描述
AIDL

AIDL是Android中编写服务向外暴露接口的一种描述语言,服务在外提供接口时需要使用AIDL将接口编写,Android会自动将AIDL文件转换为Java文件,若客户端需要进行接口调用,只需拷贝远程的AIDL文件生成Java代码后使用即可。

ServiceApp
  • 定义IRemoteServiceBinder的AIDL文件
// IRemoteServiceBinder.aidl
package com.optimize.lib.ipc;

// Declare any non-default types here with import statements

// IRemoteServiceBinder.aidl
package com.optimize.lib.ipc;

// Declare any non-default types here with import statements

interface IRemoteServiceBinder {
    /**
      * 远程登录
      */
    boolean login(String user,String password);
}


  • 在使用Service中使用,定义的AIDL生成的Java类,并在onBind中进行回传。
public class RemoteAppService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
       return new IRemoteServiceBinder.Stub() {

            @Override
            public boolean login(String data) throws RemoteException {
                System.out.println("user:"+user+",password"+password);
            }
        };
    }
}
ClientApp进行远程调用
  • 创建AIDL文件夹,将将远程的AIDL文件进行复制到aidl文件夹中,注意文件名称和报名路径必须和ServiceApp完全相同。

在这里插入图片描述

  • 代码中进行赋值和调用
IRemoteServiceBinder binder = null;

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //这里不能做强制类型的转换,因为他们的内存地址是不一样的,所以修改一下. binder = (IRemoteServiceBinder) service;
        //正确写法
        binder = IRemoteServiceBinder.Stub.asInterface(service);
    }

注意,虽然拷贝了相同的文件,但是他们在内存中的地址是不一样的,所以不能进行强转,此时我们需要IRemoteServiceBinder.Stub.asInterface(service);方法来进行类型转换。

  • 调用
findViewById(R.id.syncDataBtn).setOnClickListener(v -> {
            if (binder != null) {
                try {
                    EditText userNameEdt = findViewById(R.id.userNameEdt);
                    EditText passwordEdt = findViewById(R.id.passwordEdt);
                    boolean isSuccess = binder.login(userNameEdt.getText().toString(),
                            passwordEdt.getText().toString());
                    if (isSuccess){
                        System.out.println("login success");
                    }else {
                        System.out.println("login failure");
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
  • 查看结果
    在这里插入图片描述

参考文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值