2024年4月1日发(作者:)
androidservice中stub作用是什么?
AIDL(android 接口描述语言)是一个IDL语言,它可以生成一段代码,可以使在一个and
roid设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例
如:在一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使
用AIDL来生成这样的代码来伪装传递各种参数。
要使用AIDL,Service需要以aidl文件的方式提供服务接口,AIDL工具将生成一个
相应的java接口,并且在生成的服务接口中包含一个功能调用的stub服务桩类。Servic
e的实现类需要去继承这个stub服务桩类。Service的onBind方法会返回实现类的对
象,之后你就可以使用它了。
参考:/allin/archive/2010/05/15/
交互过程client<-->proxy<-->stub<-->service
stub和proxy是为了方便client/service交互而生成出来的代码,这样client/service的代
码就会比较干净,不会嵌入很多很难懂的与业务无关的代码
1.什么是aidl:aidl是 Android Interface definition language的
缩写,一看就明白,它是一种android内部进程通信接口的描述语言,
通过它我们可以定义进程间的通信接口
icp:interprocess communication :内部进程通信
2.既然aidl可以定义并实现进程通信,那么我们怎么使用它呢?
文档/android-sdk/docs/guide/developing/tools/中对步
骤作了详细描述:
-- your .aidl file - This file defines an interface (YourI
) that defines the methods and fields available to a
client.
创建你的aidl文件,我在后面给出了一个例子,它的aidl文件定
义如下:写法跟java代码类似,但是这里有一点值得注意的就是它可
以引用其它aidl文件中定义的接口,但是不能够引用你的java类文件
中定义的接口
1.
2.
tivity;
3.
4.
5.
6.
interface AIDLService {
void registerTestCall(AIDLActivity cb);
void invokCallBack();
}
package ;
import
-- the .aidl file to your makefile - (the ADT Plugin for E
clipse manages this for you). Android includes the compiler, call
ed AIDL, in the tools/ directory.
编译你的aidl文件,这个只要是在eclipse中开发,你的adt插
件会像资源文件一样把aidl文件编译成java代码生成在gen文件夹
下,不用手动去编译:编译生成如我例子中代码
--ent your interface methods - The AIDL compiler
creates an interface in the Java programming language from yo
ur AIDL interface. This interface has an inner abstract class name
d Stub that inherits the interface (and implements a few additio
nal methods necessary for the IPC call). You must create a class t
hat extends and implements the methods yo
u declared in your .aidl file.
实现你定义aidl接口中的内部抽象类Stub,public static abstract
class Stub extends implements
rvice
Stub类继承了Binder,并继承我们在aidl文件中定义的接口,我
们需要实现接口方法,下面是我在例子中实现的Stub类:
1.
2.
3.
4.
on {
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
private final mBinder = new AID
@Override
public void invokCallBack() throws RemoteExcepti
Log("allBack");
Rect1 rect = new Rect1();
=-1;
=-1;
=1;
=1;
mAction(rect);
}
@Override
public void registerTestCall(AIDLActivity cb) throw
Log("erTestCall");
callback = cb;
}
};
() {
s RemoteException {
Stub翻译成中文是存根的意思,注意Stub对象是在被调用端进
程,也就是服务端进程,至此,服务端aidl服务端得编码完成了。
-- your interface to clients - If you're writing a servi
ce, you should extend Service and override (Inten
t) to return an instance of your class that implements your interf
ace.
第四步告诉你怎么在客户端如何调用服务端得aidl描述的接口对
象,doc只告诉我们需要实现(Intent)方法,该方法会
返回一个IBinder对象到客户端,绑定服务时不是需要一个ServiceCo
nnection对象么,在没有了解aidl用法前一直不知道它是什么作用,
其实他就是用来在客户端绑定service时接收service返回的IBinder
对象的:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
AIDLService mService;
private ServiceConnection mConnection = new Se
public void onServiceConnected(ComponentNam
Log("connect service");
mService = rface(service);
try {
erTestCall(mCallback);
} catch (RemoteException e) {
}
}
public void onServiceDisconnected(ComponentN
Log("disconnect service");
mService = null;
}
};
rviceConnection() {
e className, IBinder service) {
ame className) {
mService就是AIDLService对象,具体可以看我后面提供的示例
代码,需要注意在客户端需要存一个服务端实现了的aidl接口描述文
件,但是客户端只是使用该aidl接口,不需要实现它的Stub类,获取
服务端得aidl对象后mService = rface(ser
vice);,就可以在客户端使用它了,对mService对象方法的调用不是
在客户端执行,而是在服务端执行。
中使用java类,需要实现Parcelable接口,并且在定义类
相同包下面对类进行声明:
上面我定义了Rect1类
之后你就可以在aidl接口中对该类进行使用了
package ;
import 1;
interface AIDLActivity {
void performAction(in Rect1 rect);
}
注意in/out的说明,我这里使用了in表示输入参数,out没有试
过,为什么使用in/out暂时没有做深入研究。
使用完整示例,为了清除说明aidl使用,我这里写了一个
例子,例子参考了博客:
/saintswordsman/archive/2010/01/04/5
作出说明
例子实现了一个AIDLTestActivity,AIDLTestActivity通过binds
ervice绑定一个服务AIDLTestService,通过并获取AIDLTestActivity
的一个aidl对象AIDLService,该对象提供两个方法,一个是registe
rTestCall注册一个aidl对象,通过该方法,AIDLTestActivity把本身
实现的一个aidl对象AIDLActivity传到AIDLTestService,在AIDLTe
stService通过操作AIDLActivity这个aidl远端对象代理,使AIDLTe
stActivity弹出一个toast,


发布评论