qq音乐樊篱的歌曲若何恢复

焦点 9237℃

          Android App Bundle 是 Android 新推出的一种官方宣布格式(.aab)。经由过程独霸Android App Bundle你可以促进独霸的包大年夜小,从而汲引拆卸成功率并促进卸载量。

         从上图可以看出 App Bundles 文件格式,它包含 Base Moudle 和我们拆分的 Feature Module 文件夹 ,签名文件和其他的设置设备放置文件。每个 Moudle 文件夹内包含 dex ,manifest,res ,和一个 resources.pb 文件。和 APK 的文件筹划根本贯穿连接齐截。base module 和每个 Dynamic Feature Module 都包含各自的代码和成本,它们合营构成了 apk 文件的内容 。

         Google Play 就是基于对 aab 文件措置,将 App Bundle 在多个维度举办拆分,在成本维度,ABI 维度和 Language 维度举办了拆分 ,你只需按需组装你的Apk然后拆卸便可 。假定你的手机是一个 x 86 ,xhdpi 的手机 ,你在 谷歌 play 独霸市场下载 ap k时 ,gogle play 会掉落踪掉落踪手机的信息,然后屈就 App Bundle 会帮你拼装好一个 apk,这个 apk 的成本只需 xhdpi 的,并且 so 库只需 x 86 ,其他有关的都邑剔除。从而促进了 apk 的大年夜小。

静态交付(Google Play Dynamic Delivery)

        经由过程 Android App bundle 可以基于维度的选择促进 apk 大年夜小,此外 Google Play 还供给了静态交付下场 。Android App Bundle 支撑模块化,经由过程 Dynamic Delivery with split APKs ,将一个 apk 拆分红多个 apk ,按需加载(包含加载 C/C++ libraries) 。上面是 split APK 的几种圭表类型 :

  • Base Apk(根本 apk):此 APK 中包含了全数其他拆分 APK 都可以访谒的代码和成本 ,并供给给用的根本下场 。当用户请求下载您的独霸时,会起首下载并拆卸该 APK。
  • Configuration APKs
    native libraries 和适配往先手机屏幕分辨率的成本
  • Dynamic feature APKs (上图中的 aab 文件中的 Car.apk)
    每个静态下场 APK 都包含您独霸中的某项下场的代码和成本,并且您独霸静态下场模块对比应下场举办了模块化措置。

        启用按需加载下场需求我们在 base module 中集成 Play Core Library。用户在 Google Play 下载一个经由过程 Android App Bundle  编制斥地的独霸时,只会下载 base module 对应的 apk 文件,Dynamic Feature Module 对应的 apk 文件会在运转时按需下载 。Play Core Library 用来在 App 运转时请求下载 Dynamic Feature Module 对应的 apk。可以搜检 Play Core API 独霸

Google play 不才载与更新APK是若何措置按需模块与根本模块的呢 ?

https://codelabs.developers.谷歌.com/codelabs/on-demand-dynamic-delivery/index.html#7

Note:
To test the download of an on-demand module it's not enough to update the application on the device because the update operation also updates all the on-demand modules that are already installed.
To test the download of the module, you have to uninstall the application and install it again. In this way the on-demand modules are not going to be installed.

可以看出 Google Play 的下载与更新APK的逻辑很复杂 ,每次下载时都邑只下载非按需加载模块 ,下载了根本模块此后  ,便可以按需加载其他模块 。假定此后我晋级了 APK ,按需在加载模块是若何措置的呢?Google Play 会同时为我们更新。多么我们无需为按需加载模块做版本兼容措置。Base Moudle 与  Dynamic Moudle 版本永远都邑是保管不时的 。因为 Google Play 都是基于一个 AAB 文件构建出 APK 交付给用户。

Bundletool

