AIDL (
Android Interface Definition Language) 是一种IDL 语言,用于生成可以在
Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。本文简单介绍AIDL的使用。
从内容中也可以看出,这东西类似一个接口。既然定义了这么一个玩意,那么我们就要去实现它。
基于Binder的不同进程间通信,Client与Service在不同的进程中,对用户程序而言当调用Service返回的IBinder接口后,访问Service中的方法就如同调用自己的函数一样。
配置一个所属进程名和一个action。
执行之后的Log如下:
1.新建IRemoteService.aidl
1.
package
com.tang.remoteservicedemo;
2.
interface
IRemoteService {
3.
String getInfo();
4.
}
2.新建IService“实现”IRemoteService“接口”
01.
package
com.tang.remoteservicedemo;
02.
03.
import
java.util.Date;
04.
05.
import
android.app.Service;
06.
import
android.content.Intent;
07.
import
android.os.IBinder;
08.
import
android.os.RemoteException;
09.
10.
public
class
IService
extends
Service
11.
{
12.
private
IBinder iBinder =
new
IRemoteService.Stub() {
13.
@Override
14.
public
String getInfo()
throws
RemoteException {
15.
// TODO Auto-generated method stub
16.
return
new
Date(System.currentTimeMillis()).toLocaleString()+
" 来自远程服务的信息!"
;
17.
}
18.
};
19.
@Override
20.
public
IBinder onBind(Intent intent) {
21.
// TODO Auto-generated method stub
22.
return
iBinder;
23.
}
24.
}
3.配置IService供其他进程调用
1.
<service android:name=
"com.tang.remoteservicedemo.IService"
2.
android:process=
":remote"
>
3.
<intent-filter>
4.
<action android:name=
"com.tang.remoteservicedemo.IService"
/>
5.
</intent-filter>
6.
</service>
配置一个所属进程名和一个action。
通过前面三个步骤,这个含有getInfo()方法的service就可以给别人调用了,下面在客户端调用它
4.新建一个ClientDemo工程将含有IRemoteService.aidl的那个包全部拷贝到src下,只留下aidl文件,其他全删除。
5.新建MainActivity,其他就是绑定service的操作了
001.
package
com.tang.clientdemo;
002.
003.
import
java.util.Timer;
004.
import
java.util.TimerTask;
005.
006.
import
com.tang.remoteservicedemo.IRemoteService;
007.
008.
import
android.app.Activity;
009.
import
android.content.ComponentName;
010.
import
android.content.Context;
011.
import
android.content.Intent;
012.
import
android.content.ServiceConnection;
013.
import
android.os.Bundle;
014.
import
android.os.IBinder;
015.
import
android.os.RemoteException;
016.
import
android.util.Log;
017.
018.
019.
public
class
MainActivity
extends
Activity {
020.
021.
private
IRemoteService iService =
null
;
022.
private
boolean
isBinded =
false
;
023.
024.
ServiceConnection conn =
new
ServiceConnection() {
025.
026.
@Override
027.
public
void
onServiceDisconnected(ComponentName name) {
028.
// TODO Auto-generated method stub
029.
isBinded =
false
;
030.
iService =
null
;
031.
}
032.
033.
@Override
034.
public
void
onServiceConnected(ComponentName name, IBinder service) {
035.
// TODO Auto-generated method stub
036.
iService = IRemoteService.Stub.asInterface(service);
037.
isBinded =
true
;
038.
}
039.
};
040.
041.
public
void
doBind()
042.
{
043.
Intent intent =
new
Intent(
"com.tang.remoteservicedemo.IService"
);
044.
bindService(intent, conn, Context.BIND_AUTO_CREATE);
045.
}
046.
047.
public
void
doUnbind()
048.
{
049.
if
(isBinded)
050.
{
051.
unbindService(conn);
052.
iService =
null
;
053.
isBinded =
false
;
054.
}
055.
}
056.
@Override
057.
protected
void
onCreate(Bundle savedInstanceState) {
058.
super
.onCreate(savedInstanceState);
059.
setContentView(R.layout.activity_main);
060.
new
Thread(
new
Runnable() {
061.
@Override
062.
public
void
run() {
063.
// TODO Auto-generated method stub
064.
doBind();
065.
}
066.
}).start();
067.
Timer timer =
new
Timer();
068.
timer.schedule(task,
0
,
2000
);
069.
070.
}
071.
TimerTask task =
new
TimerTask() {
072.
@Override
073.
public
void
run() {
074.
// TODO Auto-generated method stub
075.
if
(iService!=
null
)
076.
{
077.
try
{
078.
Log.i(
"AAA"
, iService.getInfo());
079.
}
catch
(RemoteException e) {
080.
// TODO Auto-generated catch block
081.
e.printStackTrace();
082.
}
083.
}
084.
else
085.
{
086.
Log.i(
"AAA"
,
"iService!=null"
);
087.
}
088.
089.
}
090.
};
091.
092.
@Override
093.
protected
void
onDestroy() {
094.
// TODO Auto-generated method stub
095.
doUnbind();
096.
task.cancel();
097.
super
.onDestroy();
098.
}
099.
}
执行之后的Log如下:
为什么会有一个为空的Log呢,因为绑定也是要时间的嘛....