AIDL(Android Interface Definition Language)

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

例子:创建两个apk,一个作为服务提供方,一个作为AIDL服务调用方。

android studio

AIDL服务方代码

一共4步
1.先进入服务方的工程,在com.rust.aidl包内创建IMyService.aidl文件

// IMyService.aidl
package com.rust.aidl;

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

interface IMyService {
    /**
     * 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);
    String helloAndroidAIDL(String name);// 此次使用的方法
}

2.在com.rust.service包内创建MyService.java文件;有一个内部类MyServiceImpl实现接口的功能

package com.rust.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

import com.rust.aidl.IMyService;

public class MyService extends Service {

    public class MyServiceImpl extends IMyService.Stub {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                               double aDouble, String aString) throws RemoteException {

        }

        public String helloAndroidAIDL(String name) throws RemoteException {
            Log.d("aidl", "helloAndroidAIDL heard from : " + name);
            return "Rust: Service01 return value successfully!";
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new MyServiceImpl();// 返回内部类实例
    }
}

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

        <service android:name="com.rust.service.MyService">
            <intent-filter>
                <action android:name="com.rust.aidl.IMyService" />
            </intent-filter>
        </service>

service写实现类MyService;action里面写上AIDL文件
4.发布运行此apk

AIDL调用方代码

建立(或进入)AIDL调用方的工程,这里是MyAIDLTest工程。有如下3个步骤:
1.将AIDL服务端生成的Java文件复制到调用方工程里,尽量保持这个Java文件的路径与服务端的一致,便于识别
2.写代码绑定服务,获取AIDL服务对象
3.通过AIDL服务对象完成AIDL接口调用

本例中,生成的Java文件路径为:服务端/app/build/generated/source/aidl/debug/com/rust/aidl/IMyService.java
将其复制到调用方工程下:MyAIDLTest/app/src/main/java/com/rust/aidl/IMyService.java
编写调用方MainActivity.java代码

package rust.myaidltest;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.rust.aidl.IMyService;

public class MainActivity extends AppCompatActivity {

    Button aidlBtn;
    IMyService myService;// 服务
    String appName = "unknown";

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myService = IMyService.Stub.asInterface(service);// 获取服务对象
            aidlBtn.setEnabled(true);
        }// 连接服务

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

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

        aidlBtn = (Button) findViewById(R.id.aidl_1_btn);
        appName = getPackageName();

        // 我们没办法在构造Intent的时候就显式声明.
        Intent intent = new Intent("com.rust.aidl.IMyService");
        // 既然没有办法构建有效的component,那么给它设置一个包名也可以生效的
        intent.setPackage("com.rust.aboutview");// the service package
        // 绑定服务,可设置或触发一些特定的事件
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

        aidlBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    // AIDL服务调用代码如下:
                    String msg = myService.helloAndroidAIDL(appName);
                    Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
效果

点击调用端的按钮,弹出Toast:Rust: Service01 return value successfully!
服务端apk打印log:helloAndroidAIDL heard from : rust.myaidltest
其中,rust.myaidltest就是调用端传入的自身的包名
服务端更新后,如果aidl文件没改动,不需要更新生成的Java文件
如果服务端apk被卸载,调用端使用此服务时会出错

Android - AIDL 使用的更多相关文章

  1. Android AIDL自动生成Java文件测试

    /******************************************************************************** * Android AIDL自动生成 ...

  2. Using self-defined Parcelable objects during an Android AIDL RPC / IPC call

    Using self-defined Parcelable objects during an Android AIDL RPC / IPC call In my previous post “Usi ...

  3. AIDL/IPC Android AIDL/IPC 进程通信机制——超具体解说及使用方法案例剖析(播放器)

    首先引申下AIDL.什么是AIDL呢?IPC? ------ Designing a Remote Interface Using AIDL 通常情况下,我们在同一进程内会使用Binder.Broad ...

  4. (转载)你真的理解Android AIDL中的in,out,inout么?

    前言 这其实是一个很小的知识点,大部分人在使用AIDL的过程中也基本没有因为这个出现过错误,正因为它小,所以在大部分的网上关于AIDL的文章中,它都被忽视了——或者并没有,但所占篇幅甚小,且基本上都是 ...

  5. Android AIDL使用详解_Android IPC 机制详解

    一.概述 AIDL 意思即 Android Interface Definition Language,翻译过来就是Android接口定义语言,是用于定义服务器和客户端通信接口的一种描述语言,可以拿来 ...

  6. android aidl

    参考: http://blog.csdn.net/u014614038/article/details/48399935 本文提供了一个关于AIDL使用的简单易懂的例子,分为客户端和服务端两部分,分别 ...

  7. android aidl 进程间通信需要注意的地方(android.os.TransactionTooLargeException)

    转自:http://blog.sina.com.cn/s/blog_4e1e357d0102wau9.html 1.bus工程实现通过service实现aidl实体类 2.actor工程通过发起bin ...

  8. Android AIDL 进行进程间通讯(IPC)

    编写AIDL文件时,需要注意: 1.接口名和aidl文件名相同. 2.接口和方法前不用加访问权限修饰符 (public.private.protected等,也不能用final.static). 3. ...

  9. Android aidl Binder框架浅析

      转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38461079 ,本文出自[张鸿洋的博客] 1.概述 Binder能干什么?B ...

  10. Android AIDL使用详解

    1.什么是aidl:aidl是 Android Interface definition language的缩写,一看就明白,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间 ...

随机推荐

  1. 论文笔记 Spatial contrasting for deep unsupervised learning

    在我们设计无监督学习模型时,应尽量做到 网络结构与有监督模型兼容 有效利用有监督模型的基本模块,如dropout.relu等 无监督学习的目标是为有监督模型提供初始化的参数,理想情况是"这些 ...

  2. HTMLCollection 对象详解,以及为什么循环获取的dom合集操作可能会出现下标不正确的情况?

    有时候循环dom合集,然后操作其中的某些dom之后,发现下标不正确了 比如我们要删除一个dom合集的时候: var selectDom = document.getElementsByClassNam ...

  3. 本地修改js代码并时时生效的解决办法

    js作为客户端语言(当然它也可以作服务端语言),非常强悍,一般情况下,我们都是在开发阶段不停的改,然后上线之后就作为稳定运行的代码. 然而有时候可能因为js写得有问题,导致上线后,某些功能无法使用,这 ...

  4. Coursera 机器学习笔记(八)

    主要为第十周内容:大规模机器学习.案例.总结 (一)随机梯度下降法 如果有一个大规模的训练集,普通的批量梯度下降法需要计算整个训练集的误差的平方和,如果学习方法需要迭代20次,这已经是非常大的计算代价 ...

  5. 如何在require中使用VUE

    现在网上抄的沸沸扬扬的VUE看来是个很NB的东西啊,看了一下,确实相对于angular1来说简化了不少东西,性能方面也比angular1要好很多,所以现在用的人越来越多了,于是作为前端,学习一下新东西 ...

  6. eclipse下启动tomcat项目,访问tomcat默认端口显示404错误

    解决:打开eclipse的server视图,双击你配置的那个tomcat,打开编辑窗口,查看server locations,看看是否选择了第一个选项(默认是第一个选项),即use workspace ...

  7. Linux crontab定时执行任务命令格式与详细例子

    基本格式 : * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 第4列表示 ...

  8. BOM API

    原文链接http://www.jb51.net/article/55851.htm 我们都知道, javascript 有三部分构成,ECMAScript,DOM和BOM,根据宿主(浏览器)的不同,具 ...

  9. JS常用数据校验集合(adding)

    常用数据校验集合 var _validator = { MAIL_REGEX: /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,; ...

  10. 1.Google Chrome浏览器 控制台全解析

    Google Chrome浏览器 控制台全解析 在Google Chrome浏览器出来之前,我一直使用FireFox,因为FireFox的插件非常丰富,更因为FireFox有强大的Firebug,对于 ...