用Gradle 构建你的android程序

原创
2013/05/20 04:12
阅读数 3.2K

<div class="span9"> <div class="content"><header class="page-header"> <div class="icon"></div> <time datetime="2013-05-19T00:00:00.000Z"><a href="/2013/05/19/android4gradle/">May 19 2013</a></time> <h1 class="title">用Gradle 构建你的android程序</h1> </header> <div id="post" class="entry"> <h2 id="menuIndex0">前言</h2> <p>android gradle 的插件终于把混淆代码的task集成进去了,加上最近,android studio 用的是gradle 来构建项目, 下定决心把android gralde 构建项目的用户指南全部看完, 让不会用gradle 的人也用gradle构建android项目,让打包(注意,打包和构建是两码事)多版本android不再痛苦。最后,题外话:珍惜生命,远离ant.... <a name="more"></a></p> <h2 id="menuIndex1">Gradle build android 历史</h2> <p><a href="http://tools.android.com">Android Tools 主页</a> ,大概是今年2月份发布 adt21.1 的时候,忽然在主页发现了<a href="http://tools.android.com/tech-docs/new-build-system">New Build System</a> 原来是可以用gradle 来构建android项目,至于<a href="http://en.wikipedia.org/wiki/Gradle">gradle</a>是什么(既然点击进来看了应该都知道了吧。) 。然后,又看了一下<a href="http://tools.android.com/tech-docs/new-build-system/roadmap">RoadMap</a> 那时候,还并不支持Proguard 打包,于是就没看了。。。</p> <p>最近,android studio 发布,终于gradle 0.4 也跟着出来了,于是,先把gradle 学了一遍,然后把<a href="http://tools.android.com/tech-docs/new-build-system/user-guide">Gradle Plugin User Guide</a>也认真阅读了一下,根据我的个人体验,如果你对gradle 毫无了解就去看<a href="http://tools.android.com/tech-docs/new-build-system/user-guide">Gradle Plugin User Guide</a> 可能很多地方都一头雾水,但是并不妨碍你用gradle 打包android 应用,只是,出现问题,你就可能很头疼。不过,本篇博文就是让不会gradle 也能用上 gradle 打包android 程序,因为,我也不懂gradle,所以,我把我碰到的问题的解决方案都一一列出。</p> <p>顺便贴上官方为什么使用gradle 的理由</p> <ul> <li>Domain Specific Language (DSL) to describe and manipulate the build logic </li> <li>Build files are Groovy based and allow mixing of declarative elements through the DSL and using code to manipulate the DSL elements to provide custom logic. </li> <li>Built-in dependency management through Maven and/or Ivy. </li> <li>Very flexible. Allows using best practices but doesn’t force its own way of doing things. </li> <li>Plugins can expose their own DSL and their own API for build files to use. </li> <li>Good Tooling API allowing IDE integration </li> </ul>

  <h2 id="menuIndex3">Gradle 基本概念</h2>

  <p>首先我们学习几个gradle 的脚本语法,掌握了这几个语法,你就能非常简单的用gradle构建打包android项目了。首先,我们来看下一个最简单android <code>build.gradle</code>。</p>

<figure class="highlight lang-groovy"><figcaption><span>build.gradle </span></figcaption>

  <table><tbody>
      <tr>
        <td class="gutter">
          <pre>1

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17</pre> </td>

        <td class="code">
          <pre>	

buildscript <span class="cell">{

 repositories {
        mavenCentral()
    }</span>

    dependencies <span class="cell">{
        classpath <span class="string">'com.android.tools.build:gradle:0.4'</span>
    }</span>
}

apply plugin: <span class="string">'android'</span>

android <span class="cell">{
    compileSdkVersion <span class="number">17</span>
}</span></pre>
        </td>
      </tr>
    </tbody></table>

</figure>

  <p><strong>英语的介绍都来自与 gradle官方文档, 主要后边的中文不是翻译,是补充介绍。。</strong></p>

  <p><code>buildscript{}</code></p>

  <blockquote>
    <p>Configures the build script classpath for this project. 说白了就是设置脚本的运行环境</p>
  </blockquote>

  <p><code>repositories{}</code></p>

  <blockquote>
    <p>Returns a handler to create repositories which are used for retrieving dependencies and uploading artifacts produced by the project. 大意就是支持java 依赖库管理(maven/ivy),用于项目的依赖。这也是gradle 强力的地方。。。 </p>
  </blockquote>

  <p><code>dependencies{}</code></p>

  <blockquote>
    <p>The dependency handler of this project. The returned dependency handler instance can be used for adding new dependencies. For accessing already declared dependencies, the configurations can be used. 依赖包的定义。支持maven/ivy,远程,本地库,也支持单文件,如果前面定义了<code>repositories{}</code>maven 库,使用maven的依赖(我没接触过ivy。。)的时候只需要按照用类似于<code>com.android.tools.build:gradle:0.4</code>,gradle 就会自动的往远程库下载相应的依赖。</p>
  </blockquote>

  <p><code>apply plugin:</code></p>

  <blockquote>
    <p>声明构建的项目类型,这里当然是android了。。。</p>
  </blockquote>

  <p><code>android{}</code></p>

  <blockquote>
    <p>设置编译android项目的参数,接下来,我们的构建android项目的所有配置都在这里完成。</p>
  </blockquote>

  <h2 id="menuIndex4">构建一个Gradle android项目</h2>

  <p>首先,你要安装<a href="http://www.gradle.org/downloads">Gradle 1.6</a> 并且,写进系统的环境变量里面,所有的命令都是默认你已经配好了gradle 的环境。而且,已经已经升级了android sdk 22</p>

  <p>要用gradle构建你的有两种方式:(<strong>build.gradle 放到项目目录下</strong>)</p>

  <ol>
    <li>利用adt 22导出 build.gradle. </li>

    <li>复制别人写好的build.gradle 文件. </li>

    <li>根据gradle 规则,手写android 的build.gradle 文件。 </li>
  </ol>

  <p>个人推荐1,2 方法。。。。</p>

  <p>一个android build.gradle 最基本基本文件</p>

<figure class="highlight lang-groovy"><figcaption><span>build.gradle </span></figcaption>

  <table><tbody>
      <tr>
        <td class="gutter">
          <pre>1

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39</pre> </td>

        <td class="code">
          <pre>buildscript {

repositories {
    mavenCentral()
}

dependencies {
    classpath <span class="comment">'com.android.tools.build:gradle:0.4'</span>
}

}

apply plugin: <span class="comment">'android'</span>

dependencies { }

android {

compileSdkVersion <span class="number">17</span>
buildToolsVersion <span class="string">&quot;17&quot;</span>

defaultConfig {
    minSdkVersion <span class="number">8</span>
    targetSdkVersion <span class="number">17</span>
}
sourceSets {
    main {
        manifest.srcFile <span class="comment">'AndroidManifest.xml'</span>
        java.srcDirs = [<span class="comment">'src']</span>
        resources.srcDirs = [<span class="comment">'src']</span>
        aidl.srcDirs = [<span class="comment">'src']</span>
        renderscript.srcDirs = [<span class="comment">'src']</span>
        res.srcDirs = [<span class="comment">'res']</span>
        assets.srcDirs = [<span class="comment">'assets']</span>
    }

    instrumentTest.setRoot(<span class="comment">'tests')</span>
}

}</pre> </td> </tr> </tbody></table>

</figure>

  <p>接着在命令行cd 到项目目录下</p>

  <blockquote>
    <p>例如: cd e:\workplace\andoridGradle</p>
  </blockquote>

  <p>如果你是第一次使用gradle 构建android项目建议你先使用<code>gradle clean</code> 把android gradle 插件,还有相关依赖包下载下来并且对环境进行初始化,如果出错了,一般可能是下载超时,试多几次即可,最后你会看到如下提示:<code>BUILD SUCCESSFUL</code></p>

  <p>The TaskContainer.add() method has been deprecated and is scheduled to be remove d in Gradle 2.0. Please use the create() method instead.</p>

  <p>:clean UP-TO-DATE</p>

  <p>BUILD SUCCESSFUL</p>

  <p>Total time: 7.847 secs</p>

  <p>完成以上的步骤,就可以正式使用gralde 构建你的android项目了。</p>

  <p>然后使用<code>gradle build</code> 就完成了android 项目的构建了。如果,你是照着以上步骤走的话,你将会想项目目录里面看到一个build 的目录,里面就是用gradle 构建android项目的全部例如了,结构目录看附录。</p>

  <p>最终打包的apk 就在build/apk 目录下了。然后,你会发现,两个apk 一个是 <em>[项目名]-debug-unaligned </em>[项目名]-release-unsigned</p>

  <p>如果以上内容你都掌握的话,接下来就将详细说说如何利用gralde 打包android apk。</p>

  <h2 id="menuIndex5">Gralde 打包参数详解</h2>

  <p>上面说了一大堆东西,其实并不吸引人去使用gradle,如果只是构建项目的话,adt不是更合适吗?如果,你看完以下内容还是这么觉得的话,你就没必要折腾gradle了。。。。。。</p>

  <h3 id="menuIndex6">打签名包</h3>

  <p>看附录 默认输出 <em>release</em> apk 是没有签名的,那么我们需要签名的很简单,只需要在android{}里面补充加上加上即可。完整<a href="https://gist.github.com/youxiachai/5608223">build.gradle 请点击我的gist</a></p>

<figure class="highlight lang-groovy"><figcaption><span>build.gradle </span></figcaption>

  <table><tbody>
      <tr>
        <td class="gutter">
          <pre>1

2 3 4 5 6 7 8 9 10 11 12 13 14 15</pre> </td>

        <td class="code">
          <pre>signingConfigs <span class="cell">{

myConfig{ storeFile file("gradle.keystore") storePassword "gradle" keyAlias "gradle" keyPassword "gradle" }</span> }

buildTypes<span class="cell">{ release { signingConfig signingConfigs.myConfig }</span> } </pre> </td> </tr> </tbody></table>

</figure>然后,运行<code>gradle clean</code> <code>gradle build</code> ,这次在build/apk 你看到了多了一个[项目名]-release-unaligned, 从字面上面我就可以知道,这个只是没有进行zipAlign 优化的版本而已。而[项目名]-release 就是我们签名,并且zipAlign 的apk包了. ###打混淆包### 只需要在原来的基础上加上,完整的<a href="https://gist.github.com/youxiachai/5608223">proguad.gradle 代码</a> <figure class="highlight lang-groovy"><figcaption><span>build.gradle </span></figcaption>

  <table><tbody>
      <tr>
        <td class="gutter">
          <pre>1

2 3 4 5 6 7 8</pre> </td>

        <td class="code">
          <pre>buildTypes{

release { signingConfig signingConfigs.myConfig runProguard <span class="literal">true</span> proguardFile <span class="comment">'proguard-android.txt'</span> } }</pre> </td> </tr> </tbody></table>

</figure>

  <p><code>gradle clean</code></p>

  <p><code>gradle build</code></p>

  <h3 id="menuIndex7">打多渠道包(Product Flavor)</h3>

  <p>现在来解释一下上一节的问题,<strong>apk目录下的两个apk 的含义</strong></p>

  <p><strong>为什么产生了两个apk?</strong></p>

  <p>默认的android gralde 插件定义了两种apk 的类型<strong>debug</strong>, <strong>release</strong>,这两种类型的详细对比看附录。</p>

  <p>这个是android gralde 插件 <code>buildTypes{}</code> 方法产生的,默认配置好了两个默认模板,当然你也可以修改,前面我们就是在修改默认的release 的配置,让输出release类型的的apk,具有签名和混淆。</p>

  <p>对于多渠道包,android 插件提供了一个名为<code>Product Flavor{}</code> 的配置,用于进行多渠道打包。</p>

  <p>例如,我的android应用有海外版,和国内版本,而且这两个版本的包名是不一样的!!(我就举两个市场的例子安装这个思路,你要打包100个不同的市场只是几行代码的事情。)。</p>

  <p>你只需要在<code>android{}</code> 补充上</p>

<figure class="highlight lang-groovy"><figcaption><span>build.gradle </span></figcaption>

  <table><tbody>
      <tr>
        <td class="gutter">
          <pre>1

2 3 4 5 6 7 8</pre> </td>

        <td class="code">
          <pre>productFlavors {
playstore {
		packageName=<span class="comment">'com.youxiachai.androidgradle.playstore'</span>
}
hiapk {
		packageName=<span class="comment">'com.youxiachai.androidgradle.amazonappstore'</span>
}

}</pre> </td> </tr> </tbody></table>

</figure>

  <p>然后<code>gradle clean</code>,<code>gradle build</code>,在build/apk 下面你会看到一堆的包,命名格式[项目名]-[渠道名]-release</p>

  <p><strong>仅此而已?</strong></p>

  <p><code>Product Flavor{}</code> 不只是能改包名那么简单,还能够对编译的源码目录进行切换。</p>

  <p>什么意思? 不知道各位有没有用过友盟做用户统计,如果,你用的是分发渠道分析,你需要修改AndroidManifest.xml 添加上 <code>&lt;meta-data android:value=&quot;hiapk&quot; android:name=&quot;UMENG_CHANNEL&quot;/&gt;</code></p>

  <p>如果,你很多渠道,,然后你就会很痛苦,现在用gradle 就非常舒服,你只需要在<code>android.sourceSets</code>指定我们的渠道名就行,android gradle 插件,会自动打包!!!例如</p>

<figure class="highlight lang-groovy"><figcaption><span>build.gradle </span></figcaption>

  <table><tbody>
      <tr>
        <td class="gutter">
          <pre>1

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21</pre> </td>

        <td class="code">
          <pre>sourceSets {
main {
    manifest.srcFile <span class="comment">'AndroidManifest.xml'</span>
    java.srcDirs = [<span class="comment">'src']</span>
    resources.srcDirs = [<span class="comment">'src']</span>
    aidl.srcDirs = [<span class="comment">'src']</span>
    renderscript.srcDirs = [<span class="comment">'src']</span>
    res.srcDirs = [<span class="comment">'res']</span>
    assets.srcDirs = [<span class="comment">'assets']</span>
}
    
hiapk {
  	manifest.srcFile <span class="comment">'hiapk/AndroidManifest.xml'</span>
}    	
   	playstore {
   		manifest.srcFile <span class="comment">'hiapk/AndroidManifest.xml'</span>
}
   
instrumentTest.setRoot(<span class="comment">'tests')</span>

}</pre> </td> </tr> </tbody></table>

</figure>然后运行<code>gradle clean</code>,<code>gradle build</code>,省下的时间去喝杯咖啡,睡个觉什么的都好。。。 ###外部依赖### android gradle 对于外部jar 包的应用支持maven/ivy 管理的包,也支持指定具体文件,前面已经在上文说过。上面演示的完整 build.gradle gist 里面也有写。你需要加上如下代码即可: <figure class="highlight lang-groovy"><figcaption><span>build.gradle </span></figcaption>

  <table><tbody>
      <tr>
        <td class="gutter">
          <pre>1

2 3</pre> </td>

        <td class="code">
          <pre><span class="title">dependencies</span> {
<span class="title">compile</span> files(<span class="string">'libs/android-support-v4.jar'</span>)

}</pre> </td> </tr> </tbody></table>

</figure>

  <h2 id="menuIndex8">结语</h2>

  <p>至此,对于用android gradle 构建android应用程序,打包android 程序,所需要的所有知识,在以上已经说明,只要你是认真看上面文章的,对于,如何打依赖于android library project 的包,可以看附录提供的那个德国人写的例子,而对于<code>build.gradle</code> 里面的代码你需要把<code>0.2</code>, 改为<code>0.4</code>即可。至于用gradle 运行android test case部分的教程,个人感觉写了也白写(我写过关于andorid 测试相关的文章,也录制过视频,所以有这个感觉。),估计不会有人关注,所以,如果你对用gradle 进行android test的话,可以看附录里面提供的官方gradle手册。</p>

  <h2 id="menuIndex9">扩展阅读</h2>

  <p>对于这部分内容,你读与不读,并不影响你使用gradle 打包android 项目。至于读了的好处就是你能够更好的使用gradle。。</p>

  <ul>
    <li>
      <p>完整的<a href="http://tools.android.com/tech-docs/new-build-system/user-guide">Gradle Plugin User Guide</a> 其中里面有个错误是<code>compile files('libs/android-support-v4.jar')</code> 不是<code>compile file('libs/android-support-v4.jar')</code> 教程是基于android gradle0.3 ,在0.4中只是多了<strong>混淆打包,这块已经在文中补充了。</strong></p>
    </li>

    <li>
      <p>一个德国人写的<a href="https://github.com/Goddchen/Android-Gradle-Examples">Android-Gradle-Examples</a></p>
    </li>

    <li>
      <p><a href="http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html"><code>dependencies{}</code></a> 更多的介绍。</p>
    </li>

    <li>
      <p><strong>debug</strong>, <strong>release</strong>,这两种类型的默认配置如下:</p>

      <table style="border-bottom-color: rgb(136,136,136); border-right-width: 1px; border-top-color: rgb(136,136,136); border-collapse: collapse; border-top-width: 1px; border-bottom-width: 1px; border-right-color: rgb(136,136,136); border-left-color: rgb(136,136,136); border-left-width: 1px" border="1" cellspacing="0" bordercolor="#080808"><tbody>
          <tr>
            <td style="width: 198px; height: 19px">Property name</td>

            <td style="width: 195px; height: 19px">Default values for debug</td>

            <td style="width: 241px; height: 19px">Default values for release / other</td>
          </tr>

          <tr>
            <td style="width: 198px; height: 20px">&#160;<font color="#38761d" face="courier new, monospace"><b>debuggable</b></font></td>

            <td style="width: 195px; height: 20px">true</td>

            <td style="width: 241px; height: 20px">false</td>
          </tr>

          <tr>
            <td style="width: 198px; height: 20px">&#160;<font color="#38761d" face="courier new, monospace"><b>jniDebugBuild</b></font></td>

            <td style="width: 195px; height: 20px">false</td>

            <td style="width: 241px; height: 20px">false</td>
          </tr>

          <tr>
            <td style="width: 198px; height: 19px">&#160;<b><font color="#38761d" face="courier new, monospace">renderscriptDebugBuild</font></b></td>

            <td style="width: 195px; height: 19px">false</td>

            <td style="width: 241px; height: 19px">false</td>
          </tr>

          <tr>
            <td style="width: 198px; height: 20px">&#160;<b><font color="#38761d" face="courier new, monospace">renderscriptOptimLevel</font></b></td>

            <td style="width: 195px; height: 20px">3</td>

            <td style="width: 241px; height: 20px">3</td>
          </tr>

          <tr>
            <td style="width: 198px; height: 20px">&#160;<b><font color="#38761d" face="courier new, monospace">packageNameSuffix</font></b></td>

            <td style="width: 195px; height: 20px">null</td>

            <td style="width: 241px; height: 20px">null</td>
          </tr>

          <tr>
            <td style="width: 198px; height: 20px">&#160;<b><font color="#38761d" face="courier new, monospace">versionNameSuffix</font></b></td>

            <td style="width: 195px; height: 20px">null</td>

            <td style="width: 241px; height: 20px">null</td>
          </tr>

          <tr>
            <td style="width: 198px; height: 20px">&#160;<b><font color="#38761d" face="courier new, monospace">signingConfig</font></b></td>

            <td style="width: 195px; height: 20px">android.signingConfigs.debug</td>

            <td style="width: 241px; height: 20px">null</td>
          </tr>

          <tr>
            <td style="width: 198px; height: 20px">&#160;<b><font color="#38761d" face="courier new, monospace">zipAlign</font></b></td>

            <td style="width: 195px; height: 20px">false</td>

            <td style="width: 241px; height: 20px">true</td>
          </tr>
        </tbody></table>
    </li>
  </ul>

  <ul>
    <li>
      <p><strong>defaultConfig {}</strong> 配置参数列表</p>

      <table style="border-bottom-color: rgb(136,136,136); border-right-width: 1px; border-top-color: rgb(136,136,136); border-collapse: collapse; border-top-width: 1px; border-bottom-width: 1px; border-right-color: rgb(136,136,136); border-left-color: rgb(136,136,136); border-left-width: 1px" border="1" cellspacing="0" bordercolor="#080808"><tbody>
          <tr>
            <td style="width: 208px; height: 19px">Property Name</td>

            <td style="width: 168px; height: 19px">Default value in DSL object</td>

            <td style="width: 251px; height: 19px">Default value</td>
          </tr>

          <tr>
            <td style="width: 208px; height: 20px">&#160;<font color="#38761d" face="courier new, monospace"><b>versionCode</b></font></td>

            <td style="width: 168px; height: 20px">-1</td>

            <td style="width: 251px; height: 20px">value from manifest if present</td>
          </tr>

          <tr>
            <td style="width: 208px; height: 20px">&#160;<font color="#38761d" face="courier new, monospace"><b>versionName</b></font></td>

            <td style="width: 168px; height: 20px">null</td>

            <td style="width: 251px; height: 20px">value from manifest if present</td>
          </tr>

          <tr>
            <td style="width: 208px; height: 20px">&#160;<font color="#38761d" face="courier new, monospace"><b>minSdkVersion</b></font></td>

            <td style="width: 168px; height: 20px">-1</td>

            <td style="width: 251px; height: 20px">value from manifest if present</td>
          </tr>

          <tr>
            <td style="width: 208px; height: 20px">&#160;<font color="#38761d" face="courier new, monospace"><b>targetSdkVersion</b></font></td>

            <td style="width: 168px; height: 20px">-1</td>

            <td style="width: 251px; height: 20px">value from manifest if present</td>
          </tr>

          <tr>
            <td style="width: 208px; height: 20px">&#160;<font color="#38761d" face="courier new, monospace"><b>packageName</b></font></td>

            <td style="width: 168px; height: 20px">null</td>

            <td style="width: 251px; height: 20px">value from manifest if present</td>
          </tr>

          <tr>
            <td style="width: 208px; height: 20px">&#160;<font color="#38761d" face="courier new, monospace"><b>testPackageName</b></font></td>

            <td style="width: 168px; height: 20px">null</td>

            <td style="width: 251px; height: 20px">app package name + “.test”</td>
          </tr>

          <tr>
            <td style="width: 208px; height: 20px">&#160;<font color="#38761d" face="courier new, monospace"><b>testInstrumentationRunner</b></font></td>

            <td style="width: 168px; height: 20px">null</td>

            <td style="width: 251px; height: 20px">android.test.InstrumentationTestRunner</td>
          </tr>

          <tr>
            <td style="width: 208px; height: 19px">&#160;<font color="#38761d" face="courier new, monospace"><b>signingConfig</b></font></td>

            <td style="width: 168px; height: 19px">null</td>

            <td style="width: 251px; height: 19px">null</td>
          </tr>

          <tr>
            <td style="width: 208px; height: 20px">&#160;<font color="#38761d" face="courier new, monospace"><b>runProguard</b></font></td>

            <td style="width: 168px; height: 20px">false</td>

            <td style="width: 251px; height: 20px">false</td>
          </tr>

          <tr>
            <td style="width: 208px; height: 19px">&#160;<font color="#38761d" face="courier new, monospace"><b>proguardFile</b></font></td>

            <td style="width: 168px; height: 19px">&#160; 'proguard-android.txt' or 'proguard-android-optimize.txt'</td>

            <td style="width: 251px; height: 19px">&#160; 'proguard-android.txt' or 'proguard-android-optimize.txt'</td>
          </tr>
        </tbody></table>
    </li>

    <li>
      <p>build 结构目录</p>

<figure class="highlight lang-shell"><figcaption><span>tree </span></figcaption>

      <table><tbody>
          <tr>
            <td class="gutter">
              <pre>1

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90</pre> </td>

            <td class="code">
              <pre>build/

├── apk ├── assets │   ├── debug │   └── <span class="keyword">release</span> ├── classes │   ├── debug │   │   └── com │   │   └── example │   │   └── gradle │   └── <span class="keyword">release</span> │   └── com │   └── example │   └── gradle ├── dependency-cache │   ├── debug │   └── <span class="keyword">release</span> ├── incremental │   ├── aidl │   │   ├── debug │   │   └── <span class="keyword">release</span> │   ├── dex │   │   ├── debug │   │   └── <span class="keyword">release</span> │   ├── mergeAssets │   │   ├── debug │   │   └── <span class="keyword">release</span> │   └── mergeResources │   ├── debug │   └── <span class="keyword">release</span> ├── libs ├── manifests │   ├── debug │   └── <span class="keyword">release</span> ├── res │   ├── <span class="keyword">all</span> │   │   ├── debug │   │   │   ├── drawable-hdpi │   │   │   ├── drawable-mdpi │   │   │   ├── drawable-xhdpi │   │   │   ├── drawable-xxhdpi │   │   │   ├── layout │   │   │   ├── menu │   │   │   ├── values │   │   │   ├── values-sw720dp-land │   │   │   ├── values-v11 │   │   │   └── values-v14 │   │   └── <span class="keyword">release</span> │   │   ├── drawable-hdpi │   │   ├── drawable-mdpi │   │   ├── drawable-xhdpi │   │   ├── drawable-xxhdpi │   │   ├── layout │   │   ├── menu │   │   ├── values │   │   ├── values-sw720dp-land │   │   ├── values-v11 │   │   └── values-v14 │   └── rs │   ├── debug │   └── <span class="keyword">release</span> ├── source │   ├── aidl │   │   ├── debug │   │   └── <span class="keyword">release</span> │   ├── buildConfig │   │   ├── debug │   │   │   └── com │   │   │   └── example │   │   │   └── gradle │   │   └── <span class="keyword">release</span> │   │   └── com │   │   └── example │   │   └── gradle │   ├── r │   │   ├── debug │   │   │   └── com │   │   │   └── example │   │   │   └── gradle │   │   └── <span class="keyword">release</span> │   │   └── com │   │   └── example │   │   └── gradle │   └── rs │   ├── debug │   └── <span class="keyword">release</span> └── symbols ├── debug └── <span class="keyword">release</span> <span class="number">88</span> directories</pre> </td> </tr> </tbody></table>

