在上文中我们实现了利用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(安卓)Gallery控件使用方法详解
  2. Android(安卓)应用程序开关GPS
  3. Android(安卓)应用程序开发环境搭建说明
  4. android自学笔记《四》——应用程序结构分析
  5. Android(安卓)开发自定义使用svg构造交互式中国(各国)地图
  6. Android(安卓)MVP模式中,单个Activity/Fragment如何对应多个VP
  7. Android中快速实现自定义字体!
  8. Android服务器端开发
  9. 一步一步学android之布局管理器——FrameLayout

随机推荐

  1. Android开发我音乐App
  2. Android自定义属性时TypedArray的使用方
  3. 关于EditText的一点深入的了解
  4. Android滑动到顶部和底部时出现的阴影如
  5. Android读取assets目录下文件数据内容
  6. Android(安卓)创建与解析XML(一)—— 概述
  7. android 轻松实现语音识别
  8. Android中资源文件的使用
  9. Android(安卓)Webview 基本使用总结
  10. 使用jQuery Mobile和Phone Gap开发Androi