展会信息港展会大全

Service About AIDL 安卓开发教程
来源:互联网   发布日期:2016-01-13 21:52:46   浏览:1562次  

导读:Translated from googleAIDL(Android Interface Definition Language) 安卓接口定义语言,为了IPC-即进程间通信。 既然是两个APP进程间的通信,如何让对方程序理解你的话,将对象分解成操作系统能够理解......

Translated from google

AIDL(Android Interface Definition Language)安卓接口定义语言,为了IPC-即进程间通信。 既然是两个APP进程间的通信,如何让对方程序理解你的话,将对象分解成操作系统能够理解的原始数据,然后操作系统处理对象信号编辑后发送给对方。这种信 号的编辑比较繁琐,顾Android 引入了AIDL。

注意:AIDL只在进程间通信的时候有必要这么做,如果是同个进程间的,可以用绑定形式的Service,如果你还想IPC,但不是多线程访问的,你可以使用Messenger。

设计AIDL时请注意(调用方法):

1.当你在本地进程直接调用方法的时候,实际上该方法所处的线程与本地是同一个,当你另外开个线程调用方法的时候,这才是真正在服务端执行的代码,也就是不同进程。

这句话的言外之意就是,如果只是本地这么调用的话,你应该设计个Bound类型的Service或者其它,而不是AIDL。

2.注意AIDL支持多线程访问,问题就来了,你要确保方法的同步,以避免一些问题。

3.oneway 关键字会修改远程调用方法的行为。当你使用的时候,远程方法调用不会阻塞。 反之则不然。 当然如果你在本地调用的,这个木有影响,还是同步的。

定义AIDL接口

1.创建.aidl文件

后缀名必须是.aidl,然后里面定义的方式类似于java接口的定义方式。

AIDL支持下列数据类型:

默认的:所有原始数据类型:比如int、long之类的。String、CharSequence、List、Map。关于list和Map你可能使用的是多态,但是最终对方收到的仍然是ArrayList或者HashMap.

List或者Map中的泛型参数也必须是所支持的参数,比如Map<String,Integer>是不支持的。

如果你要使用其他的数据类型,你需要Import,注意即便是在同个包中的,也是需要Import。

你需要注意的:

1.方法可以0或者多个参数,返回一个或者void。

2.所有非原始数据类型的需要一个直接的标签,来指示数据出去的方式。in、out或者inout。

原始类型默认是in,也只能是in。

3.所有在.aidl的代码注释都被包含在IBinder接口。(除了导入包名之前的语句)

4.AIDL中你只能定义方法,不像java还可以搞些静态变量。

下面列出DEMO:

// IRemoteService.aidl

package com.example.android;

// Declare any non-default types here with import statements

/** Example service interface */

interface IRemoteService {

/** Request the process ID of this service, to do evil things with it. */

int getPid();

/** Demonstrates some basic types that you can use as parameters

* and return values in AIDL.

*/

void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,

double aDouble, String aString);

}

简单的保存你的.aidl文件在src/目录下,当编译你的工程时,SDK工具会自动产生IBinder接口文件在你的gen/目录下。

产生的文件名字与.aidl的名字一致,不过扩展名变成了.java的。

2.实现接口

刚才说到的产生的那个java文件,包含一个子类,名字为Stub,是其父接口的抽象实现,比如YourInterface.Stub,它会声明所有.aidl文件中的方法。

你需要去实现这个抽象类比如:

private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {

public int getPid(){

return Process.myPid();

}

public void basicTypes(int anInt, long aLong, boolean aBoolean,

float aFloat, double aDouble, String aString) {

// Does nothing

}

};

关于AIDL的实现仍然有几点要说的:

别人要调用你,注意别ANR,别把事情都放在主线程做了。

你的异常若不抛出,则会被送往调用者。

3.向客户端暴露接口

当然就设计Service了,look:

public class RemoteService extends Service {

@Override

public void onCreate() {

super.onCreate();

}

@Override

public IBinder onBind(Intent intent) {

// Return the interface

return mBinder;

}

private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {

public int getPid(){

return Process.myPid();

}

public void basicTypes(int anInt, long aLong, boolean aBoolean,

float aFloat, double aDouble, String aString) {

// Does nothing

}

};

}

客户端这边绑定服务,使用bindService这种方式,当然就需要ServiceConnection了,在绑定的时候把mBinder弄过来,然后就可以操作了。

IRemoteService mIRemoteService;

private ServiceConnection mConnection = new ServiceConnection() {

// Called when the connection with the service is established

public void onServiceConnected(ComponentName className, IBinder service) {

// Following the example above for an AIDL interface,

// this gets an instance of the IRemoteInterface, which we can use to call on the service

mIRemoteService = IRemoteService.Stub.asInterface(service);

}

// Called when the connection with the service disconnects unexpectedly

public void onServiceDisconnected(ComponentName className) {

Log.e(TAG, "Service has unexpectedly disconnected");

mIRemoteService = null;

}

};

当然你会问,客户端这边又没有定义方法? 答:需要copy一份aidl到客户端处,gen下面也会同时自动生成。

赞助本站

人工智能实验室

相关热词: Service AIDL

相关内容
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港