Welcome to Ray's Blog

Stay Hungry Stay Foolish - Steve Jobs

0%

AIDL简约示例笔记

AIDL 定义

AIDL: Android Interface Definition Language : Android 接口定义语言。用于不同进程(Process)之间的通讯。

使用步骤

创建 Service 服务端新工程
  1. 创建服务端工程 aidlserviceproj

  2. 然后右键创建 aidl 文件:IRemoteService.aidl

  3. 在 aidl 文件中添加方法

1
2
3
4
5
6
7
8
9
10
11
12
13
// IRemoteService.aidl
package com.chenley.an.aidlserviceproj;
// Declare any non-default types here with import statements
interface IRemoteService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
* AIDL支持的数据,还加上实现parceble的类
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
String getText(); //添加简单方法
}
  1. 编译代码获得 IRemoteService.java 接口;

  2. 创建AidlRemoteSerive extends Serivce ,然后创建IRemoteService的成员变量,并且返回数据,最后在onbind()方法中将mIRemoteService对象作为Binder对象返回;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class AidlRemoteService extends Service {
private IRemoteService.Stub mIRemoteService = new IRemoteService.Stub() {
@Override
public void basicTypes(int anInt
, long aLong
, boolean aBoolean
, float aFloat
, double aDouble
, String aString) throws RemoteException {
}

@Override
public String getText() throws RemoteException {
return "HELLO ADIL!"; //这里既是需要返回的数据
}
};
public AidlRemoteService() {
}
@Override
public IBinder onBind(Intent intent) {
return mIRemoteService.asBinder();
}
}
  1. 在 AndroidManifest.xml 文件中注册 service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<service
android:name=".AidlRemoteService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.chenley.an.aidlserviceproj.AidlRemoteService" />
</intent-filter>
</service>
~~~
**这里需要注意的是`action`,在客户端的时候需要精准匹配,才可以获得数据**

7. 在`MainActivity`中为组件设置点击事件绑定`Service`,重点是`IResultReceiver.Stub.asInterface(service)`;将`service`作为接收者,然后返回数据;
~~~java
/**
* 设置点击事件
*/
private void initListener() {
findViewById(R.id.btn_bind_service).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AidlRemoteService.class);
bindService(intent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IResultReceiver.Stub.asInterface(service);
Toast.makeText(MainActivity.this, "绑定成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}, BIND_AUTO_CREATE);
}
});
创建客户端工程
  1. 创建客户端工程:AIDLSampleProJect

  2. 将客户端的 AIDL 文件夹整体拷贝到客户端工程,见上图,然后在点编译可以获得
    public interface com.chenley.an.aidlserviceproj.IRemoteService extends android.os.IInterface接口类和public java.lang.String getText() throws android.os.RemoteException;方法

  3. MainActivity中创建IRemoteService的成员变量,然后通过bindService获取变量实例:

1
2
3
4
5
6
7
8
9
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
  /**
* 绑定远程Service,获取连接
*/
public static final String ACTION = "com.chenley.an.aidlserviceproj.AidlRemoteService";
public static final String PACKAGE = "com.chenley.an.aidlserviceproj";
private void onBindService() {
Intent serviceIntent = new Intent(ACTION); //action必须在服务端的AndroidManifest.xml文件中注册
serviceIntent.setPackage(PACKAGE);//5.0版本以上需要设置PACKAGE
bindService(serviceIntent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mIRemoteService = IRemoteService.Stub.asInterface(service); //获取远程服务的实例对象
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}, RemoteViewsService.BIND_AUTO_CREATE);
}
~~~

4. 点击组件调用Service的方法,获取到远程数据
~~~java
/**
* 调用远程服务对象的方法,获取远程数据,达到进程间通信的目的
*/
private void initListener() {
findViewById(R.id.btn_aidl).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
String text = mIRemoteService.getText();
mTvInfo.setText(text);
} catch (RemoteException e) {
Log.i(TAG, "onClick: 没有获取到远程信息数据!");
}
}
});
}
~~~

##### 使用方法和结果
1. 运行服务端工程`aidlserviceproj`,并且运行服务程序;
![](/images/aidl07.jpg)

2. 运行客户端工程`aidlsampeproject`,先绑定`Service`,获取远程`Serivce`连接,然后点击组件调用`service`的接口方法获取远程服务数据;
![](/images/aidl08.jpg) ![](/images/aidl09.png)

##### 总结
1. 注意服务端`AndroidManifest.xml`中的`service`注册信息和客户端的`intent`绑定`Service`的信息要一致;
2. 获取`IRemoteService`和`IRemoteReceive` 需要在创建`aidl`文件后再次编译工程;
3. 客户端和服务端的`aidl`文件的包名需要一致;