您的位置:首页 > 移动开发 > Android开发

定制Android系统开发之九——在系统服务中实现回调

2016-01-04 16:28 513 查看
在上一篇博文里,我已经实现了从JNI到Java系统服务的回调。数据已经传回到java里了,那么下面的问题就是如何将数据传回到APP端。这篇博文将解决这个问题。

在前面的博文里,我曾说过,Android中的系统服务是客户端/服务器模式,所以,在下文中,客户端统一指SystemManager,服务端统一指SystemManagerService。

在客户端中定义注册回调的函数

第一步,当然是定义一个Listener接口。在framework/base/core/java/android/os/下定义SystemManagerListener接口如下:

package android.os;

public interface SystemManagerListener {
/**
* @param process
*/
void onProgress(int process);
}


然后在SystemManager中定义注册回调的函数:

/**
* 注册回调。
*
* @param listener
* @return 成功返回0,失败请参考错误码ErrorCode
*/
public int registerListener(SystemManagerListener listener) {}


在服务端中实现注册回调的函数

我们知道,在系统服务的模型中,客户端的工作只有一个,就是调用服务端的对应的函数,所以在registerListener中,将调用SystemManagerService中的registerListener函数。那么,问题来了,SystemManagerService中的registerListener是在ISystemManager.aidl中实现的,但是aidl的参数不能直接传递普通的接口,只能传递由aidl定义的接口。而我们的SystemManagerListener需要暴露给APP端,只能是个普通的接口,不能用aidl来定义。这个矛盾怎么解决呢?我在LocationManager中找到了解决方案(所有的问题都可以在Android源码中找到参考!!!),那就是定义一个SystemManagerListenerTransfer类实现ISystemManagerListener.aidl定义的接口。代码如下:

// 定义ISystemManagerListener
interface ISystemManagerListener{
/**
* @param process
*/
void onProgress(int process);
}

// =======================================================

// 在ISystemManager中定义registerListener函数
import android.os.iflytek.ISystemManagerListener;

/**
* 注册回调。
*
* @param listener
* @return 成功返回0,失败请参考错误码ErrorCode
*/
int registerListener(ISystemManagerListener listener);

// =======================================================

// 实现SystemManagerListenerTransfer
public class SystemManagerListenerTransfer extends ISystemManagerListener.Stub{
private static final String TAG = "TimothySystemManagerListenerTransfer";
private SystemManagerListener mListener;

public SystemManagerListenerTransfer(SystemManagerListener listener){
this.mListener = listener;
}

@Override
public void onProgress(int process) throws RemoteException {
Log.d(TAG, "onProgress() is called, process = " + process);
mListener.onProgress(process);
}
}


这样的实现方式,只需要用传入SystemManager的SystemManagerListener构造一个SystemManagerListenerTransfer,用这个Transfer传入SystemManagerService即可。当在Service中调用Transfer的onProgress的时候,实际上调用的就是Listener的onProgress。

到这里,在服务端中实现registerListener函数就很简单了,这里直接贴代码:

public int registerListener(ISystemManagerListener listener) throws RemoteException {
Log.d(TAG, "registerListener() is called");
this.mSystemManagerListener = listener;
}


在客户端中实现注册回调的函数

回过头来,实现SystemManager中registerListener如下:

try {
SystemManagerListenerTransfer transfer = new SystemManagerListenerTransfer(listener);
return mService.registerListener(transfer);
} catch (RemoteException e) {
e.printStackTrace();
return SystemManagerCons.ErrorCode.ERROR_REMOTE_EXCEPTION;
}


实现注销Listener函数

注销Listener的实现过程和注册类似,只需在SystemManagerService的unregisterListener中将mSystemManagerListener置空即可。

回调函数的调用

调用这个回调函数就很简单了,在JNI的java函数里面,使用下面的一行代码即可:

mSystemManagerListener.onProgress(xxx);


写在最后

有一点要注意:所有的aidl都要在Android.mk中声明,不然编译一定会出错哦!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: