使用eclipse和gradle对Android应用进行批量打包

本文分享了使用Gradle进行Android应用多渠道打包的具体实践,包括配置示例、解决常见问题及注意事项。针对不同渠道自定义配置,实现自动化构建。

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

对于gradle配置可以看一下这个博客;我主要对我自己遇到的一些问题说明一下:

先上我的最终build.gradle的结果内容一:

apply plugin: 'android'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    compile project(':alipay_lib')
}
repositories {
  mavenCentral()
}

android {
    compileSdkVersion 17
    buildToolsVersion "19.0.1"

      //签名  
    signingConfigs {  
      myConfig {  
          storeFile file(**)      //签名文件  
          storePassword **      
          keyAlias **                    
          keyPassword <span style="font-family: Arial, Helvetica, sans-serif;">**</span>//签名密码  
      }  
    }
 buildTypes{
     release {
     signingConfig signingConfigs.myConfig
  runProguard true
  //zipAlign false
  proguardFile 'proguard-project.txt'
     }
   }
	
 lintOptions {
  abortOnError false
 }
	
  defaultConfig {
        versionCode getVersionCode()
        versionName getVersionName()
        minSdkVersion 8
        targetSdkVersion 17
    }
     
    productFlavors {
        hiapk{
        }
        _360cn{
        }
    }
	
 sourceSets {
        main {
            manifest {
                srcFile 'AndroidManifest.xml'
            }
            java {
                srcDir 'src'
            }
            res {
                srcDir 'res'
            }
            assets {
                srcDir 'assets'
            }
            resources {
                srcDir 'src'
            }
            aidl {
                srcDir 'src'
            }
            jniLibs{
                srcDir 'libs'
            }
        }
    }
}
android.applicationVariants.all{ variant -> 
    variant.processManifest.doLast{
        copy{
            from("${buildDir}/manifests"){
                include "${variant.dirName}/AndroidManifest.xml"
            }
            into("${buildDir}/manifests/$variant.name")
 
            filter{
                String line -> line.replaceAll("UMENG_CHANNEL_VALUE", ("${variant.productFlavors[0].name}"-'_'))
            }
 
            variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.name}/${variant.dirName}/AndroidManifest.xml")
        }    
   }
}

minSdkVersion 8 targetSdkVersion 17
这个要跟你在AndroidManifest中定义的一致;

</pre><pre code_snippet_id="572518" snippet_file_name="blog_20150105_5_9407819" name="code" class="html">filter{
                String line -> line.replaceAll("UMENG_CHANNEL_VALUE", ("${variant.productFlavors[0].name}"-'_'))
            }
这一段的作用是修改AndroidManifest中的统计键值对的值的,其中AndroidManifest中会有很多 <meta-data>的键值对, 统计的<meta-data>不要放到这些<meta-data>中的第一位,且value值需要放到name之前( UMENG_CHANNEL_VALUE是统计的value值),暂时不知道为什么,如果不这么修改 value值修改不了(也可能你的不会出现这种问题,有的话不放试试这么修改);


多渠道打包设置:hiapk和360cn渠道(自己添加不同的 渠道,因为我自己不需要对包进行特殊处理只需要修改渠道号,因此未对单个渠道进行特殊处理)

productFlavors {
        hiapk{
        }
        _360cn{
        }
    }


如果不想打debug包的话,可以使用命令行gradle assembleRelease 进行release构建,如果buildtype中设置zipAlign false,打包的结果中就会每种渠道中一个包;


第二种打包的配置结果如下:参考文章

apply plugin: 'android'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    compile project(':alipay_lib')
}
repositories {
  mavenCentral()
}

