前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android | IPC 之 AIDL实践

Android | IPC 之 AIDL实践

作者头像
凌川江雪
发布2020-04-01 17:45:12
4580
发布2020-04-01 17:45:12
举报
文章被收录于专栏:李蔚蓬的专栏李蔚蓬的专栏

项目GitHub地址

Service基础回顾

  • 主要要用到的就是启动Service和绑定Service两种方式, 大概的流程这里就不赘述了, 可以参考一下这篇博文:学习笔记| AS入门(十) 组件篇之Service
  • 这里主要强调几点:
    • startServicebindService都可以启动服务, 但是其影响Service的生命周期不同, 而且bindService可以是Activity能同Service交互通信, 监控Service任务的情况;
    • startServicebindService两种方式都调用之后, 必须同时使用stopServiceunbindService 才能销毁服务;
    • 换句话说, startService被调用之后,如果没有调用stopService 则无论调用多少次bindServiceunbindService 都无法销毁服务;

IPC实战

跨进程启动服务

现在我们看一下这两个实战项目, 一个AIDLTest项目 还有一个AIDLDemo项目 AIDLTest项目可以 单独用于测试同一个进程内的Service基础运作, 当然这里咱们要表演一个IPC(进程间通信)过程, 即, AIDLDemo项目中, 访问到AIDLTest项目MyService 【即跨APP、跨进程通信访问】 下面是AIDLTest项目AndroidManifest 我们给MyService一个action标签 以及记下来AIDLTest项目的包名,待会儿需要用到!

AIDLTest项目的MyService代码:

代码语言:javascript
复制
public class MyService extends Service {
    ....
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("MyService","服务创建了");
...
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("MyService","服务启动了");
        return super.onStartCommand(intent, flags, startId);
    }
...
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("MyService","服务绑定了");
        return mb;
    }
    ...

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("MyService","服务解绑了");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("MyService","服务销毁了");

    }
}

AIDLDemo项目中, 指定访问我们刚刚提到的AIDLTest项目的包名 以及MyService的action标签

  • 成了,先运行AIDLTest项目【提供Service方】, 再运行AIDLDemo项目【访问方】, AIDLDemo项目中点击按钮,观察logcat, 可以看到我们在AIDLDemo项目中操作的时候, 成功跨进程开启了另外一个进程APP【AIDLTest】的Service了!!!

跨进程绑定服务

AIDL实战开始!!

  • 以上的方式只能做到跨进程开启、绑定服务, 但是无法进行通信,监控另一个进程的进度; 所以这里就要使用AIDL了!
  • AIDL是作为 两个进程间 数据共享的接口!
一般性步骤
  • 创建aidl文件, 【aidl文件用于定义进程间的接口, 进程两端的文件要保持一致】;
  • 创建好了AIDL文件之后, build一下会自动生成java文件;
  • 使用AIDL;

  • 1/3 创建aidl文件, 服务提供方先创建,即 AIDLTest项目 在对应的包处 new 一下就好了:

在弹出的窗口处点击Finish后,成功创建, 项目会自动生成一个包:

【刚刚是右键aidltest包创建的AIDL文件, 所以这里生成的包跟aidltest包的完整包名是一致的】 初始生成的AIDL文件 —— IMyAidlInterface.aidl:

代码语言:javascript
复制
// IMyAidlInterface.aidl
package com.lwp.aidltest;

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

interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}
  • 添加自定义的业务方法【需要提供给其他进程使用的业务】:
代码语言:javascript
复制
...
interface IMyAidlInterface {
    ...
            
    //定义自己所需要的方法:显示当前服务的进度
    void showProgress();        
}
  • 2/3 build一下项目: 可以看到项目build/generated/下生成了aidl相关的包 (generated包表示该包下放着的都是自动生成的代码), 展开之后可以看到自动生成的java文件

注意这里生成的是java文件 我们刚刚自定义的文件是aidl文件,并不能直接使用 稍微浏览一下生成的java文件, 可以看到它首先定义了一个静态抽象类Stub!!!!!!!!! Stub类 继承Binder类,表明通信作用 Binder类是实现IBinder接口的;public class Binder implements IBinder 所以Stub类也间接实现了IBinder接口)!!!!!!! 同时它实现了我们刚刚自定义的aidl文件(接口)!!!!!!!!!:

我们自定义的aidl文件中的接口方法, 在生成的这个接口中,都会有两个方法对应, 第一个是重写(override)的,第二个是重新生成的声明:

3/3 使用AIDL!!! 调用的核心,就是使用刚刚我们提到静态内部抽象类stub!!!! (即,我们最终使用的接口类,!!!!! 是AS自动生成的aidl文件接口对应的java接口类!!!!!!!!!) AIDLTest项目 中的MyServiceonBind方法中, 返回刚刚build生成aidl文件接口对应的java接口类实例 匿名内部类的形式实现业务方法!!!!!!! (非跨进程情况,这里返回的是自定义Service类 内部自定义的Binder类

下面是使用aidl接口后,

!!!!!!!!!!!!!

提供服务本线程内调用服务方法的写法!!!!!!!!!!!!!

!!!!!!!!!!!!!:

接着运行项目,

点击启动服务,接着点击绑定服务,测试成功:

接着是另外一个进程提供服务进程服务跨进程调用的写法
  • 上面说了, IPC两边的进程准备的AIDL文件都需要保持一致 所以接下来, AIDLDemo项目创建一个aidl包 aidl包创建一个包用于存放AIDL文件 这个用于存放AIDL文件的包的包名需要跟 服务提供方【AIDLTest项目】存放aidl文件的包名保持一致!!!!!! 接着把 AIDLTest项目中的AIDL文件 直接复制粘贴、覆盖到AIDLDemo项目中的aidl包下对应的包下:
  • Rebuild一下AIDLDemo项目,自动生成Java代码, 因为使用的AIDL文件跟AIDLTest项目的一样, 所以生成的文件也都是一样:
  • 接着使用AIDL接口:
  • 运行两个项目,然后在AIDLDemo项目的APP上操作, 可以看到AIDLTest项目是有对应的响应的, 即,实现跨进程调用服务方法:
  • 注意, 这里使用AIDL是可以方便生成IPC所需的接口代码, 但是其实读懂自动生成的Java接口文件, 懂得其中的IPC编程规范,要自己编写而不用AIDL文件也是可以的; AIDL文件只是方便我们自动生成代码工具 真正使用的以及实现跨进程逻辑的, 是AS根据AIDL文件自动生成Java接口文件!!!!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Service基础回顾
  • IPC实战
    • 跨进程启动服务
      • 跨进程绑定服务
      • AIDL实战开始!!
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档