前言:
由於項目中地址接口被反編譯而遭受攻擊,所以需要對接口地址進行保護,那麼這自然要用到Android的NDK開發。其實我在開發的過程中也是在網上找各種資料,然後實現了的。現在我根據我自己的的親身實踐,將自己開發的流程記錄下來,方便有需要的人查閱,更多的是爲了自己能夠學習。
ndk開發主要就是講敏感的資源放到C文件中,然後通過編譯,將C文件打包成動態庫.so文件,然後將.so文件加載到libs下面。然後Android項目中就可以獲取到C文件中的接口地址了。
ndk開發流程:
1.準備工作
NDK下載地址:
官網地址:https://developer.android.com/ndk/downloads/index.html
- Windows32:http://dl.google.com/android/ndk/android-ndk-r10d-windows-x86.exe
- Windows64:http://dl.google.com/android/ndk/android-ndk-r10d-windows-x86_64.exe
- Mac OS X 32-bit:android-ndk-r10d-darwin-x86.bin
- Mac OS X 64-bit:android-ndk-r10d-darwin-x86_64.bin
- Linux 32-bit (x86):http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86.bin
- Linux 64-bit (x86):http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86_64.bin
- 下載完成之後就是NDK環境的配置了,下面的操作都是在Mac OS X 64-bit平臺上完成的。
- 環境配置:
- a.將下載的包安裝好
- b.打開終端,執行命令: touch ~/.bash_profile(第一次編輯的時候需要)
- 執行命令: vim ~/.bash_profile
回車進入如下界面,滾動到最下面:
最後一行輸入:e
在進入的界面的最後添加
NDK_ROOT就是ndk的安裝路徑
輸入編輯內容後,在輸入模式下按esc鍵,輸入 保存並退出命令:
:wq
# 然後執行如下代碼,更新配置文件
source .bash_profile
環境配好之後就可以開始操作了
下載ndk文件解壓出來會看到裏面有個sample文件,裏面就是一些範例,如下圖:
在Android studio中打開上面截圖中的最後一個示例,hello-jni。
對於hello-jni示例會看到有兩個jni文件,一個是在main文件夾下面的,一個是在整個工程目錄下面的。這兩個jni的內容是一模一樣的。只是在android中的編譯方式不同,在main下面的jni文件,可以在AS中配置相關信息之後,修改jni中的內容之後,自動編譯。在外部的jni文件,修改之後內容以後,手動編譯。
jni文件夾下有三個文件,如下圖:
hello-jin.c文件裏面的一個個函數就是與java層橋接的接口。這些函數命名是有約束的,規則如下:
Java_PackageName_ClassName_MethodName
例如:
那麼這個函數就對應java中com.example.hellojni包下面的HelloJni類中的getContentFromJNI()函數。
Android.mk文件用來指定源碼編譯的配置信息,例如工作目錄,編譯模塊的名稱,參與編譯的文件等,大致內容如下:
- LOCAL_PATH:設置工作目錄,而my-dir則會返回Android.mk文件所在的目錄。
- CLEAR——VARS:清除幾乎所有以LOCAL——PATH開頭的變量(不包括LOCAL_PATH)。
- LOCAL_MODULE:用來設置模塊的名稱。
- LOCAL_SRC_FILES:用來指定參與模塊編譯的C/C++源文件名。
- BUILD_SHARED_LIBRARY:作用是指定生成的靜態庫或者共享庫在運行時依賴的共享庫模塊列表。
Application.mk文件用來配置編譯平臺相關內容,我們最常用的估計只是APP_ABI
字段,它用來指定我們需要基於哪些CPU架構的.so文件
這代表編譯所有平臺的.so文件。
如果不創建Application.mk文件,那麼手動編譯的.so文件只有armeabi平臺一個版本,其他平臺的不會被編譯。
當jni文件編寫好之後,打開終端,進入到jni所在的目錄,然後輸入命令:ndk-build,那麼在jni所在的目錄下回多出libs和obj兩個目錄,打開libs目錄,可以看到對應不同平臺的.so文件
將這些libhello-jni.so文件拷貝到工程目錄的libs文件夾對應的文件夾下
然後在與hello-jni.so文件中對應的類裏面添加如下靜態代碼塊:
加載對應的JNI庫,hello-jni是JNI庫的名字。實際加載動態庫的時候,根據不同的拓展成平臺真實的動態庫文件名,例如在Linux系統上會拓展成libhello_jni.so而在Windows平臺上則會拓展成libhello_jni.dll
並用native關鍵字修飾hello-jni中對應的類,eg:
表示getContentFromJNI()函數由native層實現
這時候就可以在java中調用getContentFromJNI獲取到C++層的數據了。到此,ndk 簡單開發完成。
下面爲demo示例: