android so库框架,Flutter框架Android so库的一些实践

学而思网校1对1的android工程是用flutter框架实现的,而android工程不可避免的要和cpu架构和so库打交道,在实践中,针对flutter框架对cpu架构的支持,我们也有一些经验在此总结。

so库说明

so库在android中,是使用c/c++代码编译出来的库文件,可以使用ndk调用,就是你在android代码中见到的native方法,具体的实现就在so库中。

关于so库兼容性问题

andorid中或多或少都会引用到第三方库,而很多第三方库中都有so的存在,不论是复制到项目中(如百度地图),或是gradle依赖(如个推)

其中都涉及到了so库的相关问题,如果你选择的库是有所有cpu类型可选还好,如果不是,那么就需要自定义设置了。

举个栗子

你的app依赖两个库,分别是lib1,lib2

lib1: arm64-v8a,armeabi-v7a

lib2: armeabi-v7a

那么当你运行在v7的手机上时,因为你的项目含有v7的so库,所以没有问题,可以跑起来如果,你运行在v8手机上,那么你的项目就会Crash, 为啥呢? 这就涉及到so对齐了

so对齐

简单来说,就是要有就必须都有,如果一个没有,那就一个都不要

比如上面的例子,如果你是自己复制到项目下的,你需要删掉arm64-v8a的文件夹

flutter经典问题couldn't find "libflutter.so"

引发的原因

导致这个问题出现的原因是因为我们在项目种使用了so库,或者项目中引用的三方sdk使用了so库。在引用so库时需要针对不同的cpu架构使用不同的.so文件。armeabi,armeabi-v7a,x86,arm64-v8a,大家通常会对这几个cpu架构进行适配。然而问题就出在现在Flutter在打包Apk时不能同引入arm32和arm64的libflutter.so。我门将打好包的Apk安装到arm64架构(默认打包会引入arm32)的手机上就出现了couldn't find libflutter.so这个异常。

如何解决

针对arm32和arm64分别打包(flutter 提供了命令来之分别对arm32和arm64分别打包)

flutter build apk --target-platform=android-arm32

flutter build apk --target-platform=android-arm64

我们用flutter build apk --target-platform=android-arm64打包apk,并在arm64cpu架构的手机安装运行,很好完美运行。但是当我们吧apk安装到32位时问题再次出现,原因就不再重复了。很显然到这里这个方式并不能解决这个问题,为了适配arm32和arm64我们需要分别打包,而国内大部分应用市场不能针对不同cpu架构上传不同的apk。

不对arm64做适配,打包时排除其他非arm32架构的so文件

这时候有些朋友可能会又疑问,问题不就是因为打包时没有引入arm64的libflutter的so文件导致在arm64架构手机上出现“兼容”问题的么。arm64cpu架构是可以像下兼容的,简单点就是arm64架构的cpu可以使用arm32的.so文件。出现问题真正原因是我们在引用so库时(引用的三方库中引用了so库),对arm64做了兼容。这样就会导致运行时系统误以为我们的应用对所有的so库做了arm64架构的兼容,但是在打包时libflutter并没有引入arm64的版本。这就导致系统去寻找arm64版本的libflutter发现找不到。系统误会了我们,我们只能通过gradle在打包时排除其他非arm32架构的so文件来解除这个误会。

好那如何排除其他非arm32架构的so文件。在app下的gradle文件加入如下代码

buildTypes {

release {

ndk{

//这里其实我觉可以直接是用"armeabi-v7a",但国内几个大哥之前使用的都是"armeabi"

abiFilters "armeabi"

}

}

debug {

ndk {

//这里要加上,否则debug包会出问题,后面三个为可选,x86建议加上不然部分模拟器回报错

abiFilters "armeabi", ,"armeabi-v7a","arm64-v8a", "x86"

}

}

}

3.flutter 1.7.8+hotfix.2 以上版本已经支持flutter 64位了 直接打包即可.

只支持64位:flutter build apk --target-platform android-arm64

支持32位:flutter build apk --target-platform=android-arm

同时支持64位和32位:flutter build apk

工程加入x5内核引起的新问题

经过上述文章方法的处理,我们的工程解决了在64位手机上,出现couldn't find "libflutter.so"引起的Crash问题,但是,当我们引入x5内核后,又出现了新的问题。

这是我们在没有引入x5内核前工程支持的cpu架构配置,这个地方需要说明,如果不加入 "arm64-v8a"配置的话,flutter build apk命令虽然会将so库打入工程,但是平时开发时使用的flutter run apk命令并不会把so库打入工程。

ndk {

abiFilters "armeabi" ,"armeabi-v7a", "arm64-v8a"

}

这种配置方式能保证flutter run和flutter build同时生效,不会引起程序因为找不到so库引起的Crash。

但是当引入x5内核后,会出现如下错误

X5 does not support the 64-bit mode to run

x5官方解释是x5内核暂时不提供64位的so文件,在64位手机上需要让AP以32位模式运行,所以我们如果加入了 "arm64-v8a"的话,x5内核在64位手机无法启动。

但是加入的话,又会引起flutter的so库找不见,解决办法如下:

修改flutter.gradle里面,关于flutter run的配置,使其支持把64位的so库打入工程

String flutterExecutableName = Os.isFamily(Os.FAMILY_WINDOWS) ? "flutter.bat" : "flutter"

flutterExecutable = Paths.get(flutterRoot.absolutePath, "bin", flutterExecutableName).toFile();

if (useLocalEngine(project)) {

String engineOutPath = project.property('localEngineOut')

File engineOut = project.file(engineOutPath)

if (!engineOut.isDirectory()) {

throw new GradleException('localEngineOut must point to a local engine build')

}

Path baseEnginePath = Paths.get(engineOut.absolutePath)

flutterJar = baseEnginePath.resolve("flutter.jar").toFile()

if (!flutterJar.isFile()) {

throw new GradleException("Local engine jar not found: $flutterJar")

}

localEngine = engineOut.name

localEngineSrcPath = engineOut.parentFile.parent

// The local engine is built for one of the build type.

// However, we use the same engine for each of the build types.

project.android.buildTypes.each {

addApiDependencies(project, it.name, project.files {

flutterJar

})

}

}

修改构建脚本,在jenkens上构建工程时,动态修改cpu架构支持

#andorid app build.gradle 工程配置文件地址

# 删除 arm64-v8a,防止 hybrid 在某些手机上无法构建。

androidAppGradlePath="$JENKINS_WORKSPACE/northstar_flutter/android/app/build.gradle"

echo "App 中 app/build.gradle 配置文件地址是:${androidAppGradlePath}"

sed -i 's/, "arm64-v8a"/ /' $androidAppGradlePath

echo "已经将 arm64-v8a 从文件中剔除,文件路径是:$androidAppGradlePath"

我们最终采用了方案2,因为每次更新flutter的版本,flutter.gradle文件都会被官方修改,尽量不动此文件为好。

总结

以上就是我们在学而思网校1对1android工程中对flutter框架支持so库做的一些实践和总结,随着flutter版本的不断更新,相信官方会对cpu架构支持越来越好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值