什么是AIDL?

AIDL是 Android Interface definition language的缩写,它是一种Android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口

AIDL可以解决什么问题?

  • 可以实现多个应用程序共享同一个Service的功能,比如:IM服务可以提供给多个APP使用,先在推送基本都是采取这种方案
  • 可以跨进程调用服务里的方法

搭建了简单的Service框架

1.继承Service

public class PushService extends Service{

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

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
}

2.在AndroidManifest.xml里注册

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="name.quanke.aidldemo">

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:name=".App"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <service
                android:name=".PushService"
                android:enabled="true"
                android:process=":push"
                android:exported="true">
        </service>
    </application>

</manifest>

建立AIDL

创建AIDL文件

编写AIDL文件
interface IHandler {
  void connect();
}

aidl生成后的样子


编写客户端 ServiceConnection
public class PushClient {
    private IHandler iHandler;
    private static PushClient instance = new PushClient();

    public static PushClient getInstance() {
        return instance;
    }

    public void init(Application app){
        Intent binderIntent = new Intent(app,PushService.class);
        app.bindService(binderIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iHandler = IHandler.Stub.asInterface(service);
            //连接成功调用
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //断开连接调用
        }
    };

    //通过AIDL远程调用
    public void connect(){
        try {
            iHandler.connect();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

写服务端实现connect方法
public class LibHandler extends IHandler.Stub{

    @Override
    public void connect() throws RemoteException {

    }

    @Override
    public IBinder asBinder() {
        return null;
    }
}

测试

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        init();
    }

    private void init() {
      findViewById(R.id.aidl_test).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        PushClient.getInstance().connect();
    }
}

其实到这里我们就结束了。

接下来我们看看如果自定义传递的数据类型

传递自定义的类型

AIDL默认支持的类型包括Java基本类型(int、long、boolean等),和(String、List、Map、CharSequence),如果要传递自定义的类型需要实现android.os.Parcelable接口。


自定义Message实体:
public class Message implements Parcelable {
    private long id;
    private String content;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "Message{" +
                "id=" + id +
                ", content='" + content + '\'' +
                '}';
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(this.id);
        dest.writeString(this.content);
    }

    protected Message(Parcel in) {
        this.id = in.readLong();
        this.content = in.readString();
    }

    public static final Creator<Message> CREATOR = new Creator<Message>() {
        @Override
        public Message createFromParcel(Parcel source) {
            return new Message(source);
        }

        @Override
        public Message[] newArray(int size) {
            return new Message[size];
        }
    };

}

修改IHandler

interface IHandler {
  void connect();
  void sendMessage(Message message);
}


注意: 自定类型aidl文件名字、路径需要和自定义类名字、路径保持一致,
 编译一下,发现报了个错

意思是必须定义Message的方向,AIDL 参数有方向。(学习了)
如果sendMessage方法的message参数是纯粹的输入参数—这意味着是从客户端到服务器的数据,你需要在AIDL声明:
void sendMessage(in Message message);

如果sendMessage方法的message参数是纯粹的输出-这意味着它的数据是通过从服务器到客户端,使用:

void sendMessage(out Message message);

如果sendMessage方法的message参数是输入也是输出-客户端的值在服务可能会修改,使用:

void sendMessage(inout Message message);

我们这里是客户端范围服务端的数据,所以用in

interface IHandler {
  void connect();
  void sendMessage(in Message message);
}

好了,aidl的用法就到这里了,aidl主要是用在跨进程间通信和数据交换,平时开发中也用的比较少,通过这个例子加深了对他的用法,后面有什么好的坑,我会发出了的,谢谢大家。最后做个链接 

https://github.com/xiangzhihong/aidl


