参照该文章进行总结:http://blog.csdn.net/saintswordsman/article/details/5130947
今天想研究下android的锁屏机制是怎么实现的,听说和桌面launcher是异步的。在看Framework代码的时候, 发现android的policy调用了一个IKeyguardService.aidl。发现它存放在fromwork/base/core目录下,而不是android的java代码下。
原来aidl就是android interface definition language 。是binder机制用到的文件。我简单说下我的理解:
1.android系统会根据aidl文件,生成同名的java文件。app项目,生成的java在gen文件夹下。(参照http://bbs.csdn.net/topics/390130973,系统编译出来的在out目录下,我还以为在framework下,搜了半天没搜到。。)
如:
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IMediaScannerService.java
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IMediaScannerListener.java
2.这个java文件主要是自动设计了一个Stub类。apk的xxxActivity.java通过bindService,startService与xxxService.java的onBind, onStart通讯。其中onBind实际是返回了一个mBinder,这个binder在xxxService.java里创建并初始化,这个mBinder就是Stub类如下:
- @Override
- public IBinder onBind(Intent t) {
- Log("service on bind");
- return mBinder;
- }
private final forService.Stub mBinder = new forService.Stub() {
- @Override
- public void invokCallBack() throws RemoteException
- {
- callback.performAction();
- }
- @Override
- public void registerTestCall(forActivity cb) throws RemoteException
- {
- callback = cb;
- }
- };
3.Stub类是一个抽象类,它继承了android.os.binder,并实现了forService或者forActivity(自定义的aidl接口名称)的接口,如下:文件forService.java中定义了Stub类和Proxy类,如下(forActivity也一样定义了这两个类):
- public interface forService extends android.os.IInterface
- {
- public static abstract class Stub extends android.os.Binder implements com.styleflying.AIDL.forService
- {
- private static final java.lang.String DESCRIPTOR = "com.styleflying.AIDL.forService";
- public Stub()
- {
- this.attachInterface(this, DESCRIPTOR);
- }
- ........
- private static class Proxy implements com.styleflying.AIDL.forService
- {
- private android.os.IBinder mRemote;
- Proxy(android.os.IBinder remote)
- {
- mRemote = remote;
- }
- ..........
- }
对比,forService.aidl全部代码:- package com.styleflying.AIDL;
- import com.styleflying.AIDL.forActivity;
- interface forService {
- void registerTestCall(forActivity cb);
- void invokCallBack();
- }
4. 另外,Stub在哪里会调用呢?先提醒下,forService.java和forActivity.java都定义了一个Stub(存根,如第3点所述)。到这里先区分下几个文件,forService定义的是接口,而开发者会在自定义的xxService.java中调用这个文件的接口。forActivity同理。
如第二点所述,forService的Stub在app的后台服务Service中调用。而forActiviy的Stub在app的Activiy中调用,如下:
Activiy文件中定义
private forActivity mCallback = new forActivity.Stub() {
- public void performAction() throws RemoteException
- {
- Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();
- }
- };
小结:顾名思义,forActiviy定义的接口类,都是给Activiy用的。forService同理。Activiy的Stub初始化为mCallBack,在mConnection中注册
forService mService;
private ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className,
- IBinder service) {
- mService = forService.Stub.asInterface(service);
- try {
- mService.registerTestCall(mCallback);}
- catch (RemoteException e) {
- }
- }
- public void onServiceDisconnected(ComponentName className) {
- Log("disconnect service");
- mService = null;
- }
- };
bindService的时候会调用这个mConnection: - btnOk.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- Bundle args = new Bundle();
- Intent intent = new Intent(mAIDLActivity.this, mAIDLService.class);
- intent.putExtras(args);
- bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
- startService(intent);
- }
- });
这个注册的mCallback(回调)会被Service使用,如第2点提到的mBinder下的代码:
callback.performAction();
总结: Activiy和Service是android的四大组件之二,每个实例对应一个进程,需要使用进程间通讯Binder机制。android为了实现这个功能,通过aidl文件定义接口,然后通过系统把aidl接口文件转化为java文件,实现了IInterface接口(可能是binder机制的,我还没研究),该“java接口文件“自定为开发者定义了两个重要的类:Stub和Proxy。这两个类都implement(实现)了aidl接口。但是这两个类只是完成了IInterface需要的参数和函数设计,如asInterface等函数,并没实现具体的实现函数。
到这里,底层的Binder机制的接口配置已经完成,于是,组件Activity和Service需要调用Stub类来通讯,而上面提到的四点,就是Stub类通讯的过程和相关函数。重新整理Android的Binder调用流程如下:
Acitviy中
1.初始化mConnection。
2.通过函数bindService(intent,mConnection,Contxt.xxxx)促发Service的onBind
3.实现mCallBack中的performAction()接口,这是核心部分,Service在适当条件下,就会调用该函数。(第1个Stub,forActivity的接口实现类.注册到mConnection后,被Service调用即)。
Service中
4.onBind响应,返回mBinder(获得forService的Stub)。这时产生第2个Stub实例,会被下面的流程调用.
回到Activiy中
5.这时mConnection中的onServiceConnect响应,获得第3步产生的forService.Stub接口mService,并把mCallback注册到该接口(mCallback是forActiviy.Stub类)。这时,Service就可以通过mService获得Activiy的Stub接口了。
到这里,Service已经可以和Activity互相通讯了,即双向通道已经打通。Service会根据不同的条件,调用mCallback(forActiviy的Stub)的实现函数,通知Activity做出相应的View操作。
-
下面用时序图来表示,第一次画时序图,工具功能少,不太专业: