<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # 1. 簡介 ## 1.1 功能 JNI是Java Native Interface的縮寫,在實際中主要也是為了完成C/C++和Java程序的互相調用。因為C/C++存在更久,且對于浮點數的計算更快,且Android底層驅動大多是C/C++來完成的。所以有些時候需要使用C/C++代碼,比如驅動開發、音頻開發等。 ## 1.2 Android中的JNI 在Android中JUC編程中,尤其是在鎖的底層,我們都可以看到native修飾的方法,這個也就是本地方法。在Android中使用NDK這個工具包來完成JNI的開發。JNI可以看做是規定的協議,而NDK是谷歌提供的實踐的工具。 ## 1.3 NDK NDK是一套工具原生開發套件,使你能夠在 Android 應用中使用 C 和 C++ 代碼,并提供眾多平臺庫,你可使用這些平臺庫管理原生 Activity 和訪問物理設備組件,例如傳感器和輕觸輸入。那么什么時候可以考慮使用NDK? * 提高應用的執行效率。將浮點數計算過多的邏輯使用C/C++語言開發。 * 代碼的保護。C/C++庫反編譯難度較大。 * 可以方便地使用C/C++代碼編寫的開源庫,比如OpenCV做圖像識別。 * 便于移植。方便在其他的嵌入式平臺上使用。 # 2. NDK 環境配置 ## 2.1 下載地址 可以直接從官網中選擇所需要的版本,地址:[NDK 修訂歷史記錄 ?|? Android NDK ?|? Android Developers](https://developer.android.com/ndk/downloads/revision_history) ## 2.2 AndroidStudio中配置 這里可以直接在AndroidStudio中進行配置,直接進行下載: ![](https://img.kancloud.cn/00/ff/00ffa86392086fe4305e07eecfa73cf2_895x361.png) 選擇NDK,應用即可下載。然后可以在本地的AndroidSDK環境中找到剛剛下載的NDK: ![](https://img.kancloud.cn/f9/92/f99273e615a4a5e48d392ee9a850522a_1052x669.png) 然后配置一下環境變量,配置后就可以使用cmd進行檢測: ![](https://img.kancloud.cn/4f/20/4f20a8b745b20d8c0b40adf58829eca0_1425x239.png) 然后在local.properties文件中配置: ![](https://img.kancloud.cn/63/95/63959a940b130023638481346f719e13_1153x361.png) 配置好后可以再次檢查一次: ![](https://img.kancloud.cn/ee/ad/eead4a6c5588dc99c61c775305b6ab19_1438x580.png) # 3. JNI案例 首先來體驗一下,直接使用Android Studio直接創建,即: ![](https://img.kancloud.cn/76/75/7675fd9af9bdf70a4600b1b51ce7b1f5_1110x804.png) 然后選擇C++版本為11: ![](https://img.kancloud.cn/8d/df/8ddf8d46191a1aa8f664e3e0c33c9491_873x436.png) 首先來看下這個項目和普通的項目有什么不同: ## 3.1 項目結構 ![](https://img.kancloud.cn/42/13/421369f8d418ef176eb3dcc4f3ee4e2e_445x594.png) 在項目目錄中的main文件夾下多了cpp文件夾,在該文件夾下使用了CMake配置和Cpp文件。分別看下這個兩個文件: ### 3.1.1 CMakeLists.txt ~~~ # 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.10.2) # Declares and names the project. project("jnitest") # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). native-lib.cpp ) # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. target_link_libraries( # Specifies the target library. native-lib # Links the target library to the log library # included in the NDK. ${log-lib} ) ~~~ 從注釋中我們知道,關于如何使用CMake給了一個文檔地址:https://d.android.com/studio/projects/add-native-code.html 在這個配置文件中做了這么幾件事: * 指定最小CMake版本和項目名稱; * 添加類庫,也就是這里的第二個文件,native-lib.cpp; * 指定查找路徑和鏈接庫的名字; ### 3.1.2 MainActivity.java ~~~ public class MainActivity extends AppCompatActivity { // 加載 static { System.loadLibrary("native-lib"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 調用 TextView tv = findViewById(R.id.sample_text); tv.setText(stringFromJNI()); } public native String stringFromJNI(); } ~~~ 起始也就是定義供Java代碼調用的接口,這里即為native修飾的stringFromJNI方法。 然后我們編譯一下項目,可以看見生成的SO文件: ![](https://img.kancloud.cn/ac/48/ac48677f0916a8a4b76d0cc7d6f6667d_482x374.png) ### 3.1.3 native-lib.cpp 最后來看下這個文件: ~~~ #include <jni.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_com_weizu_jnitest_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } ~~~ 方法的命名規則為Java\_全類名\_本地方法名。至于類型這里為JNI所規定的,后面在繼續學習。 ### 3.1.4 build.gradle 在該模塊的build.gradle文件中: ~~~ android { ... defaultConfig { ... externalNativeBuild { cmake { cppFlags "-std=c++11" } } } externalNativeBuild { cmake { path "src/main/cpp/CMakeLists.txt" version "3.10.2" } } } ~~~ 也配置了對應的C++版本和對應的Cmake配置和版本。 然后運行一下項目,可以看見確實成功了: ![](https://img.kancloud.cn/84/26/842694ba3d870b7ca887d9ffde63b17f_277x114.png) 從這個流程來看這里所使用的方式和我們在第二步中所配置的略微不相關。那么接下來就使用cmake的方式。接下來嘗試將其按照上面的規則進行遷移到任意一個Android Studio項目中。 # 4. 項目配置 拷貝上面的CMakeLists.txt以及lib.cpp文件到新的項目,然后修改一下native-lib.cpp文件: ~~~ #include <jni.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_com_weizu_jnitest_JNITest_helloJni( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } ~~~ 然后在新工程中創建對應的包名和方法: ~~~ package com.weizu.jnitest; public class JNITest { // 加載 static { System.loadLibrary("native-lib"); } // Java_com_weizu_jnitest_MainActivity_helloJni public native String helloJni(); } ~~~ 最后拷貝一下build.gradle中的配置內容,指定C++版本和CMakeLists.txt文件路徑。然后就可以調用了: ~~~ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Log.e("TAG", "onCreate: ${JNITest().helloJni()}" ) } } ~~~ 結果: ![](https://img.kancloud.cn/c8/a9/c8a90774d55dd6087e52dd111fc04f7d_1048x94.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看