专栏首页AnRFDevAndroid AIDL 了解与使用

Android AIDL 了解与使用

AIDL简介

AIDL(Android Interface Definition Language, Android 接口定义语言) 用于定义C/S体系结构中Server端可以提供的服务调用接口,框架层提供的Java系统服务接口大多由AIDL语言定义。 Android提供了AIDL工具,可将AIDL文件编译成Java文件。提高服务开发的效率

程序员可以利用AIDL自定义编程接口,在客户端和服务端之间实现进程间通信(IPC)。 在Android平台上,一个进程通常不能访问另外一个进程的内存空间,因此,Android平台将这些跨进程访问的对象分解成操作系统能够识别的简单对象。 并为跨应用访问而特殊编排和整理这些对象。用于编排和整理这些对象的代码编写起来十分冗长,所以Android的AIDL提供了相关工具来自动生成这些代码。

开发人员只需要在AIDL文件中定义Server端可以提供的服务方法,AIDL工具便可将其转化为Java文件。转化后的Java文件包含C/S体系结构的以下内容:

  • 服务接口 (IPowerManager)
  • 服务在Client端的代理(Proxy)
  • 服务存根(Stub)
  • Binder类型与IIterface类型的转换接口(asInterface 和 asBinder 方法)
  • 服务方法请求码

AIDL意义

AIDL工具建立了基于Binder的C/S体系结构的通用组件;开发者可以专注于开发服务的功能,而不需理会具体的通信结构,提高效率。

应用示例

根据上文我们可以知道,我们创建两个apk,一个作为服务提供方,一个作为AIDL服务调用方。

AIDL服务提供方代码

首先是AIDL服务提供方主要文件目录

main/aidl/
`-- com
    `-- rustfisher
        `-- ndkproj
            `-- ITomInterface.aidl // AIDL代码

main/java
`-- com
    `-- rustfisher
        |-- tom
        |   `-- TomService.java // 对应的Service

build/generated/source/aidl/
`-- debug
    `-- com
        `-- rustfisher
            `-- ndkproj
                `-- ITomInterface.java // 工程编译后AIDL生成的Java文件 提供给调用方

新建AIDL文件并写好接口

进入服务方的工程,右键新建AIDL文件ITomInterface.aidl。 文件会默认生成在main/aidl/com/rustfisher/ndkproj

// ITomInterface.aidl
package com.rustfisher.ndkproj;

// 文件名应该和接口名相同
// 编写好AIDL文件后可以先编译一次
interface ITomInterface {
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
    String helloAIDL(String name); // 此次使用的方法
}

编写服务方的接口实现代码

com.rustfisher.tom包内创建TomService.java文件;建立内部类TomServiceImpl实现接口的功能

import com.rustfisher.ndkproj.ITomInterface;

public class TomService extends Service {
    private static final String TAG = "rustApp";

    public class TomServiceImpl extends ITomInterface.Stub {

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

        }

        @Override
        public String helloAIDL(String name) throws RemoteException {
            Log.d(TAG, name + " requires helloAIDL()");
            return "Hello " + name + ", nice to meet you!";
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new TomServiceImpl(); // 绑定服务则返回 TomServiceImpl 实例
    }
}

服务方在AndroidManifest.xml文件中配置

实现了TomService类后,对此AIDL服务进行配置;在AndroidManifest.xml文件中配置

<service android:name="com.rustfisher.tom.TomService">
    <intent-filter>
        <action android:name="com.rustfisher.ndkproj.ITomInterface" />
    </intent-filter>
</service>

action里面写上AIDL文件

安装运行此apk到手机上

让服务方运行起来

AIDL调用方代码(客户端)

建立(或进入)AIDL调用方的工程,这里是aidlcaller工程。

主要文件目录

java/
`-- com
    |-- rust
    |   `-- aidlcaller
    |       `-- MainActivity.java // 演示用的
    `-- rustfisher
        `-- ndkproj // 这个路径尽量保持与服务提供方那里的一致
            `-- ITomInterface.java // 从服务方那里copy来的

有如下3个步骤:

  • 1.将AIDL服务端生成的Java文件复制到调用方工程里,尽量保持这个Java文件的路径与服务端的一致,便于识别
  • 2.写代码绑定服务,获取AIDL服务对象
  • 3.通过AIDL服务对象完成AIDL接口调用

编写调用方MainActivity.java代码

import com.rustfisher.ndkproj.ITomInterface;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "rustApp";
    ITomInterface mTomService; // AIDL 服务
    TextView mTv1;

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mTomService = ITomInterface.Stub.asInterface(service);// 获取服务对象
            mTv1.setClickable(true); // 需要等服务绑定好  再允许点击
            Log.d(TAG, "[aidlcaller] onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected " + name);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initAIDLService();
        initUI();
    }

    private void initUI() {
        mTv1 = (TextView) findViewById(R.id.tv1);
        mTv1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    String hello = mTomService.helloAIDL("Jerry");
                    Log.d(TAG, hello);
                } catch (Exception e) {
                    Log.e(TAG, "mTomService initAIDLService: Fail ", e);
                    e.printStackTrace();
                }
            }
        });
    }

    private void initAIDLService() {
        // 这个是服务提供方的AndroidManifest action
        Intent intent = new Intent("com.rustfisher.ndkproj.ITomInterface");
        intent.setPackage("com.rustfisher.ndkproj"); // 服务提供者的包名
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }
}

测试和效果

点击调用端的View,打出log Hello Jerry, nice to meet you! 服务端apk打印log:Jerry requires helloAIDL()

如果调用失败则抛出 android.os.DeadObjectException

当服务提供方App没有在运行时,调用方去请求服务会失败。

服务端更新后,如果aidl文件没改动,不需要更新生成的Java文件 如果服务端apk被卸载,调用端使用此服务时会出错

参考资料

Android Binder 机制介绍

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android 进阶7:进程通信之 AIDL 的使用

    记得 2015 年实习面试,笔试题里就有这道题:请介绍下 AIDL。 当时的我是懵逼的,只好老老实实空着。没想到后来面试时面试官大哥嘿嘿一笑说他也没用过这玩意,...

    张拭心 shixinzhang
  • Android Binder Analysis(3)

    前文中我们描述了Binder的基本概念,及其在Binding Service时的两种应用场景,Extends Binder Class和Messenger,接下...

    小海编码日记
  • Android:远程服务Service(含AIDL & IPC讲解)

    步骤2. 在新建AIDL文件里定义Service需要与Activity进行通信的内容(方法),并进行编译(Make Project)

    Carson.Ho
  • Android进程间通信实践的示例代码

    因为线程间的内存是共享的,所以它们之间的通信简单,比如可以通过共享变量等方式实现。而进程间想要通信就要麻烦许多了。要想实现进程间通信,我们需要在不同进程之间定义...

    砸漏
  • Android异步任务

    用户1733354
  • Android:IPC之AIDL的学习和总结

    为了使得一个程序能够在同一时间里处理许多用户的要求。即使用户可能发出一个要求,也肯能导致一个操作系统中多个进程的运行(PS:听音乐,看地图)。而且多个进程间需要...

    静默加载
  • Framework掌握不全被面试官怼?Android字节跳动大牛的精编解析笔记带你系统学习!

    通常作为一个Android APP开发者,我们并不关心Android的源代码实现,不过随着Android开发者越来越多,企业在筛选Android程序员时越来越看...

    Android技术干货分享
  • 金三银四的面试黄金季节,Android面试题来了!

    当然, 也可以用 killProcess()和 System.exit()这样的方法。 对于多个 activity

    Android技术干货分享
  • 跨进程访问(AIDL服务)

    我们都知道Service的主要的作用是后台运行和跨进程访问。 关于Service后台运行请查看鄙人的另外一篇文章Service基础

    小小工匠
  • 详解Android aidl的使用方法

    AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface defin...

    砸漏
  • Android开发之漫漫长途 IX——彻底掌握Binder

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索...

    LoveWFan
  • Android开发笔记(五十三)远程接口调用AIDL

    AIDL全称是“Android Interface Definition Language”,即Android的接口定义语言。AIDL用来协助开发者来处理进...

    用户4464237
  • android使用AIDL跨进程通信(IPC)

    AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行...

    砸漏
  • Android 进阶9:进程通信之 AIDL 解析

    在 Android 进阶7:进程通信之 AIDL 的使用 中我们使用 AIDL 实现了跨进程的通信,但是不清楚 AIDL 帮我们做了什么。 AIDL 的本质是...

    张拭心 shixinzhang
  • [003]AIDL是什么

    AIDL是什么?还记得好多面试知识点中提到,应用之间的跨进程通信有哪些方式,AIDL好几次被作为正确答案来说,其实这是大错特错,其实AIDL就是帮程序员偷懒的封...

    王小二
  • Android开发高级进阶——多进程间通信

    当一个应用在开始运行时,系统会为它创建一个进程,一个应用默认只有一个进程,这个进程(主进程)的名称就是应用的包名。

    trampcr
  • 详解Android跨进程IPC通信AIDL机制原理

    AIDL:Android Interface Definition Language,即Android接口定义语言,用于生成Android不同进程间进行进程通信...

    砸漏
  • Android AIDL 教程 (一)—— 简单的示例

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/de...

    程序员徐公
  • android之AIDL介绍

    AIDL是一个缩写,全称是Android Interface Definition Language,也就是Android接口定义语言。

    李小白是一只喵

扫码关注云+社区

领取腾讯云代金券