Adnroid ndk 中jni訪問java方法、物件、成員變數
阿新 • • 發佈:2019-02-15
JNI資料夾下,C++原始碼
extern "C" { JNIEXPORT void JNICALL Java_ndk_test_JNI_accessJavaMethod(JNIEnv *env,jobject obj) { jclass ClassJNI = env->FindClass("ndk/test/JNI"); jmethodID returnStringID = env->GetMethodID( ClassJNI, "InstanceMethod", "()Ljava/lang/String;"); jstring jstr =(jstring)env->CallObjectMethod(obj,returnStringID); //呼叫帶返回引數的java方法 const char *c_str = env->GetStringUTFChars(jstr, NULL); // 4. 將unicode編碼的java字串轉換成C風格字串 LOGI("java中的方法執行結果是:%s",c_str); //呼叫有輸入引數與返回值的方法 jmethodID paramID = env->GetMethodID(ClassJNI, "paramMethod", "(Ljava/lang/String;)Ljava/lang/String;"); jstring param = env->NewStringUTF("這是java方法中需要的引數"); jstring jstr2 =(jstring)env->CallObjectMethod(obj, paramID, param); const char *c_str2 = env->GetStringUTFChars(jstr2, NULL); LOGI("呼叫有輸入引數與返回值的方法java中的方法執行結果是:%s",c_str2); //呼叫java中多個引數的方法,並使用另一種查詢方式 jmethodID muitleParamId = env->GetMethodID( ClassJNI, "MuitleParamMethod", "(ILjava/lang/String;[I)Ljava/lang/String;"); jint a=119; jstring tmp_jstr = env->NewStringUTF("liuzheyu"); jintArray ret = env->NewIntArray(3); //例項化一個g一維陣列 jint* buffer = new jint[1024]; //固定陣列,測試用,注意別溢位 for (int i = 0; i < 3; i++) { buffer[i]=i; } env->SetIntArrayRegion(ret, 0, 3, buffer); //從NativeType型別(jint)陣列中,拷貝0~y資料到jintArray物件中 jstring jstr3 =(jstring)env->CallObjectMethod(obj,muitleParamId,a,tmp_jstr,ret); //呼叫帶返回引數的java方法 const char *c_str3 = env->GetStringUTFChars(jstr3, NULL); // 4. 將unicode編碼的java字串轉換成C風格字串 LOGI("呼叫java中多個引數的方法結果是:%s",c_str3); env->DeleteLocalRef(ret); /** * 測試訪問靜態方法 */ jmethodID staticId = env->GetStaticMethodID(ClassJNI,"staticMethod","()Ljava/lang/String;"); jstring jstr_4 =(jstring) env->CallObjectMethod(obj,staticId); const char * c_str4=env->GetStringUTFChars(jstr_4,NULL); LOGI("訪問java中的靜態方法中結果是:%s",c_str4); } }
JNI資料夾下:java物件
package ndk.test; /** * JNI * @author Administrator * 2016-05-22 */ public class JNI { public native String getString(); public native int plus(int a,int b); /** * 操作一維陣列 * @param a * @param b * @return */ public native int operateArray(int[] a,int[] b); /** * 獲取原生中的二維陣列 * @param row * @param col * @return */ public native int[][] get2Array(int row,int col); /** * 獲取一個數組的物件 * @param row * @param col * @return */ public native int[][] get2ArrayObject(int[][] a); /** * 原生代碼訪問例項物件 * @param obj */ public native static void accessInstanceField(ClassObject obj); /** * 原生代碼訪問靜態域 */ private native static void accessStaticField(); /** * 例項方法,在C++中呼叫 * @return */ public String InstanceMethod() { return "JNI中通過方法id來獲取例項方法"; } /** * 靜態方法,在C++中呼叫 * @return */ public static String staticMethod() { return "JNI中通過方法id來獲取靜態方法"; } /** * C++中測試呼叫帶引數的方法 * @param info * @return */ public String paramMethod(String info) { return info; } /** * c++能過原生方法呼叫帶有多個不同型別的引數方法 * @param a * @param str * @param array * @return */ public String MuitleParamMethod(int a,String str,int[] array) { int total=0; for(int i=0;i<array.length;i++) { total+=array[i]; } String result = a+str+total; return result; } /** * 通過直接找類來訪問java中的物件 * @param obj */ public native void accessJavaMethod(); }
java測試類物件:
Android activity類:package ndk.test; /** * 在原生代碼中進行修改 * @author Administrator * */ public class ClassObject { /** * 對應第一種方法:C++中訪問java物件 */ public native ClassObject accessJavaObject(); /** * 測試修改靜態成員變數 */ private static int num; private String str; public static int getNum() { return num; } public static void setNum(int num) { ClassObject.num = num; } public String getStr() { return str; } public void setStr(String str) { this.str = str; } }
package ndk.test;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
static
{
System.loadLibrary("NDKTest"); //匯入庫
}
private Button javaObjBtn;
JNI jni;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView text=(TextView)findViewById(R.id.t1);
jni = new JNI();
String tmp1 = jni.getString()+"和:"+jni.plus(2, 7);
//text.setText(tmp1);
int[] a = {1,2,3};
int[] b = {4,5,6};
int muitle = jni.operateArray(a, b);
String tmp2 = "運算元組之後:"+ muitle;
text.setText(tmp1+tmp2);
int[][] array = {{1,2,3},{4,5,6},{7,8,9}};
int[][] int2Array = jni.get2Array(3, 3);
System.out.println("37-----------:"+int2Array[1][1]);
int [][] tmpArray = jni.get2ArrayObject(array);
System.out.println("40-----------:"+tmpArray [1][1]);
//操作物件
ClassObject obj = new ClassObject();
obj.setStr("劉胡來");
obj.setNum(26);
jni.accessInstanceField(obj);
/*ClassObject o = obj.accessJavaObject();
System.out.println("測試修改物件,修改後名字:"+o.getStr()+":年齡:"+o.getNum());*/
javaObjBtn = (Button)findViewById(R.id.button1);
javaObjBtn.setOnClickListener(new BtnClick());
Button javaMethodBtn = (Button)findViewById(R.id.button2);
javaMethodBtn.setOnClickListener(new BtnClick());
}
private class BtnClick implements OnClickListener
{
@Override
public void onClick(View v) {
switch(v.getId())
{
case R.id.button2:
jni.accessJavaMethod();
/*int a =119;
String str="liuzeyu";
int [] array={1,2,3};
jni.MuitleParamMethod(a, str, array);*/
break;
}
}
}
}