日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Flutter 添加 armeabi-v7a 本地库出现的一些问题

發(fā)布時間:2023/12/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Flutter 添加 armeabi-v7a 本地库出现的一些问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 第三方native library無法加載

由于我們的 flutter 應用中要集成第三方的 sdk 來實現(xiàn)一些特殊功能,該 sdk 中集成了一些 native library ,而且只有 32位 的。目前在 flutter 的 android 工程中添加了這些 library , 如下圖所示:

隨后在 android 工程的 build.gradle 文件中手動指定 jniLibs 目錄的路徑,如下圖所示:

現(xiàn)在正常在 flutter 工程中執(zhí)行 debug 啟動工程,如下圖所示:

點擊界面按鈕,調用第三方 native library 后立馬出現(xiàn)報錯,隨后 App 閃退。報錯內容如下:

通過日志可以看出來,我們前面添加的 native library 沒有被加載。

當時首先懷疑的是打包時是否將 native library 有打包到 apk 中,所以采用 android studio 的 analyze apk 命令分析,發(fā)現(xiàn)確實是已經(jīng)打包到 apk 文件中了。如下圖所示:

仔細回顧上面的日志,不難發(fā)現(xiàn),沒有被加載的原因是因為它尋找 library 的路徑不對,根本沒有包含我們需要的 armeabi-v7a 這個目錄。如下圖所示,加載的路徑基本上都是 arm64 相關的目錄,很顯然是因為我的真機是 arm64 架構的,所以可能導致這個問題。

關于這個問題,在文章 https://medium.com/codechai/flutter-app-couldnt-find-libflutter-so-c95ad81cbccd 中有詳細的說明。大體情況如下:

