这一节,我们将修改APP,使用反射的方法去操控硬件。 打开AS工程app-> java-> com.example.administrator中的MainActivity.java文件。注释文件中的以下代码
//import android.os.ServiceManager;
//import android.os.ILedService;
//iLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));
我们用反射的方法,实现ILedService.Stub.asInterface(ServiceManager.getService(“led”)),我们在源码打开ServiceManager.java, 其中的红框中的hide代表代表这是一个隐藏的类,并不直接提供的客户使用,继续往下查看
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
这是一个静态函数,需要的参数是String name,在 protected void onCreate()中添加如下代码,
+ Method getService = Class.forName("android.os.ServiceManager").getMethod("getService",String.class);
+ IBinder ledService = (IBinder) getService.invoke(null,"led");
+ Method asInterface = Class.forName("android.os.ILedService$Stub").getMethod("asInterface",IBinder.class);
+ proxy = asInterface.invoke(null,ledService);
+ ledCtrl = Class.forName("android.os.ILedService$Stub$Proxy").getMethod("ledCtrl", int.class, int.class);
1.我们从"android.os.ServiceManager"中获取"getService"方法,并且保存为Method getService。 2.调用getService方法传入“led”参数,获取IBinder ledService结构体,为下面方法调用做准备 3.获取"android.os.ILedServiceStub"中的"asInterface"方法。 4.调用asInterface方法,目的是获得Object proxy结构体,后续调用ledCtrl方法需要该参数 5.从"android.os.ILedServiceStubProxy"中获取ledCtrl 方法。
我们还需要添加如下变量
private CheckBox checkBoxLed2 = null;
- // private ILedService iLedService = null;
+ Object proxy = null;
+ Method ledCtrl = null;
把他们作为类中的变量,这样方便调用,然后把iLedService.ledCtrl全部替换成ledCtrl.invoke,举例如下
- //iLedService.ledCtrl(0,1);
+ ledCtrl.invoke(proxy,0,1);
这样我们通过反射访问硬件服务就可以实现了,在开发板运行即可。
该小节节比较简单,主要是想记录一下,通过反射实现对硬件服务的访问
章节结语到这里,我们第二章节就结束了。相信通过学习,大家对android的硬件访问服务已经有了一定的了解,从下章节开始,我们正式进入实战阶段。