Android分包(Multidex)

本文介绍了Android分包(Multidex)的概念、原因,详细讲解了Java的类加载器机制,包括BootstrapClassLoader、ExtClassLoader和AppClassLoader,并讨论了父委托加载机制的优势。接着探讨了Android中的PathClassLoader和DexClassLoader。最后,文章详细阐述了使用Gradle进行分包的步骤、注意事项及其优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

推荐使用AS,只需要在gradle中进行配置和添加一些代码即可实现分包

Multidex实现及原理

1. 什么是分包?分包可以解决什么问题?

分包(multidex)是指apk文件中含有多于一个classes.dex的dex文件,如classes2.dex。

下面是我的一个私人项目,我们在AndroidStudio中,对该项目APK进行分析,获得该apk下的目录结构如图:

我们可以看到上面的apk目录结构中有且仅有一个classex.dex文件。

 

  • classes.dex:代码文件
  • res:资源
  • lib:存放so库文件
  • resources.arsc:资源的索引,相对于R目录,(上面的目录结构中没有)
  • META-INF:签名信息
  • AndroidManifest.xml:清单文件
  • assets:资源文件(无ID)

 

再来看下我反编译的某应用下目录结构:

 

可以看到除了classes.dex外还有一个classes2.dex。

了解了什么是分包后,再来思考为啥要在自己的项目中去费力的多分一个.dex文件。不分不行吗?还真就得分。

在Android 5.0以前使用的是dalvik虚拟机,dalvik虚拟机中使用了一个short字段来保存一个dex方法数,最大不能超过65535。倘若我们的应用越来越大,方法数也是越来越多,为了程序不发生ANR等就势必要采用分包来减少classes.dex中的方法数。

 

2. Java中Classloader机制介绍

2.1 Java中常见的类加载器:

(1)BootstrapClassLoader:纯C++实现的类加载器,没有对应的Java类,主要加载jre/lib/目录下的核心库

(2) ExtClassLoader:类全名是sun.misc.Launcher$ExtClassLoader,主要加载/jre/lib/ext/目录下的扩展包

(3)AppClassLoader:sun.misc.Launcher$AppClassLoader,主要加载CLASSPATH路径下的包

2.2 一个类加载器如何加载一个类

加载一个类的过程:工程中的类被AppClassLoader加载,首先会委托给它的父加载器ExtClassLoader去加载,同样的,ExtClassLoader会委托给它的父加载器去加载,但是ExtClassLoader是没有父加载器的,所以委托给了BootstrapClassLoader,(BootstrapClassLoader为最顶级的ClassLoader),它会直接去加载:%java_home%/jre/lib路径下的,如果加载成功就返回ExtClassLoader,ExtClassLoader再返回到AppClassLoader,一个类的加载到此结束。如果BootstrapClassLoader加载失败,需要ExtClassLoader自己利用findClass(name)到路径:%java_home%/jre/lib/ext目录下去加载,如果加载成功返回给AppClassLoader,如果加载失败,就需要AppClassLoader自己利用findClass(name)到路径:CLASSPATH下去加载。这就是父委托机制的加载流程。

2.3 父委托加载机制的好处

可以提高软件系统的安全性。

 

3. Android中常用的类加载器

 

  • PathClassLoader: 加载/data/app目录下apk文件,PathClassLoader主要用来加载已经安装好了的apk。
  • DexClassLoader: 加载路径需要在创建DexClassLoader时传入,可以加载任何路径下的apk/dex/jar。(可以加载没有被安装好的apk文件)

 

Android 官网介绍传送门

 

4. 两种分包方案原理介绍和动态加载

4.1 Ant实现方式

(由于ant主要是与eclipse来配合使用的,所以感兴趣的可以自行百度或谷歌)

4.2 Gradle实现分包的原理及过程

谷歌对于分包:http://developer.android.com/tools/building/multidex.html

Gradle分包的步骤:

第一步添加:multiDexEnabled true

 

android {
    ...
    defaultConfig {
       
       ...
       //Enabling multidex support
       multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}


第二步添加:compile'com.android.support:multidex:1.0.0'

 

 

dependencies {
   compile'com.android.support:multidex:1.0.0'
}


第三步执行:

 

 

public class MyApplication extends MultiDexApplication{
    
    @Override
    public void onCreate(){
 
    }
}

//或者

public void onCreate(Bundle arguments){
    MultiDex.install(getTargetContext());
    super.onCreate(arguments);
}

(适用于项目中有自定义Application情况)。
 

 

4.3 分包注意事项

Gradle分包的优缺点:

优点

 

  • 使用简单
  • 分Dex可以进行混淆

 

缺点

 

  • 无法手动制定哪些类放入分Dex
分包时可能遇到的问题。
UNEXPECTED TOP-LEVEL ERROR
java.lang.OutOfMemoryError:Java heap space...
 
解决方法:
android{
    //...
    dexOptions{
        javaMaxHeapSize"2g"
    }
}

 
 
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值