美文网首页
QigsawBundle技术细节

QigsawBundle技术细节

作者: DonaldDu | 来源:发表于2021-03-30 00:58 被阅读0次

最新依赖-jitpack
Google的AAB出来好久了,但在国内一直没法用。知道Qigsaw后就开始学习,弄了好久都没学会,太烦了中途都放弃了。后来有时间了,又来学习这个,因为真实用啊!

直到学会了,还有问题

  • 编译后无法Clean
  • 不支持最新的 'com.android.tools.build:gradle:4.1.3'
  • Demo代码太繁琐,不容易懂
  • 使用起来也比较麻烦

学会后,我觉得不应该这样麻烦,是可以非常简单的!
可以把Qigsaw拆分为运行框架和打包工具,因此有了QigsawBundle

DynamicProvider

Provider在应用启动时就会被调用,Dynamic中的Provider第一次启动是找不到的,应用会直接报错,无法启动。Qigsaw为每个DynamicProvider生成了一个装饰类,找不到原DynamicProvider时,就调用装饰类。

QigsawBundle不生成任何装饰类,而是通过工具DynamicProviderSwitch自动把DynamicProvider设置为关闭状态(android:enabled="false")。启动应用时,再读取manifest中哪些DynamicProvider类存在,如果存在则启动Provider,不存在则忽略。Split安装后重试未启动成功的DynamicProvider。

DynamicProviderSwitch:编译时自动关闭Split中的Provider,应用启动时,启动存在的DynamicProvider。

DynamicProviderSwitch支持Google的AAB,可以直接用在海外版的App中

Activity/Service/BroadcastReceiver

Qigsaw打包时,织入了一些代码。经测试证明,不需要在编译期间织入代码的,
Activity/Service/BroadcastReceiver都可以通过运行时代码解决。
可以在ActivityLifecycleCallbacks.onActivityPreCreated中loadResources,
另外两个使用的application.resources ,所以不需要处理。

以下代码都测试通过了。

override fun onActivityPreCreated(activity: Activity, savedInstanceState: Bundle?) {
    SplitInstallHelper.loadResources(activity, activity.resources)
}
Service.resources ==applicationContext.resources//true
BroadcastReceiver.context.resources==context.applicationContext.resources//true

onActivityPreCreated 只有Android10+才支持,之前的版本没有用。所以需要用织入代码的方式来解决。

QigsawBundle在onActivityPreCreated中注入resources,因此省去了编译期织入代码。

    private Qigsaw(Context context, Downloader downloader, @NonNull SplitConfiguration splitConfiguration) {
        this.context = context;
        this.downloader = downloader;
        this.splitConfiguration = splitConfiguration;
        this.currentProcessName = ProcessUtil.getProcessName(context);
        this.isMainProcess = context.getPackageName().equals(currentProcessName);
        InjectActivityResource.inject((Application) context);//QigsawBundle注入resources
    }

CompatBundle

为了让独立打包的Split能运行起来,需要Qigsaw框架做一些兼容处理。如果不实现以下接口,则完全按照标准的Qigsaw方式运行。具体使用参考Demo。

public interface ICompatBundle {
    /**
     * for 'parseSplitContentsForDefaultVersion'
     */
    @Nullable
    String readDefaultSplitVersionContent(@NonNull Context context, @NonNull String fileName);

    @NonNull
    String getMD5(@NonNull File file);

    @NonNull
    String getMD5(@NonNull InputStream inputStream);

    /**
     * 在onActivityPreCreated中注入resources
     */
    boolean injectActivityResource();

    /**
     * 因为没有生成任何装饰类,所以ComponentInfoManager是没有数据的,所以需要禁用了
     */
    boolean disableComponentInfoManager();

    /**
     * 没有自动生成的 qigsawConfig,需要指定一个自己创建的
     */
    Class<?> qigsawConfigClass();
}

ApkMd5

QigsawBundle中所有Apk计算MD5都使用的ApkMd5,源码也在项目中。

ApkMd5:"AndroidManifest.xml"去掉版本号,去掉"META-INF/BNDLTOOL.RSA"、 "META-INF/BNDLTOOL.SF"、"META-INF/MANIFEST.MF",所有文件排序,再计算APK的MD5。

QigsawBundle可以做到:只修改Base的版本号(versionName&versionCode),然后打包。所有Split的ApkMd5值都是固定的,仅Base包变了。proguard存在一个BUG,需要特别方法才能做到这样。具体请参考 稳定混淆App

DEMO

有时间了会写个QigsawBundle使用介绍,先写了个原理。
DEMO

最后

如果本文帮助到了你,也帮我点个赞吧!

如果你愿意,还可以赞赏一杯咖啡或一瓶水,非常感觉你的慷慨!

相关文章

  • QigsawBundle技术细节

    最新依赖-jitpack[https://jitpack.io/#com.github.DonaldDu/Qigs...

  • QigsawBundle之ContentProvider优化

    缘由 其实不做优化,DynamicProviderSwitch也够用了。主要是想简化编译流程,提高编译速度,且尽量...

  • HBase知识点

    深度分析HBase架构 HBase技术简介 Hbase 技术细节笔记(上) Hbase 技术细节笔记(下) 回答思...

  • iOS超级签名

    摘抄自:超级签名-原理/机制/技术细节-完全解析蒲公英:超级签名 超级签名-原理/机制/技术细节-完全解析 随着苹...

  • 技术细节

    1.传统的js加载 在加载过程中,网页会停止渲染,进入等待,同时相互之间存在严格的依赖,如果1.js中要求的资源在...

  • 今日份打卡 190/365

    文章分享技术总监需要懂技术细节吗?

  • 第2章第3节Hello World

    内容摘要 本节将展示所有基础的技术细节,在从比较抽象的层面讲解了系统之后,我们必须深入到技术细节,从细节方面来说明...

  • 如何分析一个网站的架构

    简介 从一个浏览者的角度来最大地获取一个网站的架构信息。包括的方面:技术细节、内容组织。 技术细节 分析一个网站的...

  • Pinpoint技术细节

    本文将讲述Pinpoint的技术,如事务追踪和字节码增强。并介绍应用于Pinpoint Agent的优化方法,该方...

  • 程序员怒怼阿里P10,一周能撸出一个企业级项目?网友:井底之蛙

    什么是好的程序员?是不是懂得很多技术细节?还是懂底层编程?还是编程速度比较快?我觉得都不是。对于一些技术细节来说和...

网友评论

      本文标题:QigsawBundle技术细节

      本文链接:https://www.haomeiwen.com/subject/plqlcltx.html