如果有其他的java 文件, 需要参考 Framework中添加新的模块
在custom包下添加aidl文件 ICCCService.aidl
package android.custom;
interface ICCCService {
void setVal(String key,String value);
String getVal(String key);
}
编译后得到的classes.jar文件就包含有ICCCService接口,它继承了android.os.IInterface接口,classes.jar的路径为:/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
public class CCCService extends ICCCService.Stub {
private static HashMap<String,String> map=new HashMap<>();
private static String inner_log="";
public CCCService( ) {
}
@Override
public void setVal(String key, String value) throws RemoteException {
map.put(key,value);
}
@Override
public String getVal(String key) throws RemoteException {
return map.get(key);
}
}
在SystemServer 中startOtherServices中添加自定义的server, 并在Context 中添加常量: CCC_SERVICE = “ccc”
try {
Slog.i(TAG, "CCC Service");
ServiceManager.addService(Context.CCC_SERVICE, new CCCService());
} catch (Throwable e) {
Slog.e(TAG, "Failure starting CCC Service", e);
}
public class CCCManager {
ICCCService mService;
public CCCManager(Context ctx,ICCCService service){
mService=service;
}
public void setVal(String key,String value){
try{
mService.setVal(key,value);
}catch(Exception e){
Log.e("CCCManager",e.toString());
e.printStackTrace();
}
}
public String getVal(String key){
try{
return mService.getVal(key);
}catch(Exception e){
Log.e("CCCManager",e.toString());
e.printStackTrace();
}
return null;
}
}
registerService(Context.CCC_SERVICE, CCCManager.class, new CachedServiceFetcher<CCCManager>() {
@Override
public CCCManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.CCC_SERVICE);
ICCCService service = ICCCService.Stub.asInterface(b);
return new CCCManager(ctx, service);
}});
type ccc_service, system_api_service, system_server_service, service_manager_type;
ccc u:object_r:ccc_service:s0
// 前面的ccc 为添加在Contxet中的 ccc_service 是上面添加的系统服务
新建项目通过CCCManager manager = (CCCManager)getSystemService(“ccc”);
其中 CCCManager 可能会报错, 可以通过library, 可以新建一个CCCManager类,编译一个jar/aar, 导出jar包到现在目录,引用jar包, 再正常使用。需要注意的是应用层的manager的包名需做成和低层包名一致。
验证时可以不用修改external/sepolicy/service.te/ external/sepolicy/service_contexts 到设备,
如果只是在framework内部使用的话, 就不用做6,7,8,9,10 步。 只需前面1–5 步即可。
首先把上面编译出来的classes.jar导入到项目中,(暂时验证未发现后面描述错误 : 注意添加user Library时,要把as system Library勾选上,否则编译时会报Unable to execute dex: Java heap space的错误)
然后需要用的地方
IBinder binder = ServiceManager.getService("ccc");
ICCCService anInterface = ICCCService.Stub.asInterface(binder);
再通过 anInterface 调用 aidl中的方法. 类似manager 注册的地方
同理可以通过这个classes.jar 获取更多的系统中的服务,
应用层复制同样一份aidl文件, 编译后生成对应的java文件, 通过反射拿到系统的服务 IBinder:
private IBinder getService(String armService) { //armService 为注册时的名称ccc
IBinder iBinder = null;
try {
Class<?> clz = Class.forName("android.os.ServiceManager");
Method checkService = clz.getMethod("getService", String.class);
checkService.setAccessible(true);
iBinder = (IBinder) checkService.invoke(clz.newInstance(), armService);
} catch (Exception e) {
e.printStackTrace();
}
return iBinder;
}
ICCCService anInterface = ICCCService.Stub.asInterface(binder);
通过 anInterface 即可调用对应的方法;
同理在aidl文件夹定义个 ICallBack.aidl 文件,
package android.custom;
interface ICallBack {
void onProgress(String progressState);
}
在 ICCCService.aidl 中声明注册方法:
package android.custom;
import android.custom.ICallBack;
interface ICCCService {
void setVal(String key,String value);
String getVal(String key);
void registerCallBack(in ICallBack callback);
}
同理应用层需更新对应的 aidl 文件。
ICallBack.Stub callBack = new ICallBack.Stub(){
@Override
public void onProgress(String progress) throws RemoteException {
Log.d(TAG, "onProgress: --------???---------"+progress);
}
};
在绑定上服务的时候, 调用 anInterface.registerCallBack(callBack);
即可
注意: 在全编系统时可能会报错, 未知包名unknown package name of class file android/custom, 需要在
build/core/tasks/check_boot_jars/package_whitelist.txt 中添加该包名,
参考 https://www.jianshu.com/p/634d71e31a9d 修改