aidl使用采坑记的更多相关文章

  1. 分布式改造剧集之Redis缓存采坑记

    Redis缓存采坑记 ​ 前言 ​ 这个其实应该属于分布式改造剧集中的一集(第一集见前面博客:http://www.cnblogs.com/Kidezyq/p/8748961.html),本来按照顺序 ...

  2. Spring Cloud Config采坑记

    1. Spring Cloud Config采坑记 1.1. 问题 在本地运行没问题,本地客户端服务能连上本地服务端服务,可一旦上线,发现本地连不上线上的服务 服务端添加security登录加密,客户 ...

  3. k8s采坑记 - 解决二进制安装环境下证书过期问题

    前言 上一篇k8s采坑记 - 证书过期之kubeadm重新生成证书阐述了如何使用kubeadm解决k8s证书过期问题. 本篇阐述使用二进制安装的kubernetes环境,如何升级过期证书? k8s配置 ...

  4. Redis适配采坑记

    Redis适配采坑记 相对于其他的适配,Redis可以说是非常简单的其中只发现一个坑 问题一: 问题描述: redis认证失败 问题详解: redis连接配置时,本地需要采用password属性,远程 ...

  5. tk.mybatis通用工具采坑记

    tk.mybatis通用工具pom <!--mybatis依赖--> <dependency> <groupId>org.mybatis.spring.boot&l ...

  6. dubbo初学采坑记

    写在前面的话 dubbo 现在是apache组织旗下的项目,相信国内也有很多人使用.最近一个同事离职,我就接手了他的项目.远程通讯就是用的dubbo框架来实现的.使用Intelij idea 写了一个 ...

  7. Service worker (@nuxtjs/workbox) 采坑记

    PWA(Progressive Web App)是前端的大趋势,它能极大的加快前端页面的加载速度,得到近乎原生 app 的展示效果(其实难说).PWA 其实是多种前端技术的组合,其中最重要的一个技术就 ...

  8. css选择器:first-child和nth-child 采坑记

    今天想用nth-child来给一个类似于树的目录(bootstrap-nav-tree  一个angularjs插件)设置不同的颜色,结构大致类似于 <ul> <li class=& ...

  9. 使用wepy框架搭建微信小程序采坑记(一)

    1.什么是wepy 这个框架是腾讯内部出的一个类MVVM的小程序开发框架.大体上来说语法是类VUE的,所以如果有VUE开发经验的话迁移成本会低一些.至于具体的怎么使用我就不赘言了,有问题查文档(官方文 ...

随机推荐

  1. sublime 安装package control

    import urllib.request,os,hashlib; h = '2915d1851351e5ee549c20394736b442' + '8bc59f460fa1548d15146761 ...

  2. 搜索引擎solr和elasticsearch

    刚开始接触搜索引擎,网上收集了一些资料,在这里整理了一下分享给大家. 一.关于搜索引擎 搜索引擎(Search Engine)是指根据一定的策略.运用特定的计算机程序从互联网上搜集信息,在对信息进行组 ...

  3. Android Studio精彩案例(四)《DrawerLayout使用详解仿网易新闻客户端侧边栏 》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 为了提高兴趣,咱们开头先看看最终要实现什么样的效果: 侧拉菜单在Android应用中非常常见,它的实现方式太多了,今天我们就说说使用G ...

  4. 2017年校园招聘ios面试题

    一.搜狐快站 1.谈谈你做过的项目: 2.项目中最有成就感的部分: 3.倒计时如何实现?(NSTimer,还有其他的实现方式吗): 4.UIButton的继承关系? 5.iOS中可以进行输入的控件?( ...

  5. Python 妙用heapq

    小顶堆求TopK大 大顶堆求BtmK小 题外话 Python有一个内置的模块,heapq标准的封装了最小堆的算法实现.下面看两个不错的应用. 小顶堆(求TopK大) 话说需求是这样的: 定长的序列,求 ...

  6. RxJava(一) create操作符的用法和源码分析

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/51524470 本文出自:[余志强的博客] 1 create操作符的基 ...

  7. JSP1.x 自定义标签

    Tag接口 任何一个标签都对应着一个java类,该类必须实现Tag接口,JSP遇到一个标签后后,将通过一个tld文件查找该标签的实现类,并运行该类的相关方法 import javax.servlet. ...

  8. Android动态换肤(二、apk免安装插件方式)

    在上一篇文章Android动态换肤(一.应用内置多套皮肤)中,我们了解到,动态换肤无非就是调用view的setBackgroundResource(R.drawable.id)等方法设置控件的背景或者 ...

  9. Android简易实战教程--第十五话《在外部存储中读写文件》

    第七话里面介绍了在内部存储读写文件 点击打开链接. 这样有一个比较打的问题,假设系统内存不够用,杀本应用无法执行,或者本应用被用户卸载重新安装后.以前保存的用户名和密码都不会得到回显.所以,有必要注意 ...

  10. Java并发框架——同步状态的管理

    整个AQS框架核心功能都是围绕着其32位整型属性state进行,一般可以说它表示锁的数量,对同步状态的控制可以实现不同的同步工具,例如闭锁.信号量.栅栏等等.为了保证可见性此变量被声明为volatil ...