在上文中我们实现了利用Service来设计HAL,但是根据Android的框架,一般应用程序都不直接和Service打交到,中间需要经过一个Manager层。

我们在这里也按照Android的框架,进一步优化HAL的设计。结构如下:

HAL stub <-> JNI 库 <-> JAVA Service <-> Manager <-> JAVA 应用程序。

由于LedManager和LedService属于两个进程,他们之间的通信需要通过AIDL来实现,下面是ILedService.aidl

        
  1. packagemokoid.hardware;
  2. interfaceILedService
  3. {
  4. booleansetOn(intled);
  5. booleansetOff(intled);
  6. }

在这个文件中定义了LedService提供给LedManager的接口,经过aidl工具会被编译成ILedService.java文件。

我们再看看LedManager是如何实现的:

        
  1. publicclassLedManager
  2. {
  3. privatestaticfinalStringTAG="LedManager";
  4. privateILedServicemLedService;
  5. publicLedManager(){
  6. mLedService=ILedService.Stub.asInterface(
  7. ServiceManager.getService("led"));
  8. if(mLedService!=null){
  9. Log.i(TAG,"TheLedManagerobjectisready.");
  10. }
  11. }
  12. publicbooleanLedOn(intn){
  13. booleanresult=false;
  14. try{
  15. result=mLedService.setOn(n);
  16. }catch(RemoteExceptione){
  17. Log.e(TAG,"RemoteExceptioninLedManager.LedOn:",e);
  18. }
  19. returnresult;
  20. }
  21. publicbooleanLedOff(intn){
  22. booleanresult=false;
  23. try{
  24. result=mLedService.setOff(n);
  25. }catch(RemoteExceptione){
  26. Log.e(TAG,"RemoteExceptioninLedManager.LedOff:",e);
  27. }
  28. returnresult;
  29. }
  30. }

这里需要注意的是mLedService = ILedService.Stub.asInterface(nager.getService("led")); 通过这个函数可以得到LedService的实例,从而调用它的方法。

而对于LedService我们需要作一个小小的改变,如下:

        
  1. publicfinalclassLedServiceextendsILedService.Stub{
  2. static{
  3. System.load("/system/lib/libmokoid_runtime.so");
  4. }
  5. publicLedService(){
  6. Log.i("LedService","GotogetLEDStub...");
  7. _init();
  8. }
  9. /*
  10. *MokoidLEDnativemethods.
  11. */
  12. publicbooleansetOn(intled){
  13. Log.i("MokoidPlatform","LEDOn");
  14. return_set_on(led);
  15. }
  16. publicbooleansetOff(intled){
  17. Log.i("MokoidPlatform","LEDOff");
  18. return_set_off(led);
  19. }
  20. privatestaticnativeboolean_init();
  21. privatestaticnativeboolean_set_on(intled);
  22. privatestaticnativeboolean_set_off(intled);
  23. }

该LedService需要继承自ILedService.Stub从而实现AIDL接口与LedManager通信。

最后我们看看应用程序,在应用程序中,我们实现了一个service(注意和上面的service的区别)和一个activity,在service中start了LedService, 而在activity中通过LedManager来使用LedService中提供的接口。

我们首先来看看service的实现:

        
  1. publicclassLedSystemServerextendsService{
  2. @Override
  3. publicIBinderonBind(Intentintent){
  4. returnnull;
  5. }
  6. publicvoidonStart(Intentintent,intstartId){
  7. Log.i("LedSystemServer","StartLedService...");
  8. /*PleasealsoseeSystemServer.javaforyourinterests.*/
  9. LedServicels=newLedService();
  10. try{
  11. ServiceManager.addService("led",ls);
  12. }catch(RuntimeExceptione){
  13. Log.e("LedSystemServer","StartLedServicefailed.");
  14. }
  15. }
  16. }

这里需要注意的是ServiceManager.addService("led", ls); 通过它可以启动恰面创建的LedService。

我们再看看Activity的实现:

        
  1. publicclassLedTestextendsActivityimplementsView.OnClickListener{
  2. privateLedManagermLedManager=null;
  3. @Override
  4. publicvoidonCreate(BundlesavedInstanceState){
  5. super.onCreate(savedInstanceState);
  6. //StartLedServiceinaseperatedprocess.
  7. startService(newIntent("com.mokoid.systemserver"));
  8. Buttonbtn=newButton(this);
  9. btn.setText("ClicktoturnLED1On");
  10. btn.setOnClickListener(this);
  11. setContentView(btn);
  12. }
  13. publicvoidonClick(Viewv){
  14. //GetLedManager.
  15. if(mLedManager==null){
  16. Log.i("LedTest","CreatanewLedManagerobject.");
  17. mLedManager=newLedManager();
  18. }
  19. if(mLedManager!=null){
  20. Log.i("LedTest","GotLedManagerobject.");
  21. }
  22. /**CallmethodsinLedServiceviaproxyobject
  23. *whichisprovidedbyLedManager.
  24. */
  25. mLedManager.LedOn(1);
  26. TextViewtv=newTextView(this);
  27. tv.setText("LED1isOn.");
  28. setContentView(tv);
  29. }
  30. }

当这个activity创建的时候,会通过intent开启上面定义的LedSystemServer,该LedSystemServer会开启前面定义的LedService,当点击button的时候,会new一个LedManager,该LedManager会通过ServiceManager.addService("led", ls)得到LedService的实例,并且提供LedService中的接口给这个activity使用,从而在该activity中实现对Led的控制。

更多相关文章

  1. Android 中,应用程序需要的图片资源如何针对不同屏幕大小手机设计
  2. 分析点击android桌面app图标启动应用程序的过程
  3. Android之Merge及自定义属性attrs.xml使用
  4. Android如何自定义一个view——绘制篇
  5. android 深入研究ratingbar自定义
  6. Android应用程序框架层和系统运行库层日志系统源代码分析
  7. Android - 自定义Dialog内部透明,外部有遮罩
  8. android C/C++ source files 全局宏定义 .
  9. android,总结,判断应用程序是否切换到后台

随机推荐

  1. List集合就这么简单【源码剖析】
  2. 每个人理解的设计模式应该都不太一样
  3. 《面向模式的软件体系结构 - 卷1 模式系
  4. 单例模式在开源代码中的应用
  5. 运维转管理的成长之路
  6. 工厂模式在开源代码中的应用
  7. String常量地址变动引起的诡异结果
  8. 建造者模式和原型模式在开源代码中的应用
  9. 最想放弃的时候,离成功最近
  10. 见到了点曙光