课程名称:移动端架构师
课程章节:新一代组件化动态化方案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中有PathClassLoader和Resources创建过程。
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原理,给以后的学习打下了基础。
期待后边的学习
共同学习,写下你的评论
评论加载中...
作者其他优质文章