ant脚本使用multidex解决65536问题

现在的android项目应该大多都用gradle构建了吧,但是仍然有很多老项目使用的ant工具,这里并不推荐使用ant构建,因为最新的android sdk tools里边已经去掉了ant相关的lib包。不管gradle也好,ant也好,其实编译打包apk的过程基本都是一样的。

我遇到的这个项目,经历了两次方案的调整。

方案一:

最开始并没用dx的multidex参数,而是将所有的第三方jar包(应用启动时用的除外)打到从包中去,从包可以是多个,剩下的源码打到主包中,也就是分别调用dx打出dex包。


        
        
        
            
            

            
            
                
                    
                
                
                    
                        
                    
                
            
            Converting external libraries into ${assets}/${dex}...
	    
	    
	    
            	
            	    
            	    
                        
                    
                
            	
            		
				alljarpath="project.all.jars.path"
			   	plugjarconfig="${plug.jar.config}"
			   	plugjarconfig2="${plug.jar.config2}"
			    	plugjarpath="project.plug.path"
			    	plugjarpath2="project.plug.path2"
			    	projectjarpath="project.core.path"/>
                     	
                         
	              		 
                   	 
                
	   

            
                
            
            
                
            
            
            
	    
	    
	    
	              
                
            
            
        
    

其中separete和filterlib是两个自定义的task,作用都是从project.all.jars.path中过滤出事先定义好的第三方jar包的path,区别是separete是在代码经过混淆后执行,将混淆后的代码生成plug.jar,可以看到调用了三次dex。

代码中加载从包的方法:

	PathClassLoader pathClassLoader = (PathClassLoader) app.getClassLoader();
	DexClassLoader dexClassLoader = new DexClassLoader(libPath, app.getDir("dex", 0).getAbsolutePath(), libPath, app.getClassLoader());
	InjectResult result = null;
	try {
		Object dexElements = combineArray(getDexElements(getPathList(pathClassLoader)), getDexElements(getPathList(dexClassLoader)));
		Object pathList = getPathList(pathClassLoader);
		setField(pathList, pathList.getClass(), "dexElements", dexElements);
	} catch (IllegalArgumentException e) {
		result = makeInjectResult(false, e);
		e.printStackTrace();
	}

DexClassLoader加载从包dex,然后将pathClassLoader与dexClassLoader中的DexPathList的dexElements属性值合并,再放到pathClassLoader中的DexPathList中。最开始方案一是满足需求的,但随着主包越来越大,终于还是65536了,这种只分出去第三方jar包的做法还是不太灵活,于是有了方案二。

方案二:

使用dx的multidex参数,指定maindexlist清单文件,在这个清单文件中的类会打到主包中,清单文件的生成可以使用build-tools下的mainDexClasses脚本生成。

 
		
        
        
            
            
			 
                
                    
                
                
                    
                        
                    
                
            
            
            
	              
                  
                
            
        
    

        

        
        
            
                
            
            
                
                    
                
            
        
        
            
            
        
    

m ultidex和maindexlist也是两个自定义task,multidex其实就是调用的dx --dex --multi-dex --main-dex-list=maindexlist.txt  --minimal-main-dex --output bin --input-list,maindexlist task的作用是生成混淆后的主包清单文件。应用启动时代码原理和方案一差不多,也可以直接使用官方的android-surpport-multidex.jar包

你可能感兴趣的:(android,java,ant,android)