C/C++中寫的程序可以避開JVM的內(nèi)存開銷過大的相知、處理高性能的計算、調(diào)用系統(tǒng)服務(wù)等,但是java調(diào)用jni空方法和java調(diào)用java方法相比,性能非常低的。所以一般只用來處理一些對運算有要求,或者需要對接口隱蔽的功能。
JNI 一般編寫流程 其實就是為了避免一些錯誤 用javah生成jni函數(shù)名,還是值得推薦使用的。驗證過,可以生成。比較使用的小技巧。

javac src/com/example/com/enjoy/test/test.java -d ./bin
javah -jni -classpath ./bin -d ./jni com.example.com.enjoy.test.test

- apk crash 有l(wèi)og 可以定位,程序的anr 會在記錄在/data/anr/traces.txt mtk aee log也有。
但是NDK Crash 定位就很難了 ,容易出錯的地方有 內(nèi)存地址訪問錯誤 使用野指針 內(nèi)存泄露 堆棧溢出 初始化錯誤 類型轉(zhuǎn)換錯誤 數(shù)字除0(11/0) 等等
使用ndk-stack 進(jìn)行定位到行。

- 因為 Java 默認(rèn)使用 Unicode 編碼,而 C/C++默認(rèn)使用 UTF 編碼,所以在本地代碼中操作字符串的時候,必須使用合適的 JNI 函數(shù)把 jstring 轉(zhuǎn)換成 C 風(fēng)格的字符串。 JNI 支持字符串在 Unicode和 UTF-8 兩種編碼之間轉(zhuǎn)換,GetStringUTFChars 可以把一個 jstring 指針(指向 JVM 內(nèi)部的 Unicode字符序列)轉(zhuǎn)換成一個 UTF-8 格式的 C 字符串。
-調(diào)用完 GetStringUTFChars 之后不要忘記安全檢查,因為 JVM 需要為新誕生的字符串分配內(nèi)存空間,當(dāng)內(nèi)存空間不夠分配的時候,會導(dǎo)致調(diào)用失敗,失敗后 GetStringUTFChars 會返回 NULL,并拋出一個 OutOfMemoryError 異常。JNI 的異常和 Java 中的異常處理流程是不一樣的,Java 遇到異常如果沒有捕獲,程序會立即停止運行。而 JNI 遇到未決的異常不會改變程序的運行流程,也就是程序會繼續(xù)往下走 - 接口找不到
在Java中調(diào)用JNI接口時,出現(xiàn)異常,察看日志,發(fā)現(xiàn)有如下錯誤:
WARN/dalvikvm(422): No implementation found for native Lcom/whty/wcity/HelixPlayer;.setDllPath (Ljava/lang/String;)V
檢查了幾遍代碼,Cpp中確實定義了這個接口,而且仔細(xì)對照了Java的包名、類名,確實沒有錯誤,那為什么會出現(xiàn)這種問題呢。后來突然想到,JNI接口 都是以C的方式定義的,現(xiàn)在使用C++實現(xiàn),函數(shù)定義前是否需要加上extern "C"呢?為此定義了一個頭文件,在CPP文件中include該頭文件,頭文件加上如下代碼片斷:
ifdef __cplusplus
extern "C" {
endif
endif
...
ifdef __cplusplus
}
再次嘗試,調(diào)用成功!
- MTK flash tool 刷機(jī)問題 ubuntu 下刷機(jī) 出現(xiàn)了異常。
BROM ERROR : STATUS_ERR (-1073676287)
STATUS_BROM_CMD_SEND_DA_FAIL
chip mismatch MT0000
這幾個問題 直接用ok機(jī)器的
/etc/udev/rules.d/ 目錄下文件全部替換即可
jni讀寫文件 open 時候出錯 fd 返回-1 文件節(jié)點權(quán)限是666
剛開始以為是權(quán)限問題,chmod 666后發(fā)現(xiàn)還是不行使用java 文件流進(jìn)行讀寫 發(fā)現(xiàn)讀是ok的
寫時候出現(xiàn)異常 后面公司大神改了下驅(qū)動 將模塊驅(qū)動中映射的open函數(shù)直接返回0
還是不行 。
最后自己懷疑是selinux 問題

我的avc 異常:
[ 138.125449] <6>.(6)[283:logd.auditd]type=1400 audit(1496479197.368:93): avc: denied { read write } for pid=3144 comm="m.enjoy.testjni" name="ttctl" dev="tmpfs" ino=11250 scontext=u:r:system_app:s0 tcontext=u:object_r:ttctl_device:s0 tclass=chr_file permissive=0
修改:
/alps/device/mediatek/common/sepolicy/system_app.te
+allow system_app ttctl_device:chr_file { read write ioctl open };
還沒驗證 下周再驗證吧。編譯實在是太慢了。
周一了周六遺留的問題解決了看log很重要,但是ioctl 返回值-1剩下就要看驅(qū)動了。
-在framework PowerManger中添加 接口,update-api 發(fā)現(xiàn)mmm但編譯之后 一直報方法未重寫,但實際已經(jīng)重寫,不明原因,直接根目錄下全編一次就好了。
- 報checkJni錯誤一般在jni映射函數(shù)中出錯了,比如返回類型沒寫對