为了账号安全,请及时绑定邮箱和手机立即绑定

【备战春招】第2天 AppBundle动态交付原理

程名称:移动端架构师

课程章节:新一代组件化动态化方案App Bundle

课程讲师:CrazyCodeBoy LovelyChubby

课程内容:

与Instant App不同,AppBundle是借助android 5.0的Split Apk能力完成动态加载的

App Bundles 将一个 apk 拆分成多个 apk,我们的 apk 一般会被拆分为如下几个部分:

  • Base Apk(基本apk): 包含了所有其他拆分APK都可以访问的公共代码和资源,所以其他的模块都基于Base,并提供应用的基本功能 。当用户请求下载您的应用时,会首先下载并安装该APK

  • Configuration APKs:(配置apk) native libraries 和适配当前手机屏幕分辨率的资源

  • Dynamic feature APKs(动态下发apk) 

       每个动态功能 APK 包含应用中的某项功能的代码和资源,可以理解为模块化

这个是在后面按需的时候才会下载安装,第一次下载不会

比如一些模块功能如拍照,第一次安装不会安装这个apk,后面唤起拍照页的时候才去下载

Split Apks的运作原理有点类似于Android的组件化,安装应用程序时,首先安装base apk,然后安装split apks。

打开ApplicationInfo类中,可以看到如下信息:


     /**
     * Full paths to zero or more split APKs that, when combined with the base
     * APK defined in {@link #sourceDir}, form a complete application.
     */
    public String[] splitSourceDirs;

    /**
     * Full path to the publicly available parts of {@link #splitSourceDirs},
     * including resources and manifest. This may be different from
     * {@link #splitSourceDirs} if an application is forward locked.
     */
    public String[] splitPublicSourceDirs;

LoadeApk中有PathClassLoaderResources创建过程。

LoadedApk#mClassLoader是PathClassLoader实例引用,接着看PathClassLoader的创建过程。

public ClassLoader getClassLoader() {
        synchronized (this) {
            if (mClassLoader != null) {
                return mClassLoader;
            }
            if (mIncludeCode && !mPackageName.equals("android")) {
                ......
                final ArrayList<String> zipPaths = new ArrayList<>();
                final ArrayList<String> libPaths = new ArrayList<>();
                .......

                zipPaths.add(mAppDir);
                //将split apk路径追加到zipPaths中
                if (mSplitAppDirs != null) {
                    Collections.addAll(zipPaths, mSplitAppDirs);
                }

                libPaths.add(mLibDir);
                final String zip = TextUtils.join(File.pathSeparator, zipPaths);
                final String lib = TextUtils.join(File.pathSeparator, libPaths);

                ......
                //如果mSplitAppDirs不为空,则zip将包含base app和split apps所有路径。split apps路径,
                mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, lib,
                        mBaseClassLoader);
            } 
            return mClassLoader;
        }
    }

LoadedApk#mResources是Resources实例引用,Resources的源码如下:

可以发现:split apks资源路径(LoadedApk#mSplitResDirs)也会被增加至Resources中

public Resources getResources(ActivityThread mainThread) {
        if (mResources == null) {
            mResources = mainThread.getTopLevelResources(mResDir, mSplitResDirs, mOverlayDirs,
                    mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, null, this);
        }
        return mResources;
    }

课程收获:

谢谢老师,讲的非常细致,通俗易懂。这一节学的是AppBundle的动态加载原理,通过学习我了解AppBundle的Split Apk原理,给以后的学习打下了基础。
期待后边的学习




https://img1.sycdn.imooc.com/63e3acad000184a909300523.jpg

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
0
获赞与收藏
4

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消