我们经由过程 android studio 的 build bundle 下场生成 aab 格式文件 ,我们必须测试 Google Play 独霸该 Android App Bundle 生成 APK 的气候 。验证编制1 :bundletool 呼唤行对象举办测试。验证编制2:经由过程 Google Play 将您的 app bundle 上传到 Play 治理中心并独霸测试轨道举办测试 。
上面我们看看Bundletool的具体独霸编制

独霸bundletool build-apks 呼唤从 app bundle 生成一组 APK

java -jar bundletool-all-0.10.3.jar build-apks --bundle=app.aab --output=my_app.apks

搜检一下a pks 的文件解筹划,分为两个目次 splits 和 standalones

splits目 录:可以看出 splits 就是对各个 moudle 的在成本维度  ,ABI 维度和 Language 维度的拆分 。base moudle 和 car moudle 基于维度各自迸发了 apk 集结 。当我们独霸 app bundle 上传到 谷歌 play 后  ,在 谷歌 play 拆卸 apk 时(手机 android 版本>=21 即android 5.0),谷歌 play 就会在 apk 集结中找到和手机言语,API,分辨率不异的 apk 拆卸到手机从而促进 apk 大年夜小。

standalones 目次:因为对小于 21 的 android 手机是不支撑多 apk 的编制拆卸的 ,同时也不支撑按需加载  ,所以对该圭表类型的手秘要生成一个 APK,当然也在维度举办了拆分 。每个包的大年夜小都在 93.9 M 放置。(与如今版本比照增除夜了 3 M)

经由过程install-apks呼唤将 APK 放置到邻接的设备(andoid 版本为5.1 OPPO R9)

java -jar bundletool-all-0.10.3.jar install-apks --apks=my_app.apks

         从文件筹划可以看出推送到手机的 apk 包含 4 个 base.apk,split_config.armeabi.apk,split_config.xxhdpi.apk,split_config.zh.apk 。屈就手机的设备信息拆卸对应的 apk. 可是我们创作创造没看 car.apk 文件这是为甚么呢?

        因为我们启用了按需加载所以拆卸的模块中并没有 car.apk,我们需求在 base moudle 中独霸P lay Core Library 用来在 App 运转时请求下载 Dynamic Feature Module 对应的 apk 。假定我们把上述的 onDemand 改成 false,我们在从头拆卸 apk,我们在搜检一下 apk 的拆卸目次(为红米 k 20 经由过程 android studio 没法直接搜检拆卸目次只能经由过程a db 呼唤),就会创作创造存在 car 模块对应的 apk 了,包含split_CarLib.apk 和设置设备放置模块s plit_CarLib.config.xxhdpi.apk

192:50APP ***$ adb shell pm path xx.xxpackage:/data/app/***x-flDXC2tcSXaidf_VbJVuMQ==/base.apkpackage:/data/app/***x-flDXC2tcSXaidf_VbJVuMQ==/split_CarLib.apkpackage:/data/app/***x-flDXC2tcSXaidf_VbJVuMQ==/split_CarLib.config.xxhdpi.apkpackage:/data/app/***x-flDXC2tcSXaidf_VbJVuMQ==/split_config.armeabi.apkpackage:/data/app/***x-flDXC2tcSXaidf_VbJVuMQ==/split_config.xxhdpi.apkpackage:/data/app/***x-flDXC2tcSXaidf_VbJVuMQ==/split_config.zh.apk

屈就 aab 文件生成一个全量 apk

bundletool 只生成一个包含独霸的全数代码和成本的 APK ,以使该 APK 与独霸支撑的全数设备设置设备放置兼容,独霸 universal 参数 。

java -jar bundletool-all-0.10.3.jar build-apks --bundle=app.aab --output=all.apks  --mode=universal

 

我们是基于 9.1.0 版本只对二手车营业举办了更始创作创造生成全量 apk 包大年夜小为(95.5 M)添加了 4.8 M,那这些大年夜小添加在何处呢?

经由过程比照我们创作创造 res 文件添加了2.6M lib 文件添加 0.1 M asset 文件添加 0.1 代码添加 0.7 M

取妥往后设备的信息文件

java -jar bundletool-all-0.10.3.jar get-device-spec --output=device-spec.json

设备信息文件内容

{   "supportedAbis": ["arm64-v8a", "armeabi-v7a", "armeabi"],  "supportedLocales": ["zh-CN"],  "deviceFeatures": ["reqGlEsVersion=0x30000", "android.hardware.audio.output", "oppo.fulldiskencryption.unsupported", "oppo.guard.elf.support", "oppo.high.brightness.support", "oppo.hw.manufacturer.mtk", "oppo.inexact.alarm", "oppo.leather.proximity.sensor.support", "oppo.memory.auto.clean", "oppo.memory.auto.deep.clean", "oppo.multi.touch.camera.support", "oppo.ota.twokey.not.support", "oppo.otg.connection.menu.support", "oppo.quick.shot.support", "oppo.screen.hovering.support", "oppo.soundeffect.support", "oppo.support.single.partition", "oppo.sw.solution.device", "oppo.tp.limit.support", "oppo.volte.support"],  "screenDensity": 480,  "sdkVersion": 22}

经由过程上述的 booltool 呼唤是独霸编制 ,大年夜大年夜约我们已产出了若何独霸与如今的工程,来加快 apk 编译与为后期独霸 App Bundle 场景的更始。
1.将如今的工程基于 App Bundle 更始为 Base Moudle 与 feature Moudle
2.更始完成斥地编制直接点击构建便可以了,android stuido 直接会将 split apk 推送到手机设备(android 5.0+)
3.对正式版本构建第一步独霸 gradle 呼唤构建 aab 格式文件 ,第二步独霸 universal  参数将 aab 转换为一个全量的 apk,算作正式包独霸 。(后续的渠道包独霸都是基于这个 apk 举办独霸)

独霸 Android App bundles 项目依托筹划

从上图可以看出,独霸 AAB,项方针依托筹划产生发火了改削 。有 base 和 feature 模块,在 base 中没法直接援引 feature 模块的类,feature 模块可以直接依托 base 模块。
独霸模块化带来的益处:

  • 并行斥地:将独霸拆分不合的模块,各个团队斥地本身担当的模块 。
  • 加快编译时分:Gradle 的并行项目奉行优化,编译琐细就可以够并行地编译多个模块,从而较着促进编译时分  。
  • 静态模块按需加载促进 apk 大年夜小。

 

res 成本筹划

        每个 feature moudle 都邑生成本人自力的 arsc 文件,同时为了不与其他 moudle 产生发火冲突,每个 moudle 其成本 id 的头两位都是有不合的。从图中可以看出 car 的 feature moudle 的成本  id  是以 0x7e 最早而不是 0x7f。 是以在成本 id 独霸时需求寄看一下几点:

  1. dynamic-feature moudle 援引 base modle 成本时  ,不克不及直接独霸 R.drawdble 需求独霸  [base moudle packagename].R.drawdble 的编制。因为 dynamic-feature 的 R 文件只包含本身的成本 。若何需求独霸 base Moudle 的成本需求指定包名 。
  2. basemoude 不成以访谒 feature moudle 中的 id 。CarLib 中 arssc 文件中 R.id.title_filter_btn 中的值为 0x7e0704d8 BaseMoude 中 arssc 文件中 R.id.title_filter_btn 中的值为 0x7f090d85  因为 feature 与 baseMoude 都有各自的 arsc 文件 ,当然属性称号不时可是id值是不合等的,所以 basemoude 中触及访谒f eature moudle 的 id 值都需求改削。

对第二点我们看一下具体的场景。

         我们在 base moudle 中写一个 BaseFragment ,并且设置了却构文件 。筹划文件中设置了默许的 title 筹划。title 筹划的 id 为 R.id.title。并且设置了默许的文字。在 feature moudle 中我们延续这个 BaseFragment 写一下我们赋性化的逻辑,如我们需求将 title 的筹划改成白色布景 。我们就需求重写筹划。将 title 的筹划 backgroundcolor 改成白色,并且 id 也必须是 R.id.title。这个逻辑在之前工程筹划是没有问题标。可是当我们转为 feature moudle 时就是有问题标,因为 feature moudle与base moudle 的 id 称号一样,可是他们的值是不一样的,这个 baseFragment 在掉落踪掉落踪 R.id.title 时,就会掉落踪掉落踪一个空指针 。

静态模块上传到 maven?

          我们晓得 library 工程模块可以经由过程 aar 的编制上传到 maven 仓库 ,静态模块的构建产品是 apk 可以上传到 maven 仓库吗 ?不成以 。经由过程 Android App bundles 模块化拆分的项目假定你想要编译它 ,必须求源码依托工程。多么每个营业线斥地时只能搜检本身营业都构立下场,不成以搜检其他营业线的下场 。

AAB 拆分寄看事项

  1. dynamic-feature moudle 援引 base modle 成本时,不克不及直接独霸 R.drawdble 需求独霸 [base moudle packagename].R.drawdble 的编制
  2. dynamic-feature 项目称号不克不及以数字开首
  3. java.io.IOException: Cannot find PROCESSED_RES output for Main{ type=MAIN, fullName=flavor1Debug, filters=[], versionCode=-1, versionName=null}特别很是 需求诠释损掉落踪落 build.gradle 的 splite { abi{ }}
  4. basemoude 不成以访谒 feature moudle 中的 id
    CarLib 中 arssc 文件中 R.id.title_filter_btn 中的值为 0x7e0704d8
    BaseMoude 中 arssc 文件中 R.id.title_filter_btn 中的值为 0x7f090d85
    因为 feature 与 baseMoude 都有各自的 arsc 文件 ,当然属性称号不时可是 id 值是不合等的,所以 basemoude 中触及访谒 feature moudle 的 id 值都需求改削
  5. 静态模块设置设备放置制订 title 必须经由过程以***例设置设备放置 dist:title="@string/title_dynamic_feature"  不克不及直接编写字符串 并且改字符串必须写在 base moudle 中 。
  6. dynamic-feature moudle 与 base moudle 的 manifest 文件幻想下场会不合迟滞融合一个 manifest 文件 ,所以要担保 manifest 的成本援引均在 base moudle 中 。
  7. aab 转为全量 apk 展示 65535 问题 ,我们需求 hook transformClassesWithBundleMultiDexList 的 Task 更调 mainDexList 文件,确保 aab 在转为全量 apk 时独霸该轨则。
  8. 当翻开 on-demand(按需加载)时 ,必须开启 Fusing(熔断独霸)才调正常的让 Api 21 以下的手机独霸 module
  9. 一样往常气候下,静态模块下发此后需求重启 App 才调加载成功 ,可是假定你独霸 SplitCompat library,便可以当即奏效
  10. 假定下载的模块太除夜 ,需求用户确认,GP 请求除夜于 10 MB 需求用户确认
  11. 国际上可独霸 Google Play 的 Play Core Lib 直接从 gp 布景下载我们上传好的 dynamic module.
  12. module 中的 AndroidManifest 中定义的 Activity 不克不及有 exported:true 因为此外 app 不晓得你甚么时辰拆卸好模块从而会激起问题
  13. proguard 文件在奏效的时辰会 merge base module 和全数的 dynamic module 中的文件,所以在编写 proguard 的时辰要寄看这个问题。

展看

          App Bundles 筹划在促进 APK 大年夜小方面  ,就有很除夜的优势 。可是 App Bundles 筹划依托与 Google Play 理应才调做到营业模块的按需加载 。可是如今爱奇艺开源了 Qigsaw 框架,本身完成了一套圭表类型 Google Play 的筹划 ,同时贯穿连接 API 的独霸与 Google Play 贯穿连接齐截 ,多么便可以做到国际与国外场景的逍遥切换 。