Android服务之Service(二):关于AIDL进程间通信
2013-08-27 14:43
274 查看
上一节中我们讲解了本地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呢?下面步骤
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文件。如:
View
Code
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定义的方法
代码如下:
我们需要在onBind方法中返回我们的AIDL接口实现对象,以便其他进程调用。
当然了,现在AIDL,以及Service都定义好了,就需要在mainfest.xml中设置
在客户端服务端在同个App中,android:process=":remote",代表在应用程序里,当需要该service时,会自动创建新的进程。而如果是android:process="remote",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。
那么现在客户端来调用我们的服务了,代码如下:
View
Code
在按钮点击时候启动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文件。如:
View
Code
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",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。
那么现在客户端来调用我们的服务了,代码如下:
View
Code
在按钮点击时候启动service,然后再绑定这个Service.在连接到服务后,我们会发现,调用AIDL中定义的方法成了,打印如下:
项目结构为:
相关文章推荐
- Android服务之Service(三)关于AIDL进程间通信
- Android服务之Service——关于AIDL进程间通信(转)
- Android服务之Service(其二)关于AIDL进程间通信
- Android服务之Service(其二)关于AIDL进程间通信
- Android服务之Service(其二)关于AIDL进程间通信
- Android服务之Service(其二)关于AIDL进程间通信
- Android服务之Service(其二)关于AIDL进程间通信
- Android服务之Service(其二)关于AIDL进程间通信
- Android服务之Service(其二)关于AIDL进程间通信
- Android服务之Service 关于AIDL进程间通信
- Android服务之Service(其二)关于AIDL进程间通信
- Android服务之Service(其二)关于AIDL进程间通信
- Android服务之Service(其二)关于AIDL进程间通信
- Android四大组件之Service(二)远程服务(AIDL进程间通信)
- Android Service完全解析,关于服务你所需知道的一切(下)-进程间通信
- Android之service(其二)关于AIDL进程间通信
- Android服务之Service(AIDL进程间通信)及demo(重要!)
- Android Service完全解析,关于服务你所需知道的一切(下)-进程间通信
- Android -- service的开启方式, start开启和绑定开启服务,调用服务的的方法, aidl调用远程服务
- Android Service完全解析,关于服务你所需知道的一切