Android HAL開發之基於Service的HAL設計

在上一篇文章中,我介紹了一種應用程序直接調用JNI庫的HAL設計方法,該方法雖然簡單,但是不符合Android的框架結構,下面我們介紹一種通過Service提供接口給應用程序的設計方法,結構如下:

HAL stub <-> JNI 庫 <-> JAVA Service <->JAVA 應用程序。

HAL stub的設計和上文一樣,JNI庫的設計中唯一需要修改的地方就是register_mokoid_server_LedService函數,在上文中該JNI庫直接提供給應用程序使用,而這裏,JNI庫是提供接口給JAVA Service使用,修改如下:

  1. int register_mokoid_server_LedService(JNIEnv* env) { 
  2.     //static const char* const kClassName = 
  3.       //  "com/mokoid/LedClient/LedClient"; 
  4.     static const charconst kClassName = 
  5.         "com/mokoid/server/LedService"
  6.     jclass clazz; 
  7.  
  8.     /* look up the class */ 
  9.     clazz = env->FindClass(kClassName); 
  10.     if (clazz == NULL) { 
  11.         LOGE("Can't find class %s\n", kClassName); 
  12.         return -1; 
  13.     } 
  14.  
  15.     /* register all the methods */ 
  16.     if (env->RegisterNatives(clazz, gMethods, 
  17.             sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK) 
  18.     { 
  19.         LOGE("Failed registering methods for %s\n", kClassName); 
  20.         return -1; 
  21.     } 
  22.  
  23.     /* fill out the rest of the ID cache */ 
  24.     return 0; 

在這裏,我們的JNI庫會提供給com.mokoid.server.LedService類使用,而不是上文中的應用程序com.mokoid.LedClient.LedClient類。該JNI庫最後會被編譯成libmokoid_runtime.so。

下面我們再看看com.mokoid.server.LedService的實現: 

  1. public final class LedService { 
  2.  
  3.     static { 
  4.         System.load("/system/lib/libmokoid_runtime.so"); 
  5.     } 
  6.  
  7.     public LedService() { 
  8.         Log.i("LedService""Go to get LED Stub..."); 
  9.     _init(); 
  10.     } 
  11.  
  12.     /* 
  13.      * Mokoid LED native methods. 
  14.      */ 
  15.     public boolean setOn(int led) { 
  16.         Log.i("MokoidPlatform""LED On"); 
  17.     return _set_on(led); 
  18.     } 
  19.  
  20.     public boolean setOff(int led) { 
  21.         Log.i("MokoidPlatform""LED Off"); 
  22.     return _set_off(led); 
  23.     } 
  24.  
  25.     private static native boolean _init(); 
  26.     private static native boolean _set_on(int led); 
  27.     private static native boolean _set_off(int led); 

這個Service的實現和上文中的應用程序的實現比較類似,也是通過System.load裝載JNI庫,然後就可以在自己的方法中使用JNI接口,該Service最後會被編譯成mokoid.jar,且位於/system/framework中,值得注意的是,應用程序如果要調用該Service,必須在/etc/perimissions中有一個xml文件,內容如下:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <permissions> 
  3.     <library name="com.mokoid.server" 
  4.             file="/system/framework/mokoid.jar"/> 
  5. </permissions> 

通過這個文件,應用程序就可以使用com.mokoid.server來找到mokoid.jar文件。

我們最後再來看看應用程序的實現:

  1. package com.mokoid.LedClient; 
  2. import com.mokoid.server.LedService; 
  3.  
  4. import android.app.Activity; 
  5. import android.os.Bundle; 
  6. import android.widget.TextView; 
  7.  
  8. public class LedClient extends Activity { 
  9.     @Override 
  10.     public void onCreate(Bundle savedInstanceState) { 
  11.         super.onCreate(savedInstanceState); 
  12.  
  13.         // Call an API on the library. 
  14.         LedService ls = new LedService(); 
  15.         ls.setOn(1); 
  16.         ls.setOff(2); 
  17.          
  18.         TextView tv = new TextView(this); 
  19.         tv.setText("LED 1 is on. LED 2 is off."); 
  20.         setContentView(tv); 
  21.     } 

這裏通過import com.mokoid.server.LedService來使用上面設計的LedService,然後通過new LedService()來得到Service的實例,之後就可以直接調用該Service的方法來控制Led了。

AndroidManifest.xml如下:

  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
  2.     package="com.mokoid.LedClient"> 
  3.      
  4.     <application> 
  5.      
  6.         <!-- This tells the system about the custom library used by the 
  7.              application, so that it can be properly loaded and linked 
  8.              to the app when the app is initialized. --> 
  9.         <uses-library android:name="com.mokoid.server" /> 
  10.          
  11.         <activity android:name="LedClient"> 
  12.             <intent-filter> 
  13.                 <action android:name="android.intent.action.MAIN"/> 
  14.                 <category android:name="android.intent.category.LAUNCHER"/> 
  15.             </intent-filter> 
  16.         </activity> 
  17.     </application> 
  18. </manifest> 

注意,uses-library告訴了系統該程序需要調用的非系統庫,既上面我們設計的Service庫。

本文出自 “Mobile and Linux Deve..” 博客,請務必保留此出處http://buaadallas.blog.51cto.com/399160/384902

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章