0.  前言

不论是Android还是其他操作系统,都会有自己的IPC机制,所谓IPC(Inter-Process Communication)即进程间通信。首先线程和进程是很不同的概念,线程是CPU调用的最小单元,进程一般在PC和移动设备上指一个程序或者一个应用,一个进程可以包含多个线程。

IPC方式有很多,在Android中常用的IPC方式包括Bundle、文件、Messenger、AIDL、ContentProvider和Socket等方式。本篇主要讲解使用AIDL的方式。

1.  AIDL

AIDL(Android Interface Definition Language)是一种接口定义语言。在跨进程通信时,客户端只需要使用一个代理,服务器只需要实现一个继承Binder并实现定义接口的Stub内部类。两者不需要知道对方的实现细节,所以说两者都是实现了同一个方法,只不过是客户端调用并通过跨进程真正在远程服务中执行,而大量的跨进程过程都是相同的,为了简化使用的成本Android使用了AIDL,只需要定义一个接口,就会自动生成客户端和服务器的跨进程实现代码,而如果想实现类似验证之类的操作,只需要在Stub的onTransact中进行相应的实现就可。

和Messenger相比,AIDL最大的不同是具备多线程处理能力。AIDL的使用主要分为以下三个步骤:

(1)创建.aidl文件,定义接口;

(2)在代码中实现接口,Android SDK会根据aidl文件生成接口,接口内部有一个名为Stub内部抽象类,这个类继承了Binder类并实现aidl文件中定义的接口,我们需要拓展Stub类并实现里面的抽象方法;

(3)复写Service的onBind(),返回Stub类的实现,将接口暴露给客户端。

2.  AIDL的简单使用示例

2.1  创建AIDL文件

本节将介绍一个最简单的AIDL使用示例,完成一个跨进程的远程加法计算过程。首先创建AIDL文件,并定义接口。在Android Studio中建立AIDL文件会默认在mian目录下创建aidl文件夹。这里创建了ImyAidlInterface接口以及add()方法。返回值类型为int。

// IMyAidlInterface.aidl
package com.example.ipc_aidl;
// Declare any non-default types here with import statements
interface IMyAidlInterface {int add(int num1,int num2);
}

该文件需要客户端和服务端各一份,这里为了简便示例在同一工程下进行,只需要一份即可,服务端使用android:process开启新进程,效果和两个工程下的通信是一样的。

2.2  生成java文件

编译一下工程,会在/build/generated/source/目录下生成一个aidl文件夹,且文件夹下的目录如下图所示,该java文件表示我们的aidl文件已经创建成功。

2.3  实现接口

声明接口后要实现接口,编写一个服务端,实例化IMyAidlInterface.Stub(),实现具体方法,并在onBind()中返回该Binder实例供客户端使用。

package com.example.ipc_aidl;
/*** 服务端* 实现接口并将其暴露给客户端* Created by SEU_Calvin on 2017/3/25.*/
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class IRemoteService extends Service {private IBinder iBinder = new IMyAidlInterface.Stub() {@Overridepublic int add(int num1, int num2) throws RemoteException {return num1 + num2;}};@Overridepublic IBinder onBind(Intent intent) {return iBinder;}
}

最后别忘了在Manifest.xml中声明该服务,有一次不小心把该服务写在了<application>标签外面,然后客户端bindService()死活就是返回false,蠢的不行QAQ。

<service android:name=".IRemoteService"    android:process=":remote">
</service>

2.4  客户端调用接口

最后是Activity中的逻辑:

package com.example.ipc_aidl;
/*** 客户端* 客户端调用远程接口* Created by SEU_Calvin on 2017/3/25.*/
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;public class MainActivity extends Activity{private EditText et_num1;private EditText et_num2;private EditText edit_show_result;private Button btn_count;private int mNum1;private int mNum2;private int mTotal;private IMyAidlInterface iMyAidlInterface;private ServiceConnection serviceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//服务绑定成功后调用,这里的service就是服务端onBind返回的iBinderiMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);}@Overridepublic void onServiceDisconnected(ComponentName name) {iMyAidlInterface = null;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//绑定服务Intent intent = new Intent(MainActivity.this,IRemoteService.class);//或者使用下面的方式设置Intent//intent.setComponent(new ComponentName("com.example.ipc_aidl","com.example.ipc_aidl.IRemoteService"));bindService(intent, serviceConnection, BIND_AUTO_CREATE);et_num1 = (EditText)findViewById(R.id.et_num1);et_num2 = (EditText)findViewById(R.id.et_num2);edit_show_result = (EditText)findViewById(R.id.result);btn_count = (Button)findViewById(R.id.btn_count);btn_count.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mNum1 = Integer.parseInt(et_num1.getText().toString());mNum2 = Integer.parseInt(et_num2.getText().toString());try {if(iMyAidlInterface == null){Toast.makeText(MainActivity.this,"iMyAidlInterface is null",Toast.LENGTH_SHORT).show();}else{mTotal = iMyAidlInterface.add(mNum1,mNum2);}} catch (RemoteException e) {e.printStackTrace();}edit_show_result.setText(mTotal+"");}});}@Overrideprotected void onDestroy(){super.onDestroy();unbindService(serviceConnection);}
}

