日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android系统的JNI原理分析(二)- 数据类型转换和方法签名

發(fā)布時(shí)間:2024/1/1 Android 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android系统的JNI原理分析(二)- 数据类型转换和方法签名 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

聲明

  • 前階段在項(xiàng)目中使用了Android的JNI技術(shù),在此文中做些技術(shù)知識(shí)總結(jié)。
  • 本文參考了一些書籍的若干章節(jié),比如《Android進(jìn)階解密-第9章-JNI原理》、《深入理解Android虛擬機(jī)-第4章-分析JNI》、《深入理解Android系統(tǒng)-第2章-分析JNI》、《Android NDK Beginner_'s Guide》等
  • 本文使用的代碼時(shí)LineageOS的cm-14.1,對(duì)應(yīng)Android 7.1.2,可以參考我的另一篇博客:cm-14.1 Android系統(tǒng)啟動(dòng)過(guò)程分析(〇)-如何下載Nexus5的LineageOS14.1(cm-14.1)系統(tǒng)源碼并編譯、刷機(jī)

1 Java層和JNI層的數(shù)據(jù)類型轉(zhuǎn)換

????進(jìn)入到源碼路徑:
vim ~/LineageOS/frameworks/base/media/jni/android_
media_MediaRecorder.cpp,查看函數(shù)android_media_MediaRecorder_native_setup:

