插件化开发时,想要使app启动很快,需要将主dex中只是包含首页以及基础模块的功能,其他的功能放到从dex文件中,这样就可以加快app的启动速度。那如何将核心首页以及基础模块的class文件打包到主dex文件中呢?下面来实现这个过程。
1.首先要是项目支持multidex,要是项目支持multidex,需要完成下面两个步骤
a.需要在module级别的build.gradle文件中配置

android {    defaultConfig {        // 设置支持multidex        multiDexEnabled true    }   }dependencies {    //引入对multidex支持的库    compile 'com.android.support:multidex:1.0.1'}

b.完成这些配置后,需要在自定义的application中的attachBaseContext方法中添加如下代码:

   @Override    protected void attachBaseContext(Context base) {        super.attachBaseContext(base);        MultiDex.install(this);    }

完成了这两个步骤后,项目才支持多dex。

2,要明确主dex文件中要包含哪些class文件,明确后,在module的build.gradle所在的目录下,新建一个maindexlist.txt文件,并将这些class文件所在的路径都写入到这个文件中。

3.在build.gradle文件中,在加入如下配置信息

android {    defaultConfig {        // 设置支持multidex        multiDexEnabled true    }      //新增的配置信息    dexOptions{preDexLibraries = falseadditionalParameters = [    //配置multidex参数                                '--multi-dex',//多dex分包                                '--set-max-idx-number=30000',//每个包内方法数上限                                '--main-dex-list='+projectDir+'/maindexlist.txt', //打包到主classes.dex的文件列表                                '--minimal-main-dex'                            ]}}dependencies {    //引入对multidex支持的库    compile 'com.android.support:multidex:1.0.1'}

处理完后,打包apk,这样就会将maindexlist文件中指定的class文件打包到主dex文件中。这个就是将指定的class文件打包到主dex中的操作步骤,下面结合一个实际案例,来演示。
新建一个项目,在项目中新建一个名为plugin1的module,plugin1的结构如下图:

上图中build.gradle的配置信息如下:

apply plugin: 'com.android.application'android {    compileSdkVersion 28    buildToolsVersion "28.0.3"    defaultConfig {        applicationId "com.android.skill"        minSdkVersion 14        targetSdkVersion 28        versionCode 1        versionName "1.0"        // 设置支持multidex        multiDexEnabled true        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }    dexOptions{        preDexLibraries = false        additionalParameters = [    //配置multidex参数                                    '--multi-dex',//多dex分包                                    '--set-max-idx-number=30000',//每个包内方法数上限                                    '--main-dex-list='+projectDir+'/maindexlist.txt', //打包到主classes.dex的文件列表                                    '--minimal-main-dex'                                ]    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'        }    }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    compile 'com.android.support:appcompat-v7:28.0.0'    compile 'com.android.support.constraint:constraint-layout:1.1.3'    testCompile 'junit:junit:4.12'    androidTestCompile('com.android.support.test.espresso:espresso-core:+', {        exclude group: 'com.android.support', module: 'support-annotations'    })    compile 'com.android.support:multidex:1.0.1'    //依赖mypluglibrary库    compile project(path:':mypluglibrary')}

自定义的application中的代码如下:

import android.app.Application;import android.content.Context;import android.support.multidex.MultiDex;import android.util.Log;public class PluginOneApplication extends Application {    private static final String TAG = "MY_LOG";    @Override    protected void attachBaseContext(Context base) {        super.attachBaseContext(base);        MultiDex.install(this);    }    @Override    public void onCreate() {        super.onCreate();    }}

maindexlist.txt文件中的信息如下(com/android/skill,这个是项目的包名):

com/android/skill/bean/Person.classcom/android/skill/MainActivity.classcom/android/skill/PluginOneApplication.classcom/android/skill/PluginReceiverOne.classcom/android/skill/PluginReceiverTwo.class

这些文件,可以在项目的文件夹目录下去查看(注意,不要通过AS的目录结构查看,因为通过AS的目录结构查看,会漏掉XXX$1.class这样的class文件),下面是本案例的这些class文件的位置

将上图红框中这些class文件写入到maindexlist.txt文件中。

通过上面的步骤,就完成了将指定的class文件打包的主dex的功能。为了方便演示,指定和未定class到主dex的区别,新添加一个mypluglibrary库,将这个库的引入到plugin1这个module中,如果指定了只是将plugin1中的class文件打包到主dex中,则在生成的apk文件中,解压后是不会再主dex文件中看到mypluglibrary库的文件的。如果未指定将plugin1中的文件打包到主dex,则会在主dex中是可以看到mypluglibrary库中的 文件的。下面看看mypluglibrary库的结构图

在plugin1这个module中依赖mypluglibrary这个库

dependencies {      ...    //依赖mypluglibrary库    compile project(path:':mypluglibrary')}

完成上述步骤后,执行plugin1这个module,找到生成的apk文件,将apk文件,拖动到AS中,可以看到如下


从上图中,可以发现,确实使用多dex,图中有classes.dex和classes2.dex,其中,下面的大的红框中的就是在maindexlist.txt文件中指定的要将将这些文件打包打主dex的文件。

如果在plugin1的build.gradle文件中,去掉

additionalParameters = [    //配置multidex参数                                    '--multi-dex',//多dex分包                                    '--set-max-idx-number=30000',//每个包内方法数上限                                    '--main-dex-list='+projectDir+'/maindexlist.txt', //打包到主classes.dex的文件列表                                    '--minimal-main-dex'                                ]

这个配置,在执行plugin1这个module,在将重新生成的apk包拖到AS中,可以看到:

上图中,只有一个classes.dex,没有classes2.dex,并且,这个主classes.dex文件中是包含了依赖的库mypluglibrary的文件的,下面红框中的就是主dex文件包含的依赖库的文件。可以看出,未指定将哪些class文件放入到主dex,则在打包时,会根据单个dex的方法数是否会超过65535个方法来将主项目的类先添加后,如果方法数还未超过65535,则继续将依赖的库中的文件打包到主dex中。
如果在进行分包时报

java.io.FileNotFoundException: xxx\xxx\build\intermediates\transforms\dex\debug\folders\1000\1f\main\classes.dex\classes.dex (系统找不到指定的路径。)

则表示,项目还未支持multidex,需要进行multidex相关的配置,并在自定义的application中,调用MultiDex.install(this);方法。

更多相关文章

  1. android MultiDex multidex原理原理下遇见的N个深坑(二)
  2. Android(安卓)Studio如何取消与SVN的关联
  3. 如何Android数据库缓存进行管理
  4. Android系统篇之----Android中的run-as命令引出升降权限的安全问
  5. Android大图加载优化--基于LRU算法的本地文件缓存
  6. Android中资源文件(非代码部分)的使用概览
  7. 【转发】Android(安卓)Metro风格的Launcher开发系列第一篇
  8. 对 Android(安卓)开发者有益的 40 条优化建议
  9. 使用 buck 打包 Android( 使用OkBuck给Android(安卓)Studio+gradl

随机推荐

  1. JavaScript 逆向爬取实战(下)
  2. 骚操作!嵌套 JSON 秒变 Dataframe!
  3. PMP证书获得历程
  4. 如何实时主动监控你的网站接口是否挂掉并
  5. 再见 VBA!神器工具统一 Excel 和 Python
  6. Python分析5000+抖音大V,发现大家都喜欢这
  7. 原来炫酷的可视化地图,用Python就能搞定!
  8. 太骚了!Python模型完美切换SAS,还能这么玩
  9. pandas100个骚操作:变量类型自动转换
  10. Android(安卓)View中的onMeasure()方法详