首先执行bindService()方法绑定服务端的远程服务,绑定成功后会回调serviceConnection中的onServiceConnected()方法。在该方法中获取到服务端返回的Binder实例,并赋值给ImyAidlInterface类型的成员变量,调用它的add()方法即可调用远程服务实现两个加数的相加运算。

参考源码地址点击下载。请大家多点赞支持~

有的朋友可能会说这种服务也太简单了吧,有没有更高级一点的用法呢,下一篇会介绍使用AIDL传递自定义的对象。

Android开发——进程间通信之AIDL(一)相关推荐

  1. Android开发——进程间通信之Bundle和文件

    0.  前言 不论是Android还是其他操作系统,都会有自己的IPC机制,所谓IPC(Inter-Process Communication)即进程间通信.首先线程和进程是很不同的概念,线程是CPU ...

  2. android lcd 显示图片,Android开发中通过AIDL文件中的方法打开钱箱,显示LCD屏幕

    下载相关 资源文件 ,在项目中新建如下层级的文件夹,将源文件中的AIDL文件放入其中. ICallback:打印服务执行结果的回调 ITax:打印服务执行结果的回调 ILcdCallback:顾显反馈 ...

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

    AIDL概述 AIDL全称是"Android Interface Definition Language",即Android的接口定义语言.AIDL用来协助开发者来处理进程间通信, ...

  4. Android进程间通信 深入浅出AIDL

    文中示例代码均可在demo中找到 1. AIDL概念 Android 接口定义语言 (AIDL) 与您可能使用过的其他接口语言 (IDL) 类似.您可以利用它定义客户端与服务均认可的编程接口,以便二者 ...

  5. Android开发笔记(五十一)通过Messenger实现进程间通信

    进程间通信IPC IPC是"Inter-Process Communication"的缩写,即进程间通信.Android为APP提供了多进程工作模式,这是因为多线程存在若干局限: ...

  6. Android进程间通信 深入浅出AIDL(一)

    文中示例代码均可在demo中找到 1. AIDL概念 Android 接口定义语言 (AIDL) 与您可能使用过的其他接口语言 (IDL) 类似.您可以利用它定义客户端与服务均认可的编程接口,以便二者 ...

  7. Android应用中通过AIDL机制实现进程间的通讯实例

    Android中,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢?显然,Java中是不支持跨进程内存共享的,因此要传递对象,需要把对象解析成操作系统能够理解的数据格式,以达 ...

  8. 2016BAT+华为+滴滴+搜狗Android开发岗面试问题整理

    实习面了阿里和腾讯,校招面了腾讯,百度,华为,搜狗和滴滴,总结一下遇到的面试知识点.知识点是散的而且也比较容易掌握,难点是这些知识点的应用中并且深刻理解.实习面试的时候阿里通过,腾讯一面跪(内推和实习 ...

  9. 高级Android开发面试汇总

    高级 Android 开发面试题汇总 一. Android 基础 1. Service 的两种启动方式 简单的来说就是 直接启动 和 绑定启动 两种方式. // 直接启动 Context.startS ...

最新文章

  1. error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. 的解决方法
  2. 自学是一门艺术:踏上数据科学、人工智能和机器学习的自学之路
  3. matlab linprog应用示例
  4. python 获取 文件修改时间 距离 当前时间 天数 秒数
  5. 你还在用自己的电脑跑python程序?大佬都这么玩,绝对意想不到
  6. 项目基于vue-uniapp,使用colorUi与uview框架,完美支持微信小程序
  7. 演练 网站的头部导航栏的制作 1014 HTML
  8. 我们这些中年人,多处在管理层面
  9. Cherry,你会喜欢这种手机!
  10. 创编游戏计算机课反思,游戏课创编设计(王秀英)
  11. 【Linux】POSIX信号量
  12. 谷歌宣布退出中国 google.cn已经关闭
  13. 工具推荐——Snipaste
  14. 单片机内部FLASH的字节操作
  15. MATLAB周边第三期-坤坤的唱跳rap
  16. JDBC获取数据库(mysql)四种连接方式(connection)
  17. 我的python学习(前言 初生牛犊不怕虎)
  18. Spring学习笔记4
  19. ubuntu下vscode配置C++项目编译调试(json文件),以高翔octomap教程为例,顺便解决vscode无法设置断点问题.
  20. 【完结】囚生CYの备忘录(20221121-20230123)

热门文章

  1. 蓝牙控制esp32单片机(三)
  2. 一点心得,觉知此事须躬行
  3. 一图了解交通拥堵治理措施
  4. 总结使人进步,遵循事物的发展规律
  5. php方法重写:Declaration of should be compatible with that
  6. 那些年啊 那些事 一个程序员的奋斗史 121
  7. 计算机开机选择用户界面,win7系统每次开机都会出现选择操作系统界面的设置办法...
  8. python学习之 re库 正则表达式
  9. 当机器学习遇到病理学,机遇和挑战(UCL柴秉浩博士 | 钰沐菡 公益公开课)
  10. OJ1343——First Blood