</figure></li> </ul>

  <h2 id="menuIndex10">最后的吐槽</h2>

  <p>吐槽一下。。。用ant脚本的(也许你没有接触过。。)。在以前你用ant 脚本打包apk的时候需要打包不同包名,你需要用ant 读取<code>AndroidManifest.xml</code> 然后又正则匹配替换里面packagename 参数。。虽然描述得过程很简单,你真去写的时候你就蛋疼了(对于一个ant外行人来说,个人感觉ant的学习曲线太陡峭了,如果是两年前的我,可能还写得出这样的ant脚本(当年费了很大的功夫学习了一个多星期),不过,因为很少用到(后来知道maven了。。果断放弃了ant,为什么不在android使用maven? 因为,android 的maven 插件式非官方的,而且现在看来maven 的xml实在很复杂,看起来就头疼))*</p>
</div>

<p></p>

</div>

<p></p> </div>

展开阅读全文
打赏
1
49 收藏
分享
加载中
虽然说几个月前就在搞这个了,今儿看到还是要说声赞!
2013/10/05 20:49
回复
举报

引用来自“打杂程序猿”的评论

引用来自“Ivan”的评论

引用来自“打杂程序猿”的评论

引用来自“Ivan”的评论

" Product Flavor{} 不只是能改包名那么简单,还能够对编译的源码目录进行切换。

什么意思? 不知道各位有没有用过友盟做用户统计,如果,你用的是分发渠道分析,你需要修改AndroidManifest.xml 添加上 <meta-data android:value="hiapk" android:name="UMENG_CHANNEL"/> 如果,你很多渠道,,然后你就会很痛苦,现在用gradle 就非常舒服,你只需要在android.sourceSets指定我们的渠道名就行,android gradle 插件,会自动打包!!!" 这段内容看不太懂,请问 android.sourceSets 里那个属性可以配置渠道名的

不是配置渠道名。。是直接切换AndroidManifest.xml 文件。。。具体,你看一下我贴的 。。gist link 就知道。。。那里有完整的代码。。

如果不需要切换AndroidManifest.xml 文件,只要像友盟那样更换渠道名称该怎么做呢

.....这个需要动一下脑筋了。
1. 首先你要回groovy,因为gradle 的脚本语言就是groovy。
2. 在获取AndroidManifest.xml,先进行读取,修改,生成,然后返回给打包器打包。

以上两点,说白就是你自己扩展一个gradle 的task。。。。

这两天才刚看 gradle 。以前也没什么用ant ,Maven 这些,现在看起来感觉好吃力
2013/05/24 11:06
回复
举报

引用来自“Ivan”的评论

引用来自“打杂程序猿”的评论

引用来自“Ivan”的评论

" Product Flavor{} 不只是能改包名那么简单,还能够对编译的源码目录进行切换。

什么意思? 不知道各位有没有用过友盟做用户统计,如果,你用的是分发渠道分析,你需要修改AndroidManifest.xml 添加上 <meta-data android:value="hiapk" android:name="UMENG_CHANNEL"/> 如果,你很多渠道,,然后你就会很痛苦,现在用gradle 就非常舒服,你只需要在android.sourceSets指定我们的渠道名就行,android gradle 插件,会自动打包!!!" 这段内容看不太懂,请问 android.sourceSets 里那个属性可以配置渠道名的

