1. 程式人生 > >Android studio NDK開發 從入門到實踐二

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

char *str4 = env->GetStringChars(jstr,0); 

//可以將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陣列物件

算了,下節直接複製程式碼了. 每種實現都複製一段. 附講解. 這樣一點點敲,累死了.