一.服务端程序
1. 新建aidl文件,如ICameraCallback.aidl,添加客户端要回调的接口,例如:
package com.android.camera;
interface ICameraCallback {
void onResult(String msg);
}
2. 新建一个单例的类, 如CameraControler.java, 实现进程内通信相关的接口,内容如下:
package com.android.camera;
public class CameraControler {
private OnControlListener mListener = null;
private static CameraControler sInstance = null;
public static interface OnControlListener {
void registerCallback(ICameraCallback cb);
void unregisterCallback(ICameraCallback cb);
}
private CameraControler() {
}
public final static CameraControler getInstance() {
if (sInstance == null) {
synchronized (CameraControler.class) {
if (sInstance == null) {
CameraControler.sInstance = new CameraControler();
}
}
}
return sInstance;
}
public CameraControler setOnControlListener(OnControlListener listener) {
mListener = listener;
return this;
}
public void registerCallback(ICameraCallback cb) {
if(mListener==null)
return;
mListener.registerCallback(cb);
}
public void unregisterCallback(ICameraCallback cb) {
if(mListener==null)
return;
mListener.unregisterCallback(cb);
}
}
3. 在要回调的类中实现注册回调和释放回调的接口,并在要回调的地方调用回调,例如:
private RemoteCallbackList<ICameraCallback> mCallbacks = new RemoteCallbackList<ICameraCallback>();
private CameraControler mCameraControler = CameraControler.getInstance();
mCameraControler.setOnControlListener(new CameraControler.OnControlListener() {
@Override
public void registerCallback(ICameraCallback cb) {
if(mCallbacks!=null) mCallbacks.register(cb);
}
@Override
public void unregisterCallback(ICameraCallback cb) {
if(mCallbacks!=null) mCallbacks.unregister(cb);
}
});
public void onResult(String msg) {
if(mCallbacks!=null) {
int n = mCallbacks.beginBroadcast();
try {
for(int i=0;i<n;i++) {
mCallbacks.getBroadcastItem(i).onRtmpConnected(msg);
}
}catch(Exception e) {
e.printStackTrace();
}
mCallbacks.finishBroadcast();
}
}
4. 写一个服务,如CameraServer.java,声明单例对象,通过调用单例对象的对应接口注册和释放回调
package com.android.camera;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class CameraServer extends Service {
protected CameraControler mCameraControler = CameraControler.getInstance();
@Override
public IBinder onBind(Intent intent) {
return new ICameraServer.Stub() {
@Override
public void registerCallback(ICameraCallback cb) throws RemoteException {
mCameraControler.registerCallback(cb);
}
@Override
public void unregisterCallback(ICameraCallback cb) throws RemoteException {
mCameraControler.unregisterCallback(cb);
}
};
}
}
5. 在AndroidManifest.xml中添加服务的声明
<service
android:name="com.android.camera.CameraServer"
android:enabled="true"
android:label="@string/app_name" >
<intent-filter>
<intent-filter>
<action android:name="com.android.camera.ICameraServer" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</intent-filter>
</service>
6. 新建aidl文件,如ICameraServer.aidl,其中添加注册和释放回调的接口,导入回调接口时要import全名(不能只import包名)如下:
package com.android.camera;
import com.android.camera.ICameraCallback;
interface ICameraServer {
void registerCallback(ICameraCallback cb);
void unregisterCallback(ICameraCallback cb);
}
7. 如果要放到系统源码中编码, 需要在Android.mk中添加引用,如下:
LOCAL_SRC_FILES += src/com/android/camera/ICameraServer.aidl
LOCAL_SRC_FILES += src/com/android/camera/ICameraCallback.aidl
二. 客户端程序
1. 把aidl文件拷贝到客户端程序中, 注意: aidl文件包名要与服务器包名一致; 并在要调用aidl接口的文件中声明ICameraServer camera;
2. 创建ServiceConnection对象,并在onServiceConnected中注册回调,如下:
private ServiceConnection CameraConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
camera = ICameraServer.Stub.asInterface(service);
try {
camera.registerCallback(mCameraCallback);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
3. 初始化时调用如下代码:
Intent intent = new Intent();
intent.setClassName("com.android.gallery3d", "com.android.camera.CameraServer");
bindService(intent, CameraConnection, Context.BIND_AUTO_CREATE);
4. Destroy时注销回调并解绑服务:
if(camera!=null) {
try {
camera.unregisterCallback(mCameraCallback);
} catch (RemoteException e) {
e.printStackTrace();
}
}
unbindService(CameraConnection);
CameraConnection = null;