android jni介紹
阿新 • • 發佈:2018-08-09
安裝 array數組 ref 數組 nic textview note doc jstring Jni API:https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html
JNIEnv、jobject和jclass這三種基本類型
JNIEnv、jobject和jclass這三種基本類型
操作API都在JNIEnv中,JNIEnv為Java與C/C++通信橋梁
jobject:Java層傳遞的對象(普通native方法傳遞)
jclass:Java層對應的Class類(靜態native方法傳遞)
native普通方法與靜態方法區別:Jni傳遞參數是jobject和jclass區別
android studio ndk api自動補齊
安裝插件:
Android NDK Support
NDK WorkspaceManager Support
屬性,方法,數組例子:
Java層
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity"; //測試屬性 public String strName ="test"; //排序數組 private int[] array = {89,2,4,34,88,100,1}; // Used to load the ‘native-lib‘ library on application startup. static { System.loadLibrary("native-lib"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Example of a call to a native method TextView tv = (TextView) findViewById(R.id.sample_text); //測試屬性操作 tv.setText(updateStringFromC()); //測試方法調用 tv.setText(getJavaMethod()); //測試數組操作 this.operateArraySort(array); for (int i = 0; i < array.length; i++){ Log.e(TAG, "onCreate: " + array[i]); } //異常處理 C++的異常 JAVA是無法try catch的,如果jni層出現了異常,那麽Java的代碼調用中止 try { exception(); }catch (Exception e){ Log.e(TAG, "onCreate: " + e.getMessage()); } Log.e(TAG, "onCreate: " + "end"); } //測試方法 public String getMethod(int a){ return "method" + a; } /** * A native method that is implemented by the ‘native-lib‘ native library, * which is packaged with this application. */ public native String stringFromJNI(); //從C返回字符串 public native String updateStringFromC(); //調用Java方法 public native String getJavaMethod(); //對array數組進行排序操作 public native void operateArraySort(int[] array); //異常處理 public native void exception();
}
Jni層:
#include <jni.h> #include <string> #include "stdlib.h" //C C++混編 int compare(const void* lhs, const void* rhs){ return (*(int*)lhs - *(int*)rhs); } //異常處理 extern "C" JNIEXPORT void JNICALL Java_com_home_adproj_androidndktest_MainActivity_exception(JNIEnv *env, jobject instance) { jclass _jclass = env->GetObjectClass(instance); jfieldID _jfieldID = env->GetFieldID(_jclass,"strName2","Ljava/lang/String;");//strName2不存在有異常 if(env->ExceptionCheck()){//檢測異常 env->ExceptionClear();//清除異常 不會使Java層崩潰 //拋異常給Java層 jclass exceptionClass = env->FindClass("java/lang/IllegalArgumentException"); env->ThrowNew(exceptionClass,"strName2 不存在");//拋異常到Java層,Java層進行捕獲 } } //對Java數組進行操作 extern "C" JNIEXPORT void JNICALL Java_com_home_adproj_androidndktest_MainActivity_operateArraySort(JNIEnv *env, jobject instance, jintArray array_) { jint *arrays = env->GetIntArrayElements(array_, NULL); int _len = env->GetArrayLength(array_);//獲取數組長度 //qsort(void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs)); qsort(arrays,_len, sizeof(int),compare);//數組排序 env->ReleaseIntArrayElements(array_, arrays, 0);//釋放 } //調用Java層方法 extern "C" JNIEXPORT jstring JNICALL Java_com_home_adproj_androidndktest_MainActivity_getJavaMethod(JNIEnv *env, jobject instance) { jclass _jclass =env->GetObjectClass(instance); //(jclass clazz, const char* name, const char* sig) jmethodID _jmethodID = env->GetMethodID(_jclass,"getMethod","(I)Ljava/lang/String;");//(參數類型)Ljava/lang/String返回值類型 jstring result = (jstring) env->CallObjectMethod(instance, _jmethodID,100); char* str = (char *) env->GetStringUTFChars(result, NULL);//string 轉char return env->NewStringUTF(str); } //測試Java屬性操作 extern "C" JNIEXPORT jstring JNICALL Java_com_home_adproj_androidndktest_MainActivity_updateStringFromC(JNIEnv *env, jobject instance) { // TODO jclass _jclass = env->GetObjectClass(instance); //(jclass clazz, const char* name, const char* sig) //name:屬性名 sig:屬性類型 jfieldID _jfieldID = env->GetFieldID(_jclass,"strName","Ljava/lang/String;"); jstring _result = (jstring) env->GetObjectField(instance, _jfieldID); //如何轉化成java string char* str = (char *) env->GetStringUTFChars(_result, NULL); char text[20] = "success"; return env->NewStringUTF(strcat(str,text)); } extern "C" JNIEXPORT jstring JNICALL Java_com_home_adproj_androidndktest_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); }
lldb:jni調試工具
官網:http://lldb.llvm.org/tutorial.html
android jni介紹