Android studio NDK開發 從入門到實踐二
這一節開始將,怎麼將公司扔給你的c程式碼封裝成android的so庫呢.
1.給自己的c程式碼新增log
c程式碼中的log,在ndk開發中,他是不能直接列印到我們android studio中.
https://www.cnblogs.com/0616--ataozhijia/p/5628291.html根據這個來就可以了.
用法:
LOGE("a:%d,c:%c",a,b);
2.開始我們介面封裝了.
<1.這個時候我要了解所有的jni函式
從簡單開始.
先看如下java和本地型別,本地型別是說jni中的型別
Java 型別 |
本地型別 |
說明 |
boolean |
jboolean |
無符號,8 位 |
byte |
jbyte |
無符號,8 位 |
char |
jchar |
無符號,16 位 |
short |
jshort |
有符號,16 位 |
int |
jint |
有符號,32 位 |
long |
jlong |
有符號,64 位 |
float |
jfloat |
32 位 |
double |
jdouble |
64 位 |
void |
void |
N/A |
型別簽名 |
Java 型別 |
Z |
boolean |
B |
byte |
C |
char |
S |
short |
I |
int |
J |
long |
F |
float |
D |
double |
L fully-qualified-class ; |
全限定的類 |
[ type |
type[] |
注: 下面程式碼,我是.cpp的檔案,所以不需要加env引數
jstring jstr = env->NewStringUTF("hhhh");
//可以將"hhhh"轉換成jstring,或者將char* 轉換成 jstring. 如果你想將字串"hhhh",轉換成jni識別的jstring的話可以這麼轉換.
const
//可以將jstring轉換成char*,這是將jstring轉換成c程式碼識別的char* 字串. 這個一般用在將java程式碼傳遞字串引數到c函式中,通過轉換成c的字串,供c使用.
const char*str = env->GetStringUTFChars(jstr,0);//可以將jstring 轉換成 char* UTF格式
//可以將jstring轉換成char*,這是將jstring轉換成c程式碼識別的char* 字串. 這個一般用在將java程式碼傳遞字串引數到c函式中,通過轉換成c的字串,供c使用.
jsize lenth = env->GetStringLength(jstr);//獲取jstring字串的長度
//獲取jstring的長度
jstring js = env->NewStringUTF(str);//將char*轉換成jstring型別
可以將char*轉成成jstring型別. 一般用來將c的char*型別轉換成jstring型別,然後把jstring做為返回值 return jstring;
jclass jcls = env->FindClass("com/viking/jni2/JniCls1");//根據包名類名獲取jclass
根據java中的包名和類名,獲取jclass. jclass 有很多用途 ,比如說在c中建立java物件,獲取java類中變數的id,獲取Java類中方法的id,可以通過變數id,和方法id,建立Java物件,
獲取java物件中變數的值,等等.
jclass jcls1 = env->GetObjectClass(jobj);//通過jobject 獲取jclass
//根據java物件去獲取這個物件的jclass類. 作用跟上面一樣.這個也很重要.
jobject job = env->NewGlobalRef(jobj);//將區域性引用變成全域性引用
//將區域性引用變成全域性引用.不多解釋.
env->DeleteGlobalRef(job); //刪除全域性引用
//刪除全域性引用,釋放記憶體用的
env->DeleteLocalRef(job); //刪除區域性引用
//刪除區域性引用,釋放記憶體用的
jmethodID jme = env->GetMethodID(jcls,"<init>","()V");
//根據jclass類和方法名,獲取methodid方法id,也可以獲取構造方法id,上面是構造方法的id,<init>表示構造方法, ()V 括號裡面為構造方法需要的引數型別 ,V為返回值,
我這裡沒新增引數,無返回值的,如果要新增引數的話
如: "(Ljava/lang/String;ILcom/viking/Data;)V" 這個意思就是, public Method(String str,int i ,Data data){} 這樣的構造方法.
獲得構造方法id,我們就可以在jni程式碼中建立java物件了.
jobject j_jni_cls1_1 = env->NewObject(jcls, jme);//根據類和methodid獲取物件
建立java物件, jcls:java類的jclass ,jme :java類的構造方法的id;具體程式碼如下
jclass jcls = env->FindClass("com/viking/Data");
jmethodID jme = env->GetMethodID(jcls,"<init>","()V");
jobject j_jni_cls1_1 = env->NewObject(jcls, jme);
jmethodID jeid = env->GetMethodID(jcls,"getName","()Ljava/lang/String;");//獲取類的方法id
上面說了怎麼獲取構造方法id,那麼獲取其他方法id,也大同小異了.
jcls:類 getName:方法名 ()Ljava/lang/String; :方法的引數和返回值 型別,這裡是沒有引數, 返回值型別為string.
煩死,一言不和就複製程式碼了.
//建立兩個物件TImageUserInfo TPicInfo jclass jimageuserinfobean = env->FindClass("com/viking/bean/TImageUserInfo"); jclass jpicinfobean = env->FindClass("com/viking/bean/TPicInfo"); //獲取構造方法id jmethodID jimageuserinfobeanID = env->GetMethodID(jimageuserinfobean,"<init>","()V"); jmethodID jpicinfobeanID = env->GetMethodID(jpicinfobean,"<init>","()V"); //建立物件 jobject jimageuserinfo = env->NewObject(jimageuserinfobean,jimageuserinfobeanID); jobject jpicinfo = env->NewObject(jpicinfobean,jpicinfobeanID);
jclass intarrayclass = env->FindClass("[I"); //獲得一維陣列 的類引用,即jintArray型別
獲取java陣列物件的jclass類. 可用來建立陣列物件.
jobjectArray jarr = env->NewObjectArray(5,intarrayclass,NULL);//獲取陣列的jclass,獲取大小為五的,型別為jclass型別的,jobjectArray陣列物件
算了,下節直接複製程式碼了. 每種實現都複製一段. 附講解. 這樣一點點敲,累死了.