android aidl进程间的通信

2024-06-04 21:38
文章标签 android 进程 通信 aidl

本文主要是介绍android aidl进程间的通信,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。进程在PC和移动设备上指的是一个程序或者一个应用。一个进程可以包含多个线程,因此进程和线程是包含被包含的关系。这里主要是实现activity通过aidl调用service方法和一个应用调用另一个应用方法的实现。

2、aidl在应用间的使用


首先可以先实现 .aidl文件,.aidl文件可以直接新建,跟java同级

// IMyAidlInterface.aidl
package com.example.apple.myfragment;// Declare any non-default types here with import statementsinterface IMyAidlInterface {/*** Demonstrates some basic types that you can use as parameters* and return values in AIDL.*/int add(int a, int b);int reduce(int a,int b);
}
这里只写两个方法,add和reduce,这里通过aidl将service和activity绑定,这样可以实现activity对service里面的方法的调用,要让service支持绑定,需要实现onBind方法,并反回被绑定service的当前实例。需要注意的是更新完。aidl文件需要刷新一下工程,service代码如下所示:

package com.example.apple.myfragment;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;/*** Created by apple on 17/4/14.*/public class MyService extends Service {@Nullable@Overridepublic IBinder onBind(Intent intent) {return myAidlInterface;}private final IMyAidlInterface.Stub myAidlInterface = new IMyAidlInterface.Stub() {@Overridepublic int add(int a, int b) throws RemoteException {Log.e("nsc","a+b="+(a+b));return a+b;}@Overridepublic int reduce(int a, int b) throws RemoteException {Log.e("nsc","a-b="+(a-b));return rd(a,b);}};private int rd(int a ,int b){if (a>b){return a-b;}else {return b-a;}}
}

service和activity连接需要使用ServiceConnection,里面实现了两个方法,连接和断开连接。建立连接后就可以对service实例进行引用了,当建立连接需要调用aidlInterface = IMyAidlInterface.Stub.asInterface(service);如下所示,使用完还要在onDestroy里调用unbindService(connection);

package com.example.apple.myfragment;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.TextView;public class MainActivity extends AppCompatActivity {private Button btnAdd;private Button btnReduce;private TextView tvResult;private IMyAidlInterface aidlInterface;private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {aidlInterface = IMyAidlInterface.Stub.asInterface(service);}/*** 断开连接* @param name*/@Overridepublic void onServiceDisconnected(ComponentName name) {aidlInterface = null;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();bindAndStartService();}/*** 绑定服务*/private void bindAndStartService() {Intent intent = new Intent(this, MyService.class);intent.setAction("com.example.apple.myfragment");bindService(intent, connection, Context.BIND_AUTO_CREATE);startService(intent);}private void initView() {tvResult = (TextView)findViewById(R.id.tv_result);btnAdd = (Button)findViewById(R.id.btn_add);btnAdd.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {if (aidlInterface!=null){tvResult.setText(aidlInterface.add(3,4)+"");}}catch (Exception e){e.printStackTrace();}}});btnReduce = (Button)findViewById(R.id.btn_reduce);btnReduce.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {if (aidlInterface!=null){tvResult.setText(aidlInterface.reduce(5,3)+"");}}catch (Exception e){e.printStackTrace();}}});}@Overrideprotected void onDestroy() {unbindService(connection);super.onDestroy();}
}
还要在manifest里面配置一下
<service android:name=".MyService"><intent-filter><action android:name="com.example.apple.myfragment"></action><category android:name="android.intent.category.DEFAULT"/></intent-filter></service>

最后记得在build.gradl里面的android{}加入下面代码,以便实现对.aidl文件的调用。

sourceSets {main {java.srcDirs = ['src/main/java', 'src/main/aidl']}}

实现效果


3、这里是activity调用service方法的实现。下面实现一下不同应用间的通信实现。上面的实现算是服务端,下面实现一下客户端代码


客户端的.aidl 文件直接拷贝服务端的就可以,保持好同样的路径,代码中实现需要注意的是在5.0以上的系统中启动服务需要用setPackage,否则报错,填写是服务端的包名,其他没什么注意的了。详细可以看下面代码:

 /*** 绑定服务*/private void bindAndStartService() {Intent intent = new Intent();intent.setAction("com.example.apple.myfragment");intent.setPackage("com.example.apple.myfragment");bindService(intent, connection, Context.BIND_ABOVE_CLIENT);}
MainActivity代码实现