不是配置渠道名。。是直接切换AndroidManifest.xml 文件。。。具体,你看一下我贴的 。。gist link 就知道。。。那里有完整的代码。。

如果不需要切换AndroidManifest.xml 文件,只要像友盟那样更换渠道名称该怎么做呢

.....这个需要动一下脑筋了。
1. 首先你要回groovy,因为gradle 的脚本语言就是groovy。
2. 在获取AndroidManifest.xml,先进行读取,修改,生成,然后返回给打包器打包。

以上两点,说白就是你自己扩展一个gradle 的task。。。。
2013/05/23 16:41
回复
举报

引用来自“打杂程序猿”的评论

引用来自“Ivan”的评论

" Product Flavor{} 不只是能改包名那么简单,还能够对编译的源码目录进行切换。

什么意思? 不知道各位有没有用过友盟做用户统计,如果,你用的是分发渠道分析,你需要修改AndroidManifest.xml 添加上 <meta-data android:value="hiapk" android:name="UMENG_CHANNEL"/> 如果,你很多渠道,,然后你就会很痛苦,现在用gradle 就非常舒服,你只需要在android.sourceSets指定我们的渠道名就行,android gradle 插件,会自动打包!!!" 这段内容看不太懂,请问 android.sourceSets 里那个属性可以配置渠道名的

不是配置渠道名。。是直接切换AndroidManifest.xml 文件。。。具体,你看一下我贴的 。。gist link 就知道。。。那里有完整的代码。。

如果不需要切换AndroidManifest.xml 文件,只要像友盟那样更换渠道名称该怎么做呢
2013/05/23 16:33
回复
举报
非常好
2013/05/23 06:04
回复
举报

引用来自“Ivan”的评论

" Product Flavor{} 不只是能改包名那么简单,还能够对编译的源码目录进行切换。

什么意思? 不知道各位有没有用过友盟做用户统计,如果,你用的是分发渠道分析,你需要修改AndroidManifest.xml 添加上 <meta-data android:value="hiapk" android:name="UMENG_CHANNEL"/> 如果,你很多渠道,,然后你就会很痛苦,现在用gradle 就非常舒服,你只需要在android.sourceSets指定我们的渠道名就行,android gradle 插件,会自动打包!!!" 这段内容看不太懂,请问 android.sourceSets 里那个属性可以配置渠道名的

不是配置渠道名。。是直接切换AndroidManifest.xml 文件。。。具体,你看一下我贴的 。。gist link 就知道。。。那里有完整的代码。。
2013/05/21 20:26
回复
举报
" Product Flavor{} 不只是能改包名那么简单,还能够对编译的源码目录进行切换。

什么意思? 不知道各位有没有用过友盟做用户统计,如果,你用的是分发渠道分析,你需要修改AndroidManifest.xml 添加上 <meta-data android:value="hiapk" android:name="UMENG_CHANNEL"/> 如果,你很多渠道,,然后你就会很痛苦,现在用gradle 就非常舒服,你只需要在android.sourceSets指定我们的渠道名就行,android gradle 插件,会自动打包!!!" 这段内容看不太懂,请问 android.sourceSets 里那个属性可以配置渠道名的
2013/05/21 16:51
回复
举报

引用来自“打杂程序猿”的评论

引用来自“云麟”的评论

这个eclipse 下面又没有插件,我google了半天也没找到

你是想语法高亮还是要在eclipse 下运行,如果是高亮的话http://groovy.codehaus.org/Eclipse+Plugin 下载这个。。。groovy

语法高亮 如果还有代码提示就好了,有时候记不住那些关键字
2013/05/21 16:13
回复
举报

引用来自“云麟”的评论

这个eclipse 下面又没有插件,我google了半天也没找到

你是想语法高亮还是要在eclipse 下运行,如果是高亮的话http://groovy.codehaus.org/Eclipse+Plugin 下载这个。。。groovy
2013/05/21 14:53
回复
举报
收藏了
2013/05/20 23:06
回复
举报
更多评论
打赏
13 评论
49 收藏
1
分享
返回顶部
顶部