Android HAL实现的三种方式(3) - 基于Manager的HAL设计
在上文中我们实现了利用Service来设计HAL,但是根据Android的框架,一般应用程序都不直接和Service打交到,中间需要经过一个Manager层。
我们在这里也按照Android的框架,进一步优化HAL的设计。结构如下:
HAL stub <-> JNI 库 <-> JAVA Service <-> Manager <-> JAVA 应用程序。
由于LedManager和LedService属于两个进程,他们之间的通信需要通过AIDL来实现,下面是ILedService.aidl
- packagemokoid.hardware;
- interfaceILedService
- {
- booleansetOn(intled);
- booleansetOff(intled);
- }
在这个文件中定义了LedService提供给LedManager的接口,经过aidl工具会被编译成ILedService.java文件。
我们再看看LedManager是如何实现的:
- publicclassLedManager
- {
- privatestaticfinalStringTAG="LedManager";
- privateILedServicemLedService;
- publicLedManager(){
- mLedService=ILedService.Stub.asInterface(
- ServiceManager.getService("led"));
- if(mLedService!=null){
- Log.i(TAG,"TheLedManagerobjectisready.");
- }
- }
- publicbooleanLedOn(intn){
- booleanresult=false;
- try{
- result=mLedService.setOn(n);
- }catch(RemoteExceptione){
- Log.e(TAG,"RemoteExceptioninLedManager.LedOn:",e);
- }
- returnresult;
- }
- publicbooleanLedOff(intn){
- booleanresult=false;
- try{
- result=mLedService.setOff(n);
- }catch(RemoteExceptione){
- Log.e(TAG,"RemoteExceptioninLedManager.LedOff:",e);
- }
- returnresult;
- }
- }
这里需要注意的是mLedService = ILedService.Stub.asInterface(nager.getService("led")); 通过这个函数可以得到LedService的实例,从而调用它的方法。
而对于LedService我们需要作一个小小的改变,如下:
- publicfinalclassLedServiceextendsILedService.Stub{
- static{
- System.load("/system/lib/libmokoid_runtime.so");
- }
- publicLedService(){
- Log.i("LedService","GotogetLEDStub...");
- _init();
- }
- /*
- *MokoidLEDnativemethods.
- */
- publicbooleansetOn(intled){
- Log.i("MokoidPlatform","LEDOn");
- return_set_on(led);
- }
- publicbooleansetOff(intled){
- Log.i("MokoidPlatform","LEDOff");
- return_set_off(led);
- }
- privatestaticnativeboolean_init();
- privatestaticnativeboolean_set_on(intled);
- privatestaticnativeboolean_set_off(intled);
- }
该LedService需要继承自ILedService.Stub从而实现AIDL接口与LedManager通信。
最后我们看看应用程序,在应用程序中,我们实现了一个service(注意和上面的service的区别)和一个activity,在service中start了LedService, 而在activity中通过LedManager来使用LedService中提供的接口。
我们首先来看看service的实现:
- publicclassLedSystemServerextendsService{
- @Override
- publicIBinderonBind(Intentintent){
- returnnull;
- }
- publicvoidonStart(Intentintent,intstartId){
- Log.i("LedSystemServer","StartLedService...");
- /*PleasealsoseeSystemServer.javaforyourinterests.*/
- LedServicels=newLedService();
- try{
- ServiceManager.addService("led",ls);
- }catch(RuntimeExceptione){
- Log.e("LedSystemServer","StartLedServicefailed.");
- }
- }
- }
这里需要注意的是ServiceManager.addService("led", ls); 通过它可以启动恰面创建的LedService。
我们再看看Activity的实现:
- publicclassLedTestextendsActivityimplementsView.OnClickListener{
- privateLedManagermLedManager=null;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- //StartLedServiceinaseperatedprocess.
- startService(newIntent("com.mokoid.systemserver"));
- Buttonbtn=newButton(this);
- btn.setText("ClicktoturnLED1On");
- btn.setOnClickListener(this);
- setContentView(btn);
- }
- publicvoidonClick(Viewv){
- //GetLedManager.
- if(mLedManager==null){
- Log.i("LedTest","CreatanewLedManagerobject.");
- mLedManager=newLedManager();
- }
- if(mLedManager!=null){
- Log.i("LedTest","GotLedManagerobject.");
- }
- /**CallmethodsinLedServiceviaproxyobject
- *whichisprovidedbyLedManager.
- */
- mLedManager.LedOn(1);
- TextViewtv=newTextView(this);
- tv.setText("LED1isOn.");
- setContentView(tv);
- }
- }
当这个activity创建的时候,会通过intent开启上面定义的LedSystemServer,该LedSystemServer会开启前面定义的LedService,当点击button的时候,会new一个LedManager,该LedManager会通过ServiceManager.addService("led", ls)得到LedService的实例,并且提供LedService中的接口给这个activity使用,从而在该activity中实现对Led的控制。
更多相关文章
- Android 中,应用程序需要的图片资源如何针对不同屏幕大小手机设计
- 分析点击android桌面app图标启动应用程序的过程
- Android之Merge及自定义属性attrs.xml使用
- Android如何自定义一个view——绘制篇
- android 深入研究ratingbar自定义
- Android应用程序框架层和系统运行库层日志系统源代码分析
- Android - 自定义Dialog内部透明,外部有遮罩
- android C/C++ source files 全局宏定义 .
- android,总结,判断应用程序是否切换到后台