转载请标明出处:http://blog.csdn.net/goldenfish1919/article/details/42006649
工程大了以后,不可避免就会出现方法数目超出65536的限制,很幸运的是新的android提供了多dex打包的方式可以解决这个问题。下面我们就来看下如何用android-maven-plugin打多dex包。
先看下工程结构:
并不是一个标准的maven工程,但是可以通过更改配置来完成打包。工程的代码非常简单,MainActivity有一个按钮,点击按钮跳转到SecondActivity,SecondActivity中引用了fastjson做了一个对象转string的操作,然后弹出toast提示。还有就是DemoMultiDexApplication继承了MultiDexApplication。假如你的Application已经继承了别的类,那么也可以重写attachBaseContext()来实现。
public class DemoMultiDexApplication extends MultiDexApplication { /*如果已经继承了别的类,可以重写下面的方法 @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } */ }
重点看一下pom:
<?xml version="1.0" encoding="utf-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.test</groupId> <artifactId>multidexdemo</artifactId> <version>1.0.0</version> <packaging>apk</packaging> <name>multidexdemo</name> <properties> <sign.keystore>${project.basedir}/debug.keystore</sign.keystore> <sign.alias>androiddebugkey</sign.alias> <sign.storepass>android</sign.storepass> </properties> <dependencies> <dependency> <groupId>com.google.android</groupId> <artifactId>android</artifactId> <version>4.3.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.45</version> </dependency> <dependency> <groupId>com.android.support</groupId> <artifactId>multidex</artifactId> <version>20</version> </dependency> </dependencies> <build> <finalName>${project.artifactId}-${project.version}</finalName> <sourceDirectory>src</sourceDirectory> <plugins> <!--编译插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.6</source> <target>1.6</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!--resource插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> <!--签名插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jarsigner-plugin</artifactId> <version>1.2</version> <executions> <execution> <id>signing</id> <goals> <goal>sign</goal> <goal>verify</goal> </goals> <phase>package</phase> <inherited>true</inherited> <configuration> <removeExistingSignatures>true</removeExistingSignatures> <archiveDirectory /> <includes> <include>target/${project.artifactId}-${project.version}.apk</include> </includes> <keystore>${sign.keystore}</keystore> <alias>${sign.alias}</alias> <storepass>${sign.storepass}</storepass> <verbose>true</verbose> </configuration> </execution> </executions> </plugin> <!--android-maven-plugin--> <plugin> <groupId>com.simpligility.maven.plugins</groupId> <artifactId>android-maven-plugin</artifactId> <version>4.0.0</version> <configuration> <source>1.6</source> <target>1.6</target> <encoding>UTF-8</encoding> <!--设置AndroidManifest,assets,libs,res的路径,如果是标准的maven工程不需要设置--> <androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile> <assetsDirectory>${project.basedir}/assets</assetsDirectory> <nativeLibrariesDirectory>${project.basedir}/libs</nativeLibrariesDirectory> <resourceDirectory>${project.basedir}/res</resourceDirectory> <failOnDuplicatePackages>false</failOnDuplicatePackages> <sdk> <path>${env.ANDROID_HOME}</path> <platform>19</platform> </sdk> <!--混淆--> <proguard> <skip>false</skip> <config>${project.basedir}/proguard.cfg</config> <proguardJarPath>${project.basedir}/tools/proguard.jar</proguardJarPath> <jvmArguments> <jvmArgument>-Xms256m</jvmArgument> <jvmArgument>-Xmx512m</jvmArgument> </jvmArguments> </proguard> <dex> <jvmArguments> <jvmArgument>-Xms2048m</jvmArgument> <jvmArgument>-Xmx2048m</jvmArgument> </jvmArguments> <!--使用多dex打包--> <multi-dex>true</multi-dex> <minimal-main-dex>true</minimal-main-dex> <dex-arguments>--set-max-idx-number=65536</dex-arguments> <!--主dex里面的class--> <main-dex-list>${project.basedir}/MainDexList.txt</main-dex-list> </dex> <!--禁用默认的debug签名--> <sign> <debug>false</debug> </sign> </configuration> <extensions>true</extensions> </plugin> </plugins> </build> </project>
MainDexList.txt:
android/support/multidex/MultiDex.class android/support/multidex/MultiDex$V4.class android/support/multidex/MultiDex$V14.class android/support/multidex/MultiDex$V19.class android/support/multidex/MultiDexApplication.class android/support/multidex/MultiDexExtractor.class android/support/multidex/MultiDexExtractor$1.class android/support/multidex/ZipUtil.class android/support/multidex/ZipUtil$CentralDirectory.class com/example/hello/DemoMultiDexApplication.class
这里面列出了放在主dex中的类。
proguard.cfg:
-dontpreverify -repackageclasses '' -allowaccessmodification -optimizations !code/simplification/arithmetic -keepattributes *Annotation* -keep public class * extends android.app.Activity -keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep public class * extends android.view.View { public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); public void set*(...); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclassmembers class * implements android.os.Parcelable { static android.os.Parcelable$Creator CREATOR; } -keepclassmembers class **.R$* { public static <fields>; } -keep class com.example.hello.Person{*;} -keep class android.support.multidex.*{*;} -dontwarn com.alibaba.fastjson.** -keep class com.alibaba.fastjson.**{*;} -keep class com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter { *; } -keep class com.alibaba.fastjson.support.spring.FastJsonJsonView { *; } -dontwarn com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter -dontwarn com.alibaba.fastjson.support.spring.FastJsonJsonView
签名的时候就是使用的默认的keystore来签名的。
所使用的maven环境:
以上就是所有要做的了。
另外就是maven打好的包很可能启动不起来,可以用adb logcat来抓取logcat的日志。
完整的工程在这:http://download.csdn.net/detail/goldenfish1919/8274385
拷贝文件用的plugin:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.5</version> <executions> <execution> <id>copy-resources</id> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${basedir}/res/drawable/</outputDirectory> <resources> <resource> <directory>${basedir}/securityjpg/</directory> <filtering>true</filtering> <includes> <include>*.jpg</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin>
多个源码目录:
<build> <finalName>${project.artifactId}-${project.version}</finalName> <sourceDirectory>src</sourceDirectory> <resources> <resource> <targetPath>${basedir}/src/</targetPath> <directory>${basedir}/src1/</directory> <includes> <include>**</include> </includes> <filtering>true</filtering> </resource> <resource> <targetPath>${basedir}/src/</targetPath> <directory>${basedir}/src2/</directory> <includes> <include>**</include> </includes> <filtering>true</filtering> </resource> <resource> <targetPath>${basedir}/src/</targetPath> <directory>${basedir}/src3/</directory> <includes> <include>**</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
参考:
http://www.infoq.com/cn/news/2014/11/android-multidex
https://github.com/simpligility/android-maven-plugin
http://stackoverflow.com/questions/26530654/android-multidex-support-library-using-eclipse
https://github.com/lsuski/maven-multidex-sample
http://simpligility.github.io/android-maven-plugin/dex-mojo.html