static void android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,jstring packageName, jstring opPackageName) {ALOGV("setup");ScopedUtfChars opPackageNameStr(env, opPackageName);sp<MediaRecorder> mr = new MediaRecorder(String16(opPackageNameStr.c_str()));if (mr == NULL) {jniThrowException(env, "java/lang/RuntimeException", "Out of memory");return;}if (mr->initCheck() != NO_ERROR) {jniThrowException(env, "java/lang/RuntimeException", "Unable to initialize media recorder");return;}// create new listener and give it to MediaRecordersp<JNIMediaRecorderListener> listener = new JNIMediaRecorderListener(env, thiz, weak_this);mr->setListener(listener);// Convert client name jstring to String16const char16_t *rawClientName = reinterpret_cast<const char16_t*>(env->GetStringChars(packageName, NULL));jsize rawClientNameLen = env->GetStringLength(packageName);String16 clientName(rawClientName, rawClientNameLen);env->ReleaseStringChars(packageName,reinterpret_cast<const jchar*>(rawClientName));// pass client package name for permissions trackingmr->setClientName(clientName);setMediaRecorder(env, thiz, mr); }

????其中jobject、jstring類型參數(shù)都是JNI層的數(shù)據(jù)類型,Java層數(shù)據(jù)類型到JNI層就要轉(zhuǎn)換為JNI層數(shù)據(jù)結(jié)構(gòu)。包括基本數(shù)據(jù)類型引用數(shù)據(jù)類型

1.1 Java層至JNI層基本數(shù)據(jù)類型的轉(zhuǎn)換

Java類型JNI類型C++類型關(guān)系描述簽名占內(nèi)存大小
booleanjbooleanunsigned char 或 unit8_t布爾類型Z1
intjintint或long整形I4
floatjfloatfloat單精度類型F4
doublejdoubledouble雙精度類型D8
longjlonglong長(zhǎng)整形J8
shortjshortshort短整型S2
charjcharunsigned short字符C2
bytejbytesigned char字節(jié)類型B1
voidvoidvoid空類型V

????從轉(zhuǎn)換表中可以看出Java層基本數(shù)據(jù)類型轉(zhuǎn)換到JNI層只需將數(shù)據(jù)類型前加個(gè)“j”即可(除了void類型)。

1.2 Java層至JNI層引用數(shù)據(jù)類型的轉(zhuǎn)換

JavaNative簽名(以;結(jié)尾)
所有對(duì)象jobjectL+classname +;
ClassjclassLjava/lang/Clas;
StringjstringLjava/lang/String;
TrowablejthrowableLjava/lang/Throwable;
Object[]jobjectArray[L+classname +;
byte[]jbyteArray[B
char[]jcharArray[C
double[]jdoubleArray[D
float[]jfloatArray[F
int[]jintArray[I
short[]jshortArray[S
long[]jlongArray[J
boolean[]jbooleanArray[Z

????以~/LineageOS/frameworks/base/media/java/android/media/
MediaRecorder.java中的native_setup方法為例:

private native final void native_setup(Object mediarecorder_this,String clientName, String opPackageName) throws IllegalStateException;

????對(duì)應(yīng)在~/LineageOS/frameworks/base/media/jni/android_
media_MediaRecorder.cpp,查看函數(shù)android_media_MediaRecorder_native_setup:

static void android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,jstring packageName, jstring opPackageName) { ...省略n行... }

????可以發(fā)現(xiàn):Object類型轉(zhuǎn)換為jobject類型,String類型轉(zhuǎn)換為jstring類型。

2 方法簽名

????進(jìn)入到源碼路徑: vim ~/LineageOS/frameworks/base/media/jni/
android_media_MediaRecorder.cpp,在數(shù)組gMethods[]中可看到簽名信息:

static const JNINativeMethod gMethods[] = {{"setCamera", "(Landroid/hardware/Camera;)V", (void *)android_media_MediaRecorder_setCamera},{"setVideoSource", "(I)V", (void *)android_media_MediaRecorder_setVideoSource},{"setAudioSource", "(I)V", (void *)android_media_MediaRecorder_setAudioSource},{"setOutputFormat", "(I)V", (void *)android_media_MediaRecorder_setOutputFormat},{"setVideoEncoder", "(I)V", (void *)android_media_MediaRecorder_setVideoEncoder},{"setAudioEncoder", "(I)V", (void *)android_media_MediaRecorder_setAudioEncoder},{"setParameter", "(Ljava/lang/String;)V", (void *)android_media_MediaRecorder_setParameter},{"_setOutputFile", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaRecorder_setOutputFileFD},{"setVideoSize", "(II)V", (void *)android_media_MediaRecorder_setVideoSize},{"setVideoFrameRate", "(I)V", (void *)android_media_MediaRecorder_setVideoFrameRate},{"setMaxDuration", "(I)V", (void *)android_media_MediaRecorder_setMaxDuration},{"setMaxFileSize", "(J)V", (void *)android_media_MediaRecorder_setMaxFileSize},{"_prepare", "()V", (void *)android_media_MediaRecorder_prepare},{"getSurface", "()Landroid/view/Surface;", (void *)android_media_MediaRecorder_getSurface},{"getMaxAmplitude", "()I", (void *)android_media_MediaRecorder_native_getMaxAmplitude},{"start", "()V", (void *)android_media_MediaRecorder_start},{"stop", "()V", (void *)android_media_MediaRecorder_stop},{"pause", "()V", (void *)android_media_MediaRecorder_pause},{"resume", "()V", (void *)android_media_MediaRecorder_resume},{"native_reset", "()V", (void *)android_media_MediaRecorder_native_reset},{"release", "()V", (void *)android_media_MediaRecorder_release},{"native_init", "()V", (void *)android_media_MediaRecorder_native_init},{"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V",(void *)android_media_MediaRecorder_native_setup},{"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize},{"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface }, };

????簡(jiǎn)單地說(shuō),存在簽名的原因就是Java語(yǔ)言的方法是可以重載的,重載的方法名字相同而參數(shù)不同,所以JNI僅通過(guò)方法名無(wú)法確定對(duì)應(yīng)的是重載的哪個(gè)方法,必須要參數(shù)簽名來(lái)輔助其關(guān)聯(lián)。

避免博客拖太長(zhǎng),后續(xù)參見(jiàn)下篇Android系統(tǒng)的JNI原理分析(三)- JNIEnv

總結(jié)

以上是生活随笔為你收集整理的Android系统的JNI原理分析(二)- 数据类型转换和方法签名的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。