在配置好Android studio的OpenCV環境后,我們就可以通過Java代碼調用OpenCV的API了,但是在通常情況下,用Java代碼編寫圖像處理算法的運行效率是沒有C++代碼高的,在應用層使用Java處理圖像耗時非常長,往往達不到想要的效果,而Android的NDK和Java的JNI恰好滿足了Android移動端對C++編程的支持,在應用層和原生層起到橋梁的作用。
JNI和NDK
JNI是Java Native Interface的縮寫,即 Java本地接口,其作用是提供若干API,使Java 能與本地其他類型語言(如C、C++)交互。NDK是Native Development Kit的縮寫,是 Android的一個工具開發包, 其作用是使開發者能快速開發C、 C++的動態庫,並自動將so和應用一起打包成 APK。有了這兩樣,我們就可以通過NDK在Android中使用JNI與本地代碼(C、C++)進行交互,將高耗時的圖像算法使用C++代碼實現,然后由Java應用層調用得到結果並展示。
下載NDK
1. 在官網下載NDK r16b版本的安裝壓縮包,下載地址:https://dl.google.com/android/repository/android-ndk-r16b-windows-x86_64.zip
2. 下載后解壓,相關文件如下:


導入NDK庫
打開Android Studio,點擊file-->project structure,

點擊sdk location,選擇剛才解壓的NDK文件的文件夾路徑,點擊OK即可。

在工程中添加JNI
方式一:新建工程,勾選include C++ support,

方式二:在已有工程中添加JNI
1. 在已有的工程中創建cpp文件夾。
在app/src/main/下創建cpp目錄,並在此目錄下添加cpp文件,文件名為native-lib.cpp。cpp文件使用了android 創建cmake項目時的默認demo文件


2. 創建CMakeLists.txt文件,在app/目錄下創建CMakeLists.txt文件,並在cmakeList.txt 文件添加編譯描述。

3. 修改app的build.gradle,在build.gradle中增加對Cmake的支持

4. 在Java中調用,


package www.edgematch.com.myjni; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends AppCompatActivity { // Used to load the 'native-lib' library on application startup. static { System.loadLibrary("native-lib"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Example of a call to a native method TextView tv = (TextView) findViewById(R.id.sample_text); tv.setText(stringFromJNI()); } /** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ public native String stringFromJNI(); }
提示無法找到so庫
1.提示找不到編譯之后的native-lib的so文件,即未編譯,

解決方法:
(1)在app.gradle中添加如下代碼,然后重新編譯工程,若不起作用,則繼續執行(2)。

(2)將libs文件夾下的文件除armeabi-v7a外全部刪除,然后重新編譯工程,build文件夾則會生成相應的so文件。


OpenCV環境配置
在網上查了很多資料,有的配置方法需要添加Android.mk和Application.mk文件什么的非常復雜,后來參考了https://www.jianshu.com/p/6e16c0429044 的做法,直接一步到位,不需要其他繁瑣操作,我們只需要在CMakeLists.txt中修改如下:紅框中為設置為自己的OpenCV Android sdk路徑。

# For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # ##################### OpenCV 環境 ############################ #設置OpenCV-android-sdk路徑 set( OpenCV_DIR E:/AndroidOpenCV/OpenCV-android-sdk/sdk/native/jni ) find_package(OpenCV REQUIRED ) if(OpenCV_FOUND) include_directories(${OpenCV_INCLUDE_DIRS}) message(STATUS "OpenCV library status:") message(STATUS " version: ${OpenCV_VERSION}") message(STATUS " libraries: ${OpenCV_LIBS}") message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}") else(OpenCV_FOUND) message(FATAL_ERROR "OpenCV library not found") endif(OpenCV_FOUND) # ###################### 項目原生模塊 ########################### add_library( identify-lib SHARED src/main/cpp/identify-lib.cpp src/main/cpp/edgeGradientMatching.cpp src/main/cpp/OpenCVAndroidFunction.h) target_link_libraries( identify-lib ${OpenCV_LIBS} log jnigraphics)
接下來就可以在cpp文件中導入opencv頭文件在c++代碼中其API了。

添加的cpp文件無法顯示或編譯不通過
我們在cpp文件夾下添加其他cpp文件時,Android Studio會顯示如下提示,

android studio :The file is not part of the project.Please include it ...
解決方法:打開CMakeLists.txt文件,在add_library中添加新的cpp文件和頭文件的名稱,如下,

點擊sync now,則提示語句消失,代碼編譯成功。
error: cannot use typeid with -fno-rtti

出現這個錯誤是因為AS關閉了RTTI(Runtime Type Information Support)的支持。
解決辦法:打開build.gradle文件,在cppFlags中添加-frtti標識,Gradle 會將其傳遞到 CMake,錯誤即可消除。

error: cannot use 'try' with exceptions disabled和error: cannot use 'throw' with exceptions disabled
NDK編譯錯誤,這是由於 CPP文件中使用了C++ 標准異常,而 Android NDK 編譯器默認不支持 C++ 異常控制導致。在使用NDK13b 的時候報錯,使用升級版本到NDK16b時,運行編譯則不會出錯,所以當出現這個錯誤時可以通過使用高版本的NDK解決。下載地址:https://developer.android.google.cn/ndk/downloads/older_releases

OK,萬事俱備,接下來就可以愉快的寫代碼了。
轉載請注明出處:https://www.cnblogs.com/White-xzx/p/9563555.html
