1. AIDL进程通讯
首先了解一下进程间使用service通讯的基本方式,定义了客户端和服务端,都生成了相同的AIDL和build之后的java。
服务端定义AIDL:
// IMyAidlInterface.aidl
package com.example.serverport;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
String getName();
}
服务端定义服务:
package com.example.serverport;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
Log.d("aaaa","1234");
return new MyBin();
}
class MyBin extends IMyAidlInterface.Stub {
@Override
public String getName() {
return "hahahaha";
}
}
}
客户端:
boolean b = bindService(intent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
String name = iMyAidlInterface.getName();
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}, Context.BIND_AUTO_CREATE);
bindService之后会返回服务端的Binder,利用aidl生成的java来获取服务端的服务。
2. Binder通讯
1. 首先在系统开机启动时,一个进程通过Binder驱动将自己注册成ServiceManager,其地址固定为0;
2. Server通过驱动向ServiceManager中注册Binder。驱动为这个Binder创建位于内核中的实体节点以及ServiceManager对实体的引用,将名字以及新建的引用打包传给ServiceManager,ServiceManger将其填入查找表;
3. Client通过名字,在Binder驱动的帮助下从ServiceManager中获取到对Binder实体的引用,通过这个引用就能实现和Server进程的通信。
客户端拿到的只是Server binder的引用,进一步利用asInterface(Binder *)可以拿到服务。
在SM注册的服务大多都是系统的服务,也就说系统服务统一由SM管理,包括AMS,WIFI_SERVICE等。自己的服务怎么注册SM,暂不了解!