- 浏览: 47124 次
- 性别:
文章分类
- 全部博客 (103)
- 一致性哈希算法 (1)
- 云计算 (2)
- Cassandra学习 (2)
- Java网络通信与笔记 (14)
- ZooKeeper学习 (1)
- HBase学习 (1)
- Sqoop学习 (1)
- Java网页开发之 (2)
- Java网络通信框架 (5)
- (memcached)分布式内存对象缓存系统 (1)
- Redis学习 (5)
- Shell学习 (14)
- Linux学习 (10)
- MySQL优化 (17)
- C++ (7)
- HTML5 (5)
- Android学习 (5)
- 网络 (2)
- Node.js (1)
- D3.js (1)
- R语言学习 (3)
- Spark (1)
- CAN协议 (2)
- 解决方案 (0)
最新评论
一.基础知识
AIDL的作用
在Android平台,每个应用程序App都运行在自己的进程空间。通常一 个进程不能访问另一个进程的内存空间(一个应用不能访问另一个应用),如果想沟通,需要将对象分解成操作系统可以理解的基本单元,Android提供了AIDL来处理。
AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参 数。换句比较浅显的话来说,就是我这个App应用的activity,需要调用其他App应用的Service.当然同一App应用的activity 与service也可以在不同进程间,这可以设置Service配置中,android:process=":remote"
AIDL的使用
官方文档特别提醒我们何时使用AIDL是必要的:只有你允许客户端从不同的应用程序为了进程间的通信而去访问你的service,以及想在你的service处理多线程。(太生硬了,不同进程的组件调用吧。)
那么怎么制作AIDL呢?下面步骤
1:创建.aidl文件。新建立个文件并且以.aidl作为后缀保存,在这个文件中编写接口以及方法,这个我们普通java接口声明是一样的,不同的是要显示import 复杂类型,即便复杂类型对象在同一个包内。Java基本数据类型 (int, long, char, boolean等),String和CharSequence,集合接口类型List和Map,不需要import 。
比如:
2:创建好AIDL文件后,刷新下工程,你会发现在gen包下,对应的包下面出现一个与AIDL文件相同的java文件。如:
AIDL工具自动生成了那么多代码,其实我们只需要知道3个就够了。
3:把AIDL文件存放在其他客户端应用中,我们这个作为服务端。当然我们也可以方便的把这个应用作为客户端以及服务端。其实根本区别就是为了使调用者与被调用者在不同进程中,于是在服务中添加android:process=":remote"即可。省去了再建立应用客户端调用。
4:AIDL只是请定义一个契约,我们这里需要一个服务来提供服务。于是建立服务MyService.
二.实战
既然我们了解一些基础知识后,现在我们开始来代码吧。假设我们需要在一个进程中调用其他应用的服务,这个服务提供一个股票价格查询,或者GPS定位的服务。
并且定义一个类,继承我们AIDL生成的Stub内部类,并实现我们AIDL定义的方法
代码如下:
我们需要在onBind方法中返回我们的AIDL接口实现对象,以便其他进程调用。
当然了,现在AIDL,以及Service都定义好了,就需要在mainfest.xml中设置
在客户端服务端在同个App中,android:process=":remote",代表在应用程序里,当需要该service时,会自动创建新的进程。而如果是android:process="remote",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。
那么现在客户端来调用我们的服务了,代码如下:
在按钮点击时候启动service,然后再绑定这个Service.在连接到服务后,我们会发现,调用AIDL中定义的方法成了,打印如下:
项目结构为:
AIDL的作用
在Android平台,每个应用程序App都运行在自己的进程空间。通常一 个进程不能访问另一个进程的内存空间(一个应用不能访问另一个应用),如果想沟通,需要将对象分解成操作系统可以理解的基本单元,Android提供了AIDL来处理。
AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参 数。换句比较浅显的话来说,就是我这个App应用的activity,需要调用其他App应用的Service.当然同一App应用的activity 与service也可以在不同进程间,这可以设置Service配置中,android:process=":remote"
AIDL的使用
官方文档特别提醒我们何时使用AIDL是必要的:只有你允许客户端从不同的应用程序为了进程间的通信而去访问你的service,以及想在你的service处理多线程。(太生硬了,不同进程的组件调用吧。)
那么怎么制作AIDL呢?下面步骤
1:创建.aidl文件。新建立个文件并且以.aidl作为后缀保存,在这个文件中编写接口以及方法,这个我们普通java接口声明是一样的,不同的是要显示import 复杂类型,即便复杂类型对象在同一个包内。Java基本数据类型 (int, long, char, boolean等),String和CharSequence,集合接口类型List和Map,不需要import 。
比如:
package com.dongzi; interface IStockQuoteService{ double getPrice(String ticker); }
2:创建好AIDL文件后,刷新下工程,你会发现在gen包下,对应的包下面出现一个与AIDL文件相同的java文件。如:
/* * This file is auto-generated. DO NOT MODIFY. * Original file: D:\\mywordspace\\MyPhone\\src\\com\\dongzi\\IStockQuoteService.aidl */ package com.dongzi; public interface IStockQuoteService extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.dongzi.IStockQuoteService { private static final java.lang.String DESCRIPTOR = "com.dongzi.IStockQuoteService"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.dongzi.IStockQuoteService * interface, generating a proxy if needed. */ public static com.dongzi.IStockQuoteService asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = (android.os.IInterface) obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.dongzi.IStockQuoteService))) { return ((com.dongzi.IStockQuoteService) iin); } return new com.dongzi.IStockQuoteService.Stub.Proxy(obj); } public android.os.IBinder asBinder() { return this; } @Override public 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_getPrice: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); double _result = this.getPrice(_arg0); reply.writeNoException(); reply.writeDouble(_result); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.dongzi.IStockQuoteService { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } public double getPrice(java.lang.String ticker) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); double _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(ticker); mRemote.transact(Stub.TRANSACTION_getPrice, _data, _reply, 0); _reply.readException(); _result = _reply.readDouble(); } finally { _reply.recycle(); _data.recycle(); } return _result; } } static final int TRANSACTION_getPrice = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } public double getPrice(java.lang.String ticker) throws android.os.RemoteException; }
AIDL工具自动生成了那么多代码,其实我们只需要知道3个就够了。
public static abstract class Stub extends android.os.Binder implements com.dongzi.IStockQuoteService 静态抽象内部类Stub private static class Proxy implements com.dongzi.IStockQuoteService AIDL服务代理类 public double getPrice(java.lang.String ticker) throws android.os.RemoteException; AIDL公布出的接口,就是我们定义的接口方法
3:把AIDL文件存放在其他客户端应用中,我们这个作为服务端。当然我们也可以方便的把这个应用作为客户端以及服务端。其实根本区别就是为了使调用者与被调用者在不同进程中,于是在服务中添加android:process=":remote"即可。省去了再建立应用客户端调用。
4:AIDL只是请定义一个契约,我们这里需要一个服务来提供服务。于是建立服务MyService.
二.实战
既然我们了解一些基础知识后,现在我们开始来代码吧。假设我们需要在一个进程中调用其他应用的服务,这个服务提供一个股票价格查询,或者GPS定位的服务。
并且定义一个类,继承我们AIDL生成的Stub内部类,并实现我们AIDL定义的方法
代码如下:
package com.dongzi; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class MyService extends Service { static final String TAG="MyService"; //定义内部类MyServiceImpl继承我们的AIDL文件自动生成的内部类, //并且实现我们AIDL文件定义的接口方法 private class MyServiceImpl extends IStockQuoteService.Stub{ @Override public double getPrice(String ticker) throws RemoteException { Log.e(TAG, "getPrice"); return 10.5; } } @Override public IBinder onBind(Intent arg0) { //返回AIDL实现 return new MyServiceImpl(); } @Override public void onDestroy(){ Log.e(TAG, "Release MyService"); super.onDestroy(); } }
我们需要在onBind方法中返回我们的AIDL接口实现对象,以便其他进程调用。
当然了,现在AIDL,以及Service都定义好了,就需要在mainfest.xml中设置
<service android:name=".MyService" android:process=":remote" > <intent-filter> <action android:name="com.dongzi.IStockQuoteService"/> </intent-filter> </service>
在客户端服务端在同个App中,android:process=":remote",代表在应用程序里,当需要该service时,会自动创建新的进程。而如果是android:process="remote",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。
那么现在客户端来调用我们的服务了,代码如下:
package com.dongzi; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MYyActivity extends Activity { static final String TAG="MYyActivity"; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btnCall=(Button)findViewById(R.id.btnCall); if(btnCall!=null) btnCall.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { //绑定一个服务 bindMyService(); } }); } IStockQuoteService iService=null; private ServiceConnection conn=new ServiceConnection(){ @Override public void onServiceConnected(ComponentName name, IBinder service) { //返回AIDL接口对象,然后可以调用AIDL方法 iService=IStockQuoteService.Stub.asInterface(service); double value=0.0; try { value=iService.getPrice(""); } catch (RemoteException e) { Log.e(TAG,"调用出错!"); e.printStackTrace(); } Log.e(TAG, "返回数值为:"+value); } @Override public void onServiceDisconnected(ComponentName name) { Log.i(TAG, "释放Service"); } }; private void bindMyService(){ // Intent intent=new Intent("com.dongzi.IStockQuoteService"); Intent intent=new Intent(this,MyService.class); startService(intent); bindService(intent, conn, Context.BIND_AUTO_CREATE); } }
在按钮点击时候启动service,然后再绑定这个Service.在连接到服务后,我们会发现,调用AIDL中定义的方法成了,打印如下:
项目结构为:
相关推荐
这是一个简单的进程间通信的demo
AndroidAIDL进程间通信例子代码,一个客户端调用,一个服务端Service
进程间通信的示例,有需要的可以下载下来看看,应该对你有帮助的
使用AIDL实现进程间通信 两个工程即两个APP,实现数据共享 APP1中有个service 不停的对某一个数进行++操作, APP2通过AIDL 获取APP1的Service中的这个值(通过回调) 当然要使用AIDLAPP1中也要做相应处理
使用AIDL进行进程间通信
NULL 博文链接:https://android-zhang.iteye.com/blog/1850180
aidl跨进程通信的简单例子,有客户端和服务端。客户端绑定服务,即可发送内容到服务端。如果绑定服务失败,请添加代码:intent.setPackage("com.example.alidservice");即可
Android安卓AIDL进程间通信Service简单例子,分为客户端和服务端代码,一看就会,一看就懂,核心还是IBinder.
Android使用AIDL实现进程间通信
使用Android studio 实现两个app通过AIDL 和Binder连接池的进程间通信
andorid 不同进程间的通信, uses the aidl to comple the demo,hope you can learn ,and give me you idear .
Aidl进程间通信简单封装了下,AIDL和Service作为一个library,其他3个app调用,实现3个app共享一个服务,3个中任意app打开即可开启服务,其他两个app共用
Android进程间通信 AIDL Service 一、服务端结构 服务端需要处理的有: 1.处理对象,对象内方法,注意:AIDL 只能对函数起作用; 2.处理服务; 3.配置文件; 二、客户端 配置 1.对象,切记,与服务端的对象完全一致...
本人根据开发艺术探索这本书,深入学习跨进程通信,对AIDL终有所成,资源中是代码,里面几乎每一行都进行注解,一个不错的资源,用于以后忘记时候取过来看一下
android根据不同任务创建不同进程,并通过AIDL进行进程间通信
intent、 messenger 、aidl实现进程间通信 3个demo分别用客户端服务端实现进程间通信
Android aidl 实现进程间通信(IPC)
文件包含两个工程,Client和Server,通过aidl实现客户端和服务端之间的通信。 服务端和客户端都创建一个aidl文件,定义接口。 服务端通过service将接口暴露给客户端,客户端绑定服务。 解压即可运行。