在上文中我们实现了利用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的控制。

本文出自 “Mobile and Linux Deve..” 博客,请务必保留此出处http://buaadallas.blog.51cto.com/399160/384919

更多相关文章

  1. 初识android 自定义控件
  2. Android(安卓)应用程序签名、发布
  3. 用Fragments在Android中进行多窗格开发
  4. Android(安卓)数字证书详
  5. 教你用电脑从 Google Play 下载 Android(安卓)程序 apk 文件
  6. Android(安卓)UI Operation in Thread
  7. Android(安卓)常用控件接口监听
  8. Android(安卓)----制作自己的Vendor
  9. 【QQ登录】Android_SDK使用说明

随机推荐

  1. 10个经典的Android开源项目
  2. 学习android的网站
  3. RelativeLayout的一些重要属性
  4. Android实习生 —— 网络请求及数据解析
  5. android canvas画图 切割画布(clipRect)
  6. Android加载本地网页
  7. android子线程不能更新UI
  8. Android ListView分两列显示(不用自定义Ad
  9. Android官网 打不开 解决办法
  10. android加载大图片到内存