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インターフェースを提供するハードウェアアクセスサービスクラスである。
最初に対応するヘッダファイルを含む:で定義されています。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のソースコードの学友を研究することを助けることができることを望みます。
一.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は三.同じディレクトリの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のソースコードの学友を研究することを助けることができることを望みます。