android {
    compileSdkVersion 17
    buildToolsVersion "19.0.1"

      //签名  
    signingConfigs {  
      myConfig {  
          storeFile file(**)      //签名文件  
          storePassword **      
          keyAlias **                    
          keyPassword **       //签名密码  
      }  
    }
 buildTypes{
     release {
     signingConfig signingConfigs.myConfig
  runProguard true
  //zipAlign false
  proguardFile 'proguard-project.txt'
     }
   }
	
 lintOptions {
  abortOnError false
 }
	
  defaultConfig {
        versionCode getVersionCode()
        versionName getVersionName()
        minSdkVersion 8
        targetSdkVersion 17
    }
     
    def falvors = getMyFlavorsFromFileSystem();
    productFlavors{
        prod{ }
        dev{ }
        _4T{}

        falvors.each{name,config->
            "$name"{
                sourceSets["$name"].res.srcDirs = [config.rrrr]
            }
        }

    }
	
  
	
 sourceSets {
        main {
            manifest { srcFile 'AndroidManifest.xml' }
            java { srcDir 'src' }
            res {  srcDir 'res' }
            assets { srcDir 'assets' }
            resources { srcDir 'src' }
            aidl { srcDir 'src' }
            jniLibs{ srcDir 'libs' }
        }
    }
}
def getMyFlavorsFromFileSystem(){
  flavors = [:]
  if (project.hasProperty('mc')){

   println '------setup flavors ---------------'
   def path = './build-type/type.txt'
   def prefix = '_'
   file(path).eachLine{ line ->
    println line
    def f = file("./build-type/$line")
    if (!f.exists()) {
     f.mkdir()
    }

    def resPath = file("./build-type/$line/" + prefix+line)
    if (!resPath.exists()) {
     resPath.mkdir()
    }

    copyRes(resPath.absolutePath,line)
    flavors.put(prefix+line,[
      rrrr : resPath
    ])
   }
  }
  return flavors
 }
	
 def copyRes(String path, String type) {  
  BufferedReader reader = file('./AndroidManifest.xml').newReader('utf-8')  
  StringBuffer _file = new StringBuffer()  
  reader.eachLine { line ->  
   _file.append(line).append("\n")  
  }  
  reader.close()  
   
  def dest_file = file(path+"AndroidManifest.xml")  
   
  BufferedWriter writer = new BufferedWriter(new FileWriter(dest_file))  
  writer.write(_file.toString() + "<!-- $type -->")  
  writer.close()  
 }
android.applicationVariants.all{ variant -> 
    variant.processManifest.doLast{
        copy{
            from("${buildDir}/manifests"){
                include "${variant.dirName}/AndroidManifest.xml"
            }
            into("${buildDir}/manifests/$variant.name")
 
            filter{
                String line -> line.replaceAll("UMENG_CHANNEL_VALUE", ("${variant.productFlavors[0].name}"-'_'))
            }
 
            variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.name}/${variant.dirName}/AndroidManifest.xml")
        }    
   }
}

这种也能成功打包,但是不知道最后这个 copyRes是什么作用,这个方法是我根据另外一个参考博文中的copy方法更改过来的

嗯,就这么多了,基本完成了我的需求!!


以上内容是我做测试的时候用的,转移到正式代码出现几个问题:

1、多个string资源文件中不能有重名的string的name值;

2、部分png图片不符合要求,又重新使用画图工具另存为了一下(可能会影响图片显示效果);

3、Could not create plugin of type 'LibraryPlugin',出现这么一个问题,参考文章修改了一下所有的相关的gradle-wrapper.properties文件中的distributionUrl的值,(这是因为使用gradle的时候与测试时导出的版本不一致了,没有更新gradle到最新版本,可以简单的这么修改一下)【这个问题是由于使用了与eclipse不匹配的gradle版本导致的,也就是说你的gradle环境最好与eclipse导出时gradle-wrapper.properties中给出的包一致】

4、AndroidManifest.xml文件中,通过gradle自动生成的一个manifest文件报错,通过报错的位置发现,应该是Manigest中的中文注释导致的,全部删掉。

好吧,表示搬到正式打包过程中遇到了一个非常蛋疼的问题,我们公司的渠道号是纯数字的,添加在meta-data中,但是AndroidManifest中却不支持纯数字的value值,最终只能修改为渠道号+英文字母的方法,在获取渠道号的时候再截取……

另外修改了一下替换Manifest的方法,使得能够支持注释,如下:

 String line -> line.replaceAll("UMENG_CHANNEL_VALUE", ("${variant.productFlavors[0].name}"-'_')).replaceAll("<!--.*?-->", "")


至于AndroidManifest中中文乱码问题,参照这里

修改一下GRADLE_HOME/bin/gradle(windows系统中是gradle.bat)中的变量DEFAULT_JVM_OPTS
DEFAULT_JVM_OPTS="-Dfile.encoding=UTF-8"

OK,编译通过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值