1. 程式人生 > >JNI入門教程1---Android studio 下JNI程式設計例項並生成so庫

JNI入門教程1---Android studio 下JNI程式設計例項並生成so庫

參考地址: 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.編譯執行!