Android --- AIDL 的理解


AIDL 的全称是 Android Interface Definition Language(安卓接口定义语言)
下面三四是重点,一二五给大家作为补充

一、同应用启动 Service

 startService(new Intent(this,AppService.class));

二、跨应用启动 Service

Intent serviceIntent = new Intent();
serviceIntent.setComponent(new ComponentName("com.example.test", "com.example.test.BookManagerService"));
startService(serviceIntent);

ComponentName 的两个参数:第一个参数是另外一个应用的包名,第二个参数是另外一个应用的Service 所在的位置

还有,被启动的Service需要在所在的项目的AndroidManifest.xml中声明Service权限,exporter的属性为true,否则不能跨应用启动

三、跨应用绑定 Service

private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            System.out.println("----服务已绑定");
            IBookManager iBookManager = IBookManager.Stub.asInterface(iBinder);
            try {
                List<Book> list = iBookManager.getBookList();
                Log.i("书的信息:", list.toString());
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            System.out.println("service disconnected");
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_01 = findViewById(R.id.btn_01);
        System.out.println("__________________client-------------------------");
        btn_01.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.setComponent(new ComponentName("com.example.test", "com.example.test.BookManagerService"));
                bindService(intent, connection, Context.BIND_AUTO_CREATE);
            }
        });
    }

四、AIDL 的通信流程

一、服务端
1.服务端首先要创建一个 Service 用来监听客户端的连接请求
2.然后创建一个 AIDL 文件,将暴露给客户端的接口在这个 AIDL 文件中声明
3.最后在 Service 中实现这个 AIDL 接口即可。

二、客户端
首先需要绑定服务端 Service(建立连接 ServiceConnection),绑定成功后,将服务端返回的 Binder 对象转成所属的类型,接着就可以调用 AIDL 中的方法了。

== AppA是服务端,AppB是客户端,AppA使用aidl传递身高数据给AppB的代码示例==

首先,我们需要定义一个AIDL接口,用于在AppA和AppB之间传递身高数据。
在AppA中的AIDL文件(例如,IServerInterface.aidl):

// 定义一个包含获取身高数据方法的接口
interface IServerInterface {
    // 获取身高数据的方法
    float getHeight();
}

然后,在AppA中创建一个Service,并实现这个AIDL接口:

public class HeightService extends Service {

    // 实现AIDL接口
    private final IServerInterface.Stub mBinder = new IServerInterface.Stub() {
        @Override
        public float getHeight() throws RemoteException {
            // 在这里返回身高数据,这里只是一个简单的示例,实际情况可能需要从数据库或其他地方获取数据
            return 180.5f; // 假设身高是180.5厘米
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        // 返回实现了AIDL接口的Binder对象
        return mBinder;
    }
}

在AndroidManifest.xml中注册Service:

<service android:name=".HeightService">
    <intent-filter>
        <action android:name="com.example.appa.IServerInterface"/>
    </intent-filter>
</service>

接下来,在AppB中需要使用AIDL接口来获取身高数据。首先,需要在AppB中创建一个与AppA相同的AIDL文件:

// 在AppB中创建与AppA相同的AIDL文件,以便能够调用AppA中的接口

然后,在AppB中创建一个与AIDL接口匹配的ServiceConnection,以连接到AppA中的Service,并通过AIDL接口获取身高数据:

public class HeightServiceConnection implements ServiceConnection {

    // AIDL接口实例
    private IServerInterface heightService;

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        // 获取AIDL接口实例
        heightService = IServerInterface.Stub.asInterface(service);

        try {
            // 调用AppA中的方法获取身高数据
            float height = heightService.getHeight();
            // 处理获取到的身高数据,这里只是一个简单的示例
            Log.d("AppB", "Height received from AppA: " + height + " cm");
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        // 断开连接时的处理
        heightService = null;
    }
}

最后,在AppB中启动Service,并绑定到AppA中的Service:

// 启动Service,并绑定到AppA中的Service
HeightServiceConnection connection = new HeightServiceConnection();
Intent intent = new Intent("com.example.appa.IServerInterface");
intent.setPackage("com.example.appa"); // AppA的包名
bindService(intent, connection, Context.BIND_AUTO_CREATE);

记得在不需要使用Service时解绑:

unbindService(connection);

通过这样的方式,AppB就可以通过AIDL接口与AppA通信,并获取AppA提供的身高数据。

五、startService()和bindService()区别

1.执行startService时,Service会经历onCreate->onStartCommand
当执行stopService时,直接调用onDestroy方法。调用者如果没有stopService,Service会一直在后台运行,下次调用者再起来仍然可以stopService。

2.执行bindService时,Service会经历onCreate->onBind。这个时候调用者和Service绑定在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了),Service就会调用onUnbind->onDestroy。这里所谓的绑定在一起就是说两者共存亡了。

3.多次调用startService,该Service只能被创建一次,即该Service的onCreate方法只会被调用一次。但是每次调用startService,onStartCommand方法都会被调用。Service的onStart方法在API 5时被废弃,替代它的是onStartCommand方法。

4.第一次执行bindService时,onCreate和onBind方法会被调用,但是多次执行bindService时,onCreate和onBind方法并不会被多次调用,即并不会多次创建服务和绑定服务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梁同学与Android

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值