CMake再探:引入SO檔案並呼叫
上次已經通過CMake編譯自己寫的C/C++程式碼了,這次嘗試匯入第三方程式碼來進行呼叫。通過上次寫的JniTest生成的so檔案來測試,生成的so檔案在專案的app/build/intermediates/cmake/debug/obj目錄下。
1.匯入so檔案
將so檔案拷貝到專案中,路徑自己定吧,只要配置的時候不出錯就行,我是這樣的拷貝到jniLibs資料夾中的。jniLibs下的子資料夾表示的是cpu型別,你可以少建些,但不可以不建,so檔案就放在這些資料夾下,每個cpu型別都放。
(注:匯入的so檔案需要在庫名前新增“lib”,即lib庫名.so,比如我要匯入庫名為test的so檔案,那麼你得將so檔名改為libtest.so再拷貝進專案)
2.配置
(1)在CMakeLists.txt中新增add_library()以及set_target_properties()方法
(注:通常情況下so檔案還會附帶.h標頭檔案(很明顯,我沒寫標頭檔案),這時候需要再加上include_directories()語句來定位標頭檔案的位置,不是很懂的童鞋可以去這裡看看)
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.4.1) # 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). src/main/cpp/native-lib.cpp ) add_library(test-lib SHARED IMPORTED) set_target_properties(test-lib PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libtest-lib.so)
匯入so檔案相當於你“實現”了方法,還需要“宣告”。比如我的so檔案中實現了“Java_com_example_win7_jnitest_util_JniUtil_stringFromSelf”方法,
“com_example_win7_jnitest_util”表示的是包名,
“JniUtil”表示的是方法所在類,“stringFromSelf”表示的是方法名。
因此,我在“com.example.win7.jnitest.util”包下新建了JniUtil類來聲名方法
(注:so檔案實現了哪些方法可以在.h標頭檔案中看到)
JniUtil.java:
public class在MainActivity中呼叫該方法:JniUtil { static { System.loadLibrary("test-lib"); } public static native String stringFromSelf(String str); //這裡雖然是紅字,但可以跑起來 }
public class MainActivity extends AppCompatActivity { @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(JniUtil.stringFromSelf("jack")); } }
附Demo下載地址