android进程间通讯流程分析:使用 Binder和AIDL
2014-07-25 15:41
453 查看
参照该文章进行总结: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();
}
小结:系统自动根据forService.aidl生成了forService.java,主要是实现了Stub抽象类。forActiviy.aidl同理。
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操作。
下面用时序图来表示,第一次画时序图,工具功能少,不太专业:
今天想研究下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();
}
小结:系统自动根据forService.aidl生成了forService.java,主要是实现了Stub抽象类。forActiviy.aidl同理。
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操作。
下面用时序图来表示,第一次画时序图,工具功能少,不太专业:
相关文章推荐
- android—binder进程间通讯流程分析
- Android:使用AIDL实现进程间通讯
- 示例:Android使用AIDL实现跨进程通讯(IPC)
- android 进程间通信 messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯? android 消息机制 进程间 android 进程间 可以用
- android使用AIDL实现跨进程通讯(IPC)
- Android Binder机制实现进程间数据交换(不使用aidl实现)
- android学习之使用AIDL实现进程间的通讯
- Android进程间通讯之初见(IPC,RPC,LPC,BINDER,AIDL..)
- 基于binder的跨进程通讯之使用AIDL实现Demo
- Android系统分析之AIDL跨进程通信机制的使用和原理分析
- 源码分析——从AIDL的使用开始理解Binder进程间通信的流程
- 关于AIDL的使用---- Android 进程间通讯之一
- android使用AIDL实现跨进程通讯(IPC)
- Android系统Recovery工作原理之使用update.zip升级过程分析(六)---Recovery服务流程细节
- Android 两个进程之间使用AIDL
- Android系统Recovery工作原理之使用update.zip升级过程分析(六)---Recovery服务流程细节
- Android应用中通过AIDL机制实现进程间的通讯实例
- Android系统Recovery工作原理之使用update.zip升级过程分析(六)---Recovery服务流程细节
- 天天记录 - Android 使用dmeo和源码分析invalidate流程
- Android应用中通过AIDL机制实现进程间的通讯实例