當apk安裝時,首先會標記當前應用是32位的還是64位的,這決定了后面在哪個目錄尋找本地庫。

  • 首先在 lib/arm64-v8a 目錄中尋找是否有 native libraray,如果有就標記為 64位 。(在上面的情況中,arm64-v8a文件夾中是包含有 libflutter.so 的,所以該應用被標記為 64 位)
  • 如果沒有在 lib/arm64-v8a 中找到 native libraray,則隨后在 lib/armeabi-v7a 和 lib/armeabi 中尋找,有則標記為 32位 。
  • 如果在上述目錄中都沒有找到 native library 則說明當前應用沒有使用本地庫,對 32 位還是 64位 并不敏感。此時會默認標記為 64位。
  • 此時可以在網(wǎng)上找到的大多數(shù)回答是在 build.gradle 文件中指定 ndk 的 abiFilter ,如下圖所示:

    這個配置的意思是指定一個 filter ,讓 Gradle 在打包 apk 時只添加 armeabi-v7a 下的 library ,其它的都不添加。
    根據(jù)上面的尋找 library 的規(guī)則,這么做確實只保證 armeabi-v7a 的庫被加載到。

    添加這項配置后,再繼續(xù)執(zhí)行 debug ,又拋出了 couldn't find "libflutter.so" 這個報錯信息。詳細內容如下所示:

    E/FlutterLoader( 8399): java.util.concurrent.ExecutionException: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.dm.pcbd-A-gAqiQOV9EjRIg7TZRvKw==/base.apk"],nativeLibraryDirectories=[/data/app/com.dm.pcbd-A-gAqiQOV9EjRIg7TZRvKw==/lib/arm, /data/app/com.dm.pcbd-A-gAqiQOV9EjRIg7TZRvKw==/base.apk!/lib/armeabi-v7a, /system/lib, /product/lib]]] couldn't find "libflutter.so"

    采用 analyze apk 查看了下生成的 apk 包,發(fā)現(xiàn)確實沒有將 libflutter.so 打包到 apk 中,如下圖所示:

    翻了 flutter 的很多 issue 后發(fā)現(xiàn)有很多類似的問題,例如這個 issue https://github.com/flutter/flutter/issues/29710

    2. debug下 libflutter.so 無法加載

    根據(jù) issue https://github.com/flutter/flutter/issues/29710 的描述,只要 armeabi-v7a 下添加了其它庫,就會出現(xiàn) libflutter.so 打包不進去的問題。

    經(jīng)過多次嘗試后,發(fā)現(xiàn)使用 flutter build 命令行生成出來的包中是有 libflutter.so 的,具體命令如下:

    // 生成debug包 flutter build apk --debug// 生成release包 flutter build apk --release// 安裝軟件包(在生成debug或release包之后運行) flutter install

    build 生成的 debug 包中包含 libflutter.so

    build 生成的 release 包中也包含 libflutter.so

    但是直接使用 Android Studio 上的 debug 運行時就是不打包 libflutter.so 到 armeabi-v7a 中。

    Android Studio 上的 debug 等同于命令行 flutter run --debug -v

    說實話,到這一步時覺得 flutter 還是不太成熟,差點想棄坑了。

    仔細翻閱了 https://github.com/flutter/flutter/issues/29710 這個issue,發(fā)現(xiàn)有網(wǎng)友提到命令行手動指定 target-platform 來強制指定目標平臺為 arm 32位,例如:

    flutter build apk --debug --target-platform=android-arm flutter run --use-application-binary=build/app/outputs/apk/debug/app-debug.apk

    但是 target-platform 這個參數(shù)在新版本的 flutter 中不能直接用在 flutter run 上(即上述的 debug 上),只能用在 flutter build 上。那這就導致平常調試時很不方便了,不能直接按 debug 按鈕啟動啟用,得用命令行手動啟動,太不方便了。

    在上面的 issue 中,又有網(wǎng)友提到直接在 gradle 中配置 target-platform 。具體是在 settings.gradle 文件中添加配置,如下所示:

    具體添加的代碼如下:

    gradle.beforeProject({ project->if (project.hasProperty("target-platform") && !project.getProperty("target-platform").split(",").contains("android-arm")) {project.setProperty("target-platform", "android-arm")} })

    添加這段配置后,就可以 正常使用 界面上的 debug 按鈕了,其生成的 apk 包中 armeabi-v7a 文件夾下確實是包含了 libflutter.so 。

    3. Release下出現(xiàn)閃退問題

    上面解決 debug 正常后,為了看下 release 下的效果,隨即用命令行 flutter build apk --release 生成了 release 包,安裝后點擊按鈕訪問第三方sdk內容時出現(xiàn)閃退。

    這就出現(xiàn)了 release 下和 debug 下行為不一致的問題

    這種直接安裝 apk 的方式,出現(xiàn)閃退或報錯等問題,在 Android Studio 中看不到任何日志,非常不利于問題的排查。

    這里可以采用 flutter run --release -v 的方式來啟動 release 包,這樣在控制臺至少可以看到一些日志。flutter run --release -v 在界面上也可以配置出來,如下圖所示:

    再點擊界面上的 Run 或 debug 按鈕就可以啟動這個 release 包了。(此時 debug 或 Run 按鈕不影響運行方式)

    通過這種方式運行后,得到 Release包閃退 的報錯信息如下:

    E/AndroidRuntime(22800): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dm.pcbd/com.micropattern.sdk.ext.MPFaceQualityDetectActivity}: android.content.res.Resources$NotFoundException: Resource ID #0x0 E/AndroidRuntime(22800): at .................省略一些無關的日志 E/AndroidRuntime(22800): Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x0 E/AndroidRuntime(22800): at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:292) E/AndroidRuntime(22800): at android.content.res.Resources.loadXmlResourceParser(Resources.java:2390) ........... 省略一些無關的日志 com.android.internal.policy.HwPhoneWindow.setContentView(HwPhoneWindow.java:342) E/AndroidRuntime(22800): at android.app.Activity.setContentView(Activity.java:2941) E/AndroidRuntime(22800): at com.micropattern.sdk.ext.MPFaceQualityDetectActivity.onCreate(Unknown Source:36) E/AndroidRuntime(22800): at android.app.Activity.performCreate(Activity.java:7458) E/AndroidRuntime(22800): at android.app.Activity.performCreate(Activity.java:7448) E/AndroidRuntime(22800): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286) E/AndroidRuntime(22800): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409) E/AndroidRuntime(22800): ... 11 more

    出現(xiàn)這個問題,猜測是release打包時 shrink 壓縮導致的問題。首先考慮到可能是 flutter官方文檔中提到的 Shrinking your code with R8 導致的問題,遂在命令行打包時嘗試關閉 shrinking ,命令如下所示:

    flutter build apk --release --no-shrink

    不過這個包打出來后,還是存在上面的資源問題。

    上面那個是 android 中獲取資源的問題,那么有可能是 Gradle 打包時出現(xiàn)的問題,所以考慮應該直接在 Gradle 中關閉 shrink 。具體操作如下,在 build.gradle 中添加如下配置

    關于shrink,官方文檔中有詳細介紹: https://developer.android.com/studio/build/shrink-code?utm_source=android-studio#shrink-resources

    到這里,再 Release 后就可以正常使用本地庫了。

    4. 總結

    解決這個問題耗了一整天,基于上都是停留在各種嘗試中。經(jīng)過這一番折騰,確實了解到 flutter 這個坑有些大…

    • 第一次為了解決 libflutter.so 無法加載的問題,甚至嘗試過手動將 libflutter.so 拷貝到 armeabi-v7a 文件夾下。這樣確實解決了 debug 下的問題,但是最后做出來的 release 包一直卡在空白界面。在這里浪費了很多時間。
    • 目前 flutter 并不是特別成熟,關于這個問題在 issue 中說法有很多,這也導致了各種嘗試,花費了很多時間。

    經(jīng)過這次折騰,也確實了解到了很多東西,例如:

    • ndk abiFilter 配置
    • 對 native library 加載機制有些許了解
    • flutter工程和android工程的關系也終于弄明白了一些

    5. 關于作者

    作者是一個熱愛學習、開源、分享,傳播正能量,頭發(fā)還很多的程序員-。-
    熱烈歡迎大家關注、點贊、評論交流!

    • csdn: https://blog.csdn.net/u010920692
    • 掘金: https://juejin.cn/user/3237392838298663
    • 博客園: https://www.cnblogs.com/zhangzhxb/

    總結

    以上是生活随笔為你收集整理的Flutter 添加 armeabi-v7a 本地库出现的一些问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。