Android Studio下的NDK開發(三):C中通過JNIEnv訪問Java中的內容
阿新 • • 發佈:2019-01-29
1、編寫java native類
直接上程式碼public class JniUntil { public static int a=7; public static int b=8; public static int sum(int a,int b){ return a+b; } public native int askByJni(); static { System.loadLibrary("JniTest"); } }
2、生成通過terminal生成.class檔案
開啟terminal如圖執行 cd app/src/main/java/com/jnidemo_iii/ 進入到JniUntil.java所在的目錄
然後執行 javac JniUntil.java 可以看到目錄裡多了一個JniUntil.class的檔案
3、通過terminal生成.h標頭檔案
再執行 cd .. cd .. javah com.jnidemo_iii.JniUntil 生成.h檔案,如圖4、配置CmakeList.txt
將.h標頭檔案拷貝到cpp目錄下,新建com_jnidemo_iii_JniUntil.c檔案,在CmakeLis.txt檔案中加入如下程式碼:5、編寫c檔案
在com_jnidemo_iii_JniUntil.c中編寫程式碼,如下#include "com_jnidemo_iii_JniUntil.h" JNIEXPORT jint JNICALL Java_com_jnidemo_1iii_JniUntil_askByJni (JNIEnv * env, jobject obj){ //獲取JniUntil例項 jclass jniuntil=(*env)->GetObjectClass(env,obj); //獲取a的id //第一個引數是環境,第二個引數是例項,第三個引數是變數名,第四個引數是簽名jfieldID a_id=(*env)->GetStaticFieldID(env,jniuntil,"a","I"); //通過a的id獲取a的值 jint a=(*env)->GetStaticIntField(env,jniuntil,a_id); //獲取b的id jfieldID b_id=(*env)->GetStaticFieldID(env,jniuntil,"b","I"); //通過b的id獲取b的值 jint b=(*env)->GetStaticIntField(env,jniuntil,b_id); //獲取函式JniUntil.sum函式id //第一個引數是環境,第二個引數是例項,第三個引數是函式名,第四個引數是簽名 jmethodID id_sum=(*env)->GetStaticMethodID(env,jniuntil,"sum","(II)I"); //呼叫sum函式 //第一個引數是環境,第二個引數是例項,第三個引數是函式的id號,第四、五個引數是是sum()函式的引數 int c=(*env)->CallStaticIntMethod(env,jniuntil,id_sum,a,b); //返回sum函式結果 return c; }
6、通過terminal獲取簽名
執行javap -s -p JniUntil.class descriptor:之後的就是簽名
7、生成動態連結庫
編譯執行,生成庫檔案,其目錄在如下圖
拷貝到JnilIbs
8、編寫mainActivity測試結果
編輯MainActivity中的程式碼,如下public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView result=(TextView)findViewById(R.id.result); JniUntil until=new JniUntil(); int a=until.askByJni(); Log.e("a",""); result.setText(""+a); } }
執行,結果如圖