JAVa调用aidl_远程接口调用AIDL

AIDL概述

AIDL全称是“Android Interface Definition Language”,即Android的接口定义语言。AIDL用来协助开发者来处理进程间通信,我们知道可以使用Messenger完成进程间通信。但是Messenger每次调用都只能传递一个消息包,不能很好的完成一些复杂的调用,比如说我们想像API调用那样通过不同的方法来实现不同的动作,这时Messenger就难以实现了。所以Android引入了AIDL服务来完成这种RPC调用。

下面是在项目工程中运用AIDL的具体方法和步骤。

AIDL定义修改

普通方法

通过菜单“File”——“New”创建扩展名为aidl的文件,文件内容与interface接口格式类似(区别在于要在输入参数前面加上in关键字)。文件定义完成并且没有错误,则ADT会自动在gen目录下生成该aidl文件对应的java文件。下面是一个AIDL接口定义文件的例子:

[代码]java代码:1

2

3interface IUserService {

double multiply(in double a1, in double a2);

}

方法中传递了自定义数据结构

如果想在aidl方法中使用自定义数据结构,则需加上如下步骤:

1、把自定义数据结构的代码(如User.java)挪到aidl包下面,这个数据结构必须实现Parcelable接口;

2、在aidl包下新建一个User.aidl文件,文件内容为“parcelable User;”;很简单,告诉aidl,我这里有个叫做User的parcelable对象;

3、在aidl接口定义中添加新的方法,并使用import导入User的完整路径。即使User.java就在aidl目录下,那也得import,不然ADT不认这个对象;下面是补充后的文件定义例子:

[代码]java代码:1

2

3

4

5

6import com.example.exmprocess.aidl.data.User;

interface IUserService {

double multiply(in double a1, in double a2);

int save(in List userList);

项目代码修改

客户端代码修改

1、定义一个ServiceConnection对象,在onServiceConnected方法中获取对方服务的实例。代码例子如下:

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11private IUserService mService;

private ServiceConnection mAidlConn = new ServiceConnection() {

public void onServiceConnected(ComponentName name, IBinder binder) {

mService   = IUserService.Stub.asInterface(binder);

}

public void onServiceDisconnected(ComponentName name) {

mService   = null;

}

};

2、远程服务当然只能通过bindService方法启动,不能通过startService方法启动。同时Intent对象也只能通过setAction来指定对方服务的动作,而不能直接指定对方服务的class;

3、绑定服务后,再调用aidl服务端,即可使用mService来调用相应的方法;

服务端代码修改

重写的Binder类要改为继承自Stub(原来继承自Binder),即ADT根据aidl文件定义自动生成的Stub类,查看自动生成的java源码,其实Stub类就是从Binder类派生出来的。

另外,服务端的Binder类需要实现aidl中定义的方法。

需要注意的地方

1、intent-filter节点中的“android:name”必须填入原始名称,不可用“@string/aaa”这种定义来代替。

2、Android5.0之后不能再隐式启动Service,只能显式启动Service,所以需要判断当前SDK版本从而做分支处理。

3、aidl定义文件需要同时加入到客户端项目代码与服务端项目代码中,并且aidl文件所在的包路径也要保持一致。

使用示例

下面是AIDL服务调用的效果图:

下面是AIDL客户端的示例代码:

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96import java.util.ArrayList;

import java.util.List;

import android.app.Activity;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Build;

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;

import android.widget.TextView;

import android.widget.Toast;

import com.example.exmprocess.R;

import com.example.exmprocess.aidl.data.IUserService;

import com.example.exmprocess.aidl.data.User;

import com.example.exmprocess.util.IntentUtil;

public class AidlActivity   extends Activity   implements OnClickListener   {

private static final String   TAG = "AidlActivity";

private String AIDL_SERVICE = "com.example.exmprocess.aidl.action.AIDL_ADD";

private TextView tv_aidl;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_aidl);

tv_aidl   = (TextView) findViewById(R.id.tv_aidl);

Button   btn_aidl_bind = (Button) findViewById(R.id.btn_aidl_bind);

Button   btn_aidl_unbind = (Button) findViewById(R.id.btn_aidl_unbind);

Button   btn_aidl_send = (Button) findViewById(R.id.btn_aidl_send);

btn_aidl_bind.setOnClickListener(this);

btn_aidl_unbind.setOnClickListener(this);

btn_aidl_send.setOnClickListener(this);

}

private IUserService mService;

private ServiceConnection mAidlConn = new ServiceConnection() {

public void onServiceConnected(ComponentName name, IBinder binder) {

mService   = IUserService.Stub.asInterface(binder);

}

public void onServiceDisconnected(ComponentName name) {

mService   = null;

}

};

@Override

public void onClick(View v) {

if (v.getId() == R.id.btn_aidl_bind) {

Intent   intent = new Intent();

intent.setAction(AIDL_SERVICE);

Intent   newIntent = intent;

//Android5.0之后不能再隐式启动Service,只能显式启动Service

if (Build.VERSION.SDK_INT >=   Build.VERSION_CODES.LOLLIPOP) {

newIntent   = new Intent(IntentUtil.getExplicitIntent(this,   intent));

}

boolean bBind = bindService(newIntent, mAidlConn,   Context.BIND_AUTO_CREATE);

Toast.makeText(this,   "绑定结果为"+bBind, Toast.LENGTH_LONG).show();

}   else if (v.getId() == R.id.btn_aidl_unbind)   {

unbindService(mAidlConn);

mService   = null;

}   else if (v.getId() == R.id.btn_aidl_send) {

if (mService == null) {

Toast.makeText(this,   "未绑定AIDL服务", Toast.LENGTH_LONG).show();

}   else {

try {

double a1 = 123;

double a2 = 9;

double result = mService.multiply(a1, a2);

List   userList = new ArrayList();

userList.add(new User(1, "张三", "111111"));

userList.add(new User(2, "李四", "999999"));

userList.add(new User(3, "王五", "123456"));

int count = mService.save(userList);

String   desc = String.format("%f*%f计算结果是%f\n本次保存了%d条记录",

a1,   a2, result, count);

tv_aidl.setText(desc);

}   catch (RemoteException   e) {

//   TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

下面是AIDL服务端的示例代码:

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35import java.util.List;

import com.example.exmprocess.aidl.data.IUserService.Stub;

import com.example.exmprocess.aidl.data.User;

import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

import android.os.RemoteException;

import android.util.Log;

public class AidlService   extends Service   {

private static final String   TAG = "AidlService";

private final IBinder mBinder = new LocalBinder();

public class LocalBinder extends Stub {

@Override

public double multiply(double a1, double a2) throws RemoteException {

return a1*a2;

}

@Override

public int save(List userList) throws RemoteException {

//此处省略保存操作

return userList.size();

}

}

@Override

public IBinder onBind(Intent intent) {

Log.d(TAG,   "onBind");

return mBinder;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值