安卓小白之ndk編譯打包成so供第三方呼叫
本文接著上篇文章內容來,主要講述如何生成so庫以及將類編譯成jar包供第三方呼叫
ofollow,noindex">安卓小白之ndk入門篇配置
在build.gradle中
externalNativeBuild { cmake { cppFlags "" //在這裡指定需要生成什麼型別的so abiFilters "armeabi","armeabi-v7a" } }
在CMakeList檔案中可以指定生成的so庫的名稱
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) ..... target_link_libraries( # Specifies the target library. native-lib #修改此處 # Links the target library to the log library # included in the NDK. ${log-lib})
注意 add_library
的名稱和 target_link_libraries
的名稱必須相同
還有另外一種配置
defaultConfig{ ndk{ //指定生成的so庫名稱 moduleName "native" //在這裡指定需要生成什麼型別的so abiFilters "armeabi","armeabi-v7a" } }
可以直接在gradle中都配置好,不需要更改CMakeList
配置好後,點選 Build
-> Make Project
等待編譯完成,如果你是通過第一種方法配置的,那麼生成的so庫位於 app
-> build
-> intermediates
-> cmake
-> debug
-> obj
目錄下,如果是第二種方法,那麼so庫位於 app
-> build
-> intermediates
-> ndk
-> debug
-> obj
目錄下。
生成jar包
看cpp檔案裡的方法就知道,方法宣告都是與包名繫結的,那我要是給第三方app呼叫呢,總不能讓它們用我們的包名吧,所以,我們就需要將我們的類都打成jar包供第三方間接呼叫,讓第三方呼叫我們的類,我們的類來呼叫c程式碼,這樣問題就解決啦。
1.要編譯jar包,前提條件是你的這個專案必須是一個類庫,也就是library,在app gradle
的最上面檢視是否為 apply plugin: 'com.android.library'
2.在build defaultConfig目錄里加入以下程式碼:
task makeJar(type: Copy) { //刪除存在的 delete 'build/libs/jar.jar' //設定拷貝的檔案 from('build/intermediates/bundles/debug/') //打進jar包後的檔案目錄 into('build/libs/') //將classes.jar放入build/libs/目錄下 //include ,exclude引數來設定過濾 //(我們只關心classes.jar這個檔案) include('classes.jar') //重新命名 rename ('classes.jar', 'jar.jar') } makeJar.dependsOn(build)
看註釋,名字任意取,然後再Terminal中執行命令 gradlew makeJar
, Terminal在AndroidStudio的左下角。
執行完,提示BUILD SUCCESSFUL後,在以下路徑可以找到生成的jar包:
app/build/intermediates/bundles/debug/
呼叫
jar包和so庫都生成好後,就可以使用了,將jar包放入app->libs目錄,將so庫放入app->src->main->jinLibs

s
根據你的需要在jinLibs中建立不同的cpu架構目錄,一般建立一個armeabi和armeabi-v7a就可以了,注意不要寫錯,同時注意在gradle中申明你需要的架構型別
ndk{ //在這裡指定需要生成什麼型別的so abiFilters "armeabi","armeabi-v7a" }
都配置好後,重新Sync Project下專案,就能愉快的使用了。
在使用中,有同學經常會遇到so庫檔案找不到的問題,這時你就需要檢查你的架構目錄下的so的數量是不是相同的,千萬不要出現單個目錄沒有的情況。這是因為so庫都是向下相容,假如一臺v7架構的手機,你把兩個需要使用的so庫都放到armeabi目錄中,沒問題,因為系統在v7中找不到會去armeabi目錄找。但是如果你將一個so放到armeabi和armeabi-v7a,另一個只放了到了armeabi,當一個v7架構的手機使用的時候,如果發現armeabi-v7中沒有是不會去armeabi中找的,因為另一個so也放到了armeabi-v7目錄下,代表你相容了armeabi-v7的情況,此時是不會向下相容的。所以,解決方案就是要麼刪除v7裡的so,要麼把缺少的so補齊。