JNI入門教程1---Android studio 下JNI程式設計例項並生成so庫
阿新 • • 發佈:2018-11-12
參考地址: https://www.cnblogs.com/jymblog/p/5526865.html
https://www.jianshu.com/p/ac00d59993aa
1.JNI的概述
JNI的全稱就是Java Native Interface,顧名思義,就是Java和C/C++相互通訊的介面,就好比買賣房子都需要找中介一樣,這裡的JNI就是Java和C/C++通訊的中介,一箇中間人。
2.JNI的用途
1.主要是一些演算法,因為c/c++比Java效率高,所以應用執行起來速度比較快,特別是一些遊戲中的演算法.
2.為了保密,都知道apk都可以被反編譯,就算有程式碼混淆,也只是難看懂,並不是完全看不懂,但用jni編譯成.so就不同了,所以可以達到商業機密不洩露的目的。
3.一個平臺(C++程式碼)遷移到Android平臺,底層邏輯是相同的,這樣就可以通過移植,利用JNI呼叫底層C++程式碼,避免相同邏輯的程式碼重複去寫,不過這個過程一定要注意底層物件的釋放問題。
4.與一些硬體驅動的通訊(串列埠等)
- 擴充套件:JNI擴充套件了JVM能力,驅動開發,例如開發一個wifi驅動,可以將手機設定為無限路由;
- 高效: 原生代碼效率高,遊戲渲染,音訊視訊處理等方面使用JNI呼叫原生代碼,C語言可以靈活操作記憶體;
- 複用: 在檔案壓縮演算法 7zip開原始碼庫,機器視覺 OpenCV開放演算法庫等方面可以複用C平臺上的程式碼,不必在開發一套完整的Java體系,避免重複發明輪子;
- 特殊: 產品的核心技術一般也採用JNI開發,不易破解;
3.編寫Jni實現native方法的呼叫
1.編寫jni檔案,實現本地方法
public class MainActivity extends AppCompatActivity {
private Button mBtn;
private Button mjni;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn = ((Button) findViewById(R.id.btn));
mBtn.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public void onClick(View v) {
DisplayManager mDisplayManager;//螢幕管理類
Display[] displays;//螢幕陣列
mDisplayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
displays = mDisplayManager.getDisplays();
if (displays != null) {
Presentation presentation = new MyPresentation(MainActivity.this, displays[1]);
presentation.show();
}
}
});
mjni = ((Button) findViewById(R.id.btn_jni));
mjni.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String info=JniMethod.getNativeString("你好");
Toast.makeText(MainActivity.this, info, Toast.LENGTH_SHORT).show();
}
});
}
}
2.生成.h的標頭檔案
該檔案即連線java和c(c++)的橋樑,裡面有Android工程裡本地方法的宣告。這個檔案可以在“控制檯”用javah命令自動生成
在下面這個路徑生成了目錄和.h的標頭檔案(標頭檔案的名稱不可以修改)
3.新建cpp檔案,進行方法的實現,(還要多加個空的cpp檔案empty.cpp)
.h檔案的方法宣告
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_aier_testdemos_JniMethod */
#ifndef _Included_com_aier_testdemos_JniMethod
#define _Included_com_aier_testdemos_JniMethod
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_aier_testdemos_JniMethod
* Method: getNativeString
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_aier_testdemos_JniMethod_getNativeString
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
cpp檔案的方法實現(JniMethod.cpp)
#include <jni.h>
#include<com_aier_testdemos_JniMethod.h>
#include<stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_aier_testdemos_JniMethod
* Method: getNativeString
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_aier_testdemos_JniMethod_getNativeString
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
JNIEXPORT jstring JNICALL Java_com_aier_testdemos_JniMethod_getNativeString
(JNIEnv *env, jclass, jstring){
return env->NewStringUTF("I'm comes from to Native Function!");
}
4.把jni檔案加複製,放到main目錄下
5.配置相關配置
6.編譯執行!