UbuntuではAndroid HALのためにJNI方法を編纂し、JAVAのハードウェアサービスインターフェースへのアクセスを提供しています。


前の2つの記事では、どのようにAndroidシステムのハードウェアのためにドライバを作成するかを紹介しました。Linuxカーネル空間でカーネルドライブを実現する方法と、ユーザー空間でハードウェアの抽象層インターフェースを実現する方法を含みます。この両者を実現する目的は、ハードウェアアクセスインターフェース、すなわちAndroidのAplication Frame ewarks層にハードウェアサービスを提供することである。AndroidシステムのアプリケーションはJava言語で作成されていますが、ハードウェアドライバはC言語で実現されています。JavaインターフェースはどうやってCインターフェースを訪問しますか?周知のように、JavaはJNI方法の呼び出しを提供しており、Androidシステムにおいても、JavaアプリケーションはJNIを介してハードウェア抽象層インターフェースを起動する。この記事では、上位のJavaアプリケーションが下の層から提供されるハードウェアサービスを利用できるように、Androidハードウェアの抽象層インターフェースのためにJNIを作成する方法を紹介します。
      一.Ubuntu Androidはハードウェア抽象層(HAL)モジュールのLinuxカーネルドライバへのアクセスを増加します。文を参照して、ハードウェア抽象層モジュールを準備し、Androidシステムのミラーファイルsystem.imgがハロー.defaultモジュールをすでに含んでいることを確認する。
      二.frame eworks/base/services/jniディレクトリに入り、com_を新規作成する。android_server_ハローサービス.cppファイル:
      USER-NAME@MACHINE-NAME:~/Android$cd frame eworks/base/services/jni
      USER-NAME@MACHINE-NAME://Android/frame ewarks/base/services/jni/vi com_android_server_ハローサービス.cpp
      comにありますandroid_server_ハローService.cppファイルで、JNIメソッドを実現します。ファイルの命令方法に注意してください。android_serverプレフィックスはパッケージ名を表し、ハードウェアサービスHelloServiceはフレームワーク/base/services/javaディレクトリの下に置かれているcom/android/serverディレクトリを示すもので、comp.android.server.HelloServiceというクラスがあります。ここでは、ハローサービス類の説明をしばらく省略して、次の文章でハローサービス類に戻ります。簡単に言えば、ハローServiceはJavaインターフェースを提供するハードウェアアクセスサービスクラスである。
      最初に対応するヘッダファイルを含む:

#define LOG_TAG "HelloService"
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/hardware.h>
#include <hardware/hello.h>
#include <stdio.h>
 次にハローキティを定義しますinit、ハローgetValとハローsetVal 3つのJNI方法:

namespace android
{
	/*                 ,  <hardware/hello.h>*/
 struct hello_device_t* hello_device = NULL;
	/*                       val  */
 static void hello_setVal(JNIEnv* env, jobject clazz, jint value) {
		int val = value;
		LOGI("Hello JNI: set value %d to device.", val);
		if(!hello_device) {
			LOGI("Hello JNI: device is not open.");
			return;
		}
		
		hello_device->set_val(hello_device, val);
	}
 /*                       val  */
	static jint hello_getVal(JNIEnv* env, jobject clazz) {
		int val = 0;
		if(!hello_device) {
			LOGI("Hello JNI: device is not open.");
			return val;
		}
		hello_device->get_val(hello_device, &val);
		
		LOGI("Hello JNI: get value %d from device.", val);
	
		return val;
	}
 /*                        */
	static inline int hello_device_open(const hw_module_t* module, struct hello_device_t** device) {
		return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
	}
 /*      ID                  */
	static jboolean hello_init(JNIEnv* env, jclass clazz) {
		hello_module_t* module;
		
		LOGI("Hello JNI: initializing......");
		if(hw_get_module(HELLO_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {
			LOGI("Hello JNI: hello Stub found.");
			if(hello_device_open(&(module->common), &hello_device) == 0) {
				LOGI("Hello JNI: hello device is open.");
				return 0;
			}
			LOGE("Hello JNI: failed to open hello device.");
			return -1;
		}
		LOGE("Hello JNI: failed to get hello stub module.");
		return -1;		
	}
 /*JNI   */
	static const JNINativeMethod method_table[] = {
		{"init_native", "()Z", (void*)hello_init},
		{"setVal_native", "(I)V", (void*)hello_setVal},
		{"getVal_native", "()I", (void*)hello_getVal},
	};
 /*  JNI  */
	int register_android_server_HelloService(JNIEnv *env) {
 		return jniRegisterNativeMethods(env, "com/android/server/HelloService", method_table, NELEM(method_table));
	}
};
 注意してください。ハローinit関数では、Androidハードウェアの抽象層を介して提供されるhw_ゲットするmodule方法はモジュールIDをロードしてHELLO_となります。HARDWARE_MODULE_IDのハードウェア抽象層モジュールは、HELLO_HARDWARE_MODULE_IDはで定義されています。Androidハードウェアの抽象層は、HELLO_によるとHARDWARE_MODULE_IDの値はAndroidシステムの/system/lib/hwディレクトリに該当するモジュールを見つけてロードし、hw_に戻ります。module_tインターフェイスは使用者に使用されます。jniRegister NativeMethods関数では、2番目のパラメータの値はハローServiceがあるパケットの経路、すなわちcomp.android.server.Hello Serviceに対応しなければならない。
      三.同じディレクトリのonload.cppファイルを修正し、まずnamespace androidにregister_を追加します。android_server_ハローService関数宣言:
namespace android{
      ..............................................................................................
      intレジスターandroid_server_ハローサービス(JNIEnv*env)
      };
 JNI_にいますone Load増加register_android_server_ハローService関数の呼び出し:
extern「C」ジンt JNI_オンロード(JavaVM*vm,void*rerrved)
      {
       .................................................................................................
       レジスターandroid_server_ハローサービス
       .................................................................................................
      }
 このように、Androidシステムが初期化されると、このJNIメソッド呼び出しテーブルが自動的にロードされます。
         四.同じディレクトリのAndroid.mkファイルを修正し、LOCAL_SRC_FILES変数に一行を追加します。
      LOCAL_SRC_FILES:=\
      comandroid_server_AlarmManager Service.cpp\
      comandroid_server_BatteryService.cpp\
      comandroid_server_InputManager.cpp\
      comandroid_server_Lights Service.cpp\
      comandroid_server_パワーManager Service.cpp\
      comandroid_server_System Server.cpp\
      comandroid_server_UsbService.cpp\
      comandroid_server_Vibrate Service.cpp\
      comandroid_server_location_GpspLocationProvider.cpp\
      comandroid_server_ハローサービス.cpp/
      onload.cpp
 五.コンパイルして、また億system.img:
      USER-NAME@MACHINE-NAME:~/Androidドルmmm frame eworks/base/services/jni
      USER-NAME@MACHINE-NAME:~/Android$make snod
      このように、新たにパッケージ化されたsystem.imgミラーファイルには、私たちが先ほど作成したJNI方法が含まれています。つまり、AndroidシステムのApplication Fraamew orks層から提供されたハードウェアサービスハローServiceを通じてこれらのJNI方法を呼び出し、さらに低層のハードウェア抽象層インターフェースを呼び出してハードウェアにアクセスすることができます。前に述べましたが、この文章ではハローサービスの実現をしばらく無視しています。次の記事では、ハードウェアサービスのハローサービスの実現方法を説明します。ご注意ください。
以上はJNIの方法を編纂してAndroidのハードウエアの抽象的な階の流れを訪問して、引き続き関連している知識を補充して、Androidのソースコードの学友を研究することを助けることができることを望みます。