package com.example.apple.aidl;import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;import com.example.apple.aidlactivity.R;
import com.example.apple.myfragment.IMyAidlInterface;public class MainActivity extends AppCompatActivity {private Button btnAdd;private Button btnReduce;private TextView tvResult;private IMyAidlInterface aidlInterface;private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {aidlInterface = IMyAidlInterface.Stub.asInterface(service);}/*** 断开连接* @param name*/@Overridepublic void onServiceDisconnected(ComponentName name) {aidlInterface = null;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();bindAndStartService();}/*** 绑定服务*/private void bindAndStartService() {Intent intent = new Intent();intent.setAction("com.example.apple.myfragment");intent.setPackage("com.example.apple.myfragment");bindService(intent, connection, Context.BIND_ABOVE_CLIENT);}private void initView() {tvResult = (TextView)findViewById(R.id.tv_result);btnAdd = (Button)findViewById(R.id.btn_add);btnAdd.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//   bindAndStartService();try {//  if (aidlInterface!=null){tvResult.setText(aidlInterface.add(3,4)+"");//  }}catch (Exception e){e.printStackTrace();}}});btnReduce = (Button)findViewById(R.id.btn_reduce);btnReduce.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {if (aidlInterface!=null){tvResult.setText(aidlInterface.reduce(5,3)+"");}}catch (Exception e){e.printStackTrace();}}});}@Overrideprotected void onDestroy() {unbindService(connection);super.onDestroy();}
}

4、了解一下IMyAidlInterface里面的代码,就是服务端和客户端是如何建立关联的。服务端提供的服务是由IMyAidlInterface.Stub来执行,Stub这个类是Binder的子类,继承了binder的,而且mBinder实现了IMyAidlInterface接口的方法。

public interface IMyAidlInterface extends android.os.IInterface {/*** Local-side IPC implementation stub class.*/public static abstract class Stub extends android.os.Binder implements com.example.apple.myfragment.IMyAidlInterface {private static final java.lang.String DESCRIPTOR = "com.example.apple.myfragment.IMyAidlInterface";

我们在.aidl文件里面添加的两个方法在这里都可以看到

 @Overridepublic int add(int a, int b) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();int _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(a);_data.writeInt(b);mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);_reply.readException();_result = _reply.readInt();} finally {_reply.recycle();_data.recycle();}return _result;}@Overridepublic int reduce(int a, int b) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();int _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(a);_data.writeInt(b);mRemote.transact(Stub.TRANSACTION_reduce, _data, _reply, 0);_reply.readException();_result = _reply.readInt();} finally {_reply.recycle();_data.recycle();}return _result;}}

这个proxy实例传入了我们的binder驱动,并且封装了我们调用服务端的代码,客户端通过Binder驱动的transact()方法调用服务端代码。

首先声明两个parce对象,一个用于传递数据,一个用于接收返回的数据。与服务端的enforceInterfac对应。

_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(a);_data.writeInt(b);
写入需要传递的数据。

mRemote.transact(Stub.TRANSACTION_reduce, _data, _reply, 0);

最后读出我们服务端返回的数据,然后return。可以看到和服务端的onTransact基本是一行一行对应的。

/** This file is auto-generated.  DO NOT MODIFY.* Original file: /Users/apple/Desktop/MyFragment/app/src/main/aidl/com/example/apple/myfragment/IMyAidlInterface.aidl*/
package com.example.apple.myfragment;
// Declare any non-default types here with import statementspublic interface IMyAidlInterface extends android.os.IInterface {/*** Local-side IPC implementation stub class.*/public static abstract class Stub extends android.os.Binder implements com.example.apple.myfragment.IMyAidlInterface {private static final java.lang.String DESCRIPTOR = "com.example.apple.myfragment.IMyAidlInterface";/*** Construct the stub at attach it to the interface.*/public Stub() {this.attachInterface(this, DESCRIPTOR);}/*** Cast an IBinder object into an com.example.apple.myfragment.IMyAidlInterface interface,* generating a proxy if needed.*/public static com.example.apple.myfragment.IMyAidlInterface asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof com.example.apple.myfragment.IMyAidlInterface))) {return ((com.example.apple.myfragment.IMyAidlInterface) iin);}return new com.example.apple.myfragment.IMyAidlInterface.Stub.Proxy(obj);}@Overridepublic android.os.IBinder asBinder() {return this;}@Overridepublic boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {switch (code) {case INTERFACE_TRANSACTION: {reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_add: {data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();int _arg1;_arg1 = data.readInt();int _result = this.add(_arg0, _arg1);reply.writeNoException();reply.writeInt(_result);return true;}case TRANSACTION_reduce: {data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();int _arg1;_arg1 = data.readInt();int _result = this.reduce(_arg0, _arg1);reply.writeNoException();reply.writeInt(_result);return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.example.apple.myfragment.IMyAidlInterface {private android.os.IBinder mRemote;Proxy(android.os.IBinder remote) {mRemote = remote;}@Overridepublic android.os.IBinder asBinder() {return mRemote;}public java.lang.String getInterfaceDescriptor() {return DESCRIPTOR;}@Overridepublic int add(int a, int b) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();int _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(a);_data.writeInt(b);mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);_reply.readException();_result = _reply.readInt();} finally {_reply.recycle();_data.recycle();}return _result;}@Overridepublic int reduce(int a, int b) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();int _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(a);_data.writeInt(b);mRemote.transact(Stub.TRANSACTION_reduce, _data, _reply, 0);_reply.readException();_result = _reply.readInt();} finally {_reply.recycle();_data.recycle();}return _result;}}static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);static final int TRANSACTION_reduce = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);}public int add(int a, int b) throws android.os.RemoteException;public int reduce(int a, int b) throws android.os.RemoteException;
}
代码下载地址: http://download.csdn.net/detail/u011324501/9817169









































这篇关于android aidl进程间的通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1031195

相关文章

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

C#如何优雅地取消进程的执行之Cancellation详解

《C#如何优雅地取消进程的执行之Cancellation详解》本文介绍了.NET框架中的取消协作模型,包括CancellationToken的使用、取消请求的发送和接收、以及如何处理取消事件... 目录概述与取消线程相关的类型代码举例操作取消vs对象取消监听并响应取消请求轮询监听通过回调注册进行监听使用Wa

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存