Studio (IntelliJ) +gradle (1.0+) +jenkins Package & Upload

Source: Internet
Author: User
Tags svn update jcenter

It is now more popular to use Gradle to configure projects, and this article focuses on studio and IntelliJ packaging. In an Android Gradle project, project is similar to Eclipse's workspace, and Moudule is similar to project for Eclipse. Demo SVN location: Http://10.3.254.91/svn/mobile/android/GradleTest Demo Jenkins project name: Android_gradletest Select Gradle PackageThen there will be a Gradle package under Gradle project that contains a wrapper/gradle-wrapper.properties that specifies the Gradle configuration for this project
Distributionbase=gradle_user_home
Distributionpath=wrapper/dists
Zipstorebase=gradle_user_home
Zipstorepath=wrapper/dists
Distributionurl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip This passage specifies the Gradle, and Gradle's position, Gradle _user_home generally point to ${user}/.gradle, we are interested to view the directory yourself, when you change the Gradle version, and studio and IntelliJ do not use local gradle, will automatically download Gradle package to the directory, Sometimes because of the cache cause Gradle package repeatedly download, then recommended to use the local gradle (in the domestic FQ download speed not to force, everyone to work abroad) project Gradle configuration file
  • The
  • build.gradle   primary gradle configuration file, which specifies the warehouse and dependencies of the Buildscript (this dependency does not refer to the application jar living other engineering dependencies, but rather relies on the dependency of the compiler Gradle plugin, such as dependency Android-gradle plug-in)
    dependencies {classpath  ' com.android.tools.build:gradle:1.1.1 '}  This is the introduction of the Android Gradle plugin, This plugin is Android official specifically for the configuration of Android-written plug-ins, inherited Java plug-ins, so the introduction of apply plugin:  ' Com.android.application '   or apply plugin:  ' com.android.library ' can no longer introduce Java plugin. The later version number 1.1.1 is not referring to the Gradle version, but refers to the version of this plug-in, the plug-in version and the studio version number is consistent, where different studio to the minimum gradle requirements, specifically see  http:// Tools.android.com/tech-docs/new-build-system. In the Gradle file for convenience can also be specified allprojects or subprojects closure (that is, add a curly brace "{}"), the closure of the general moudule or all Moudule common code is written here, the most common is to define the warehouse (that is, jar, Where AAR should be from).

     
  • Gradle.properties Project's Gradle property file, Gradle reads the file when it is loaded, The file can be customized to read the attributes in. Gradle, and you can also specify some properties of the gradle, such as Configureondemand, JVM parameters, open daemon process, parallel run, However, the test found that the JVM parameters and the daemon process will cause compilation failure, so only open multi-threaded operation, the actual test of multi-threaded operation does not bring much performance changes, and this property in the Gradle syntax is marked as incubating, is expressed as informal, The future is likely to change, add not to see a person likes it, plus the syntax is org.gradle.parallel=true (if it is a multi-module upload package, because the POM conflict error, it is normally recommended not to use). If this is a native test, the Daemon property can still be used without adding, because studio has been turned on by default, this daemon thread once opened, will last 3 hours, if you do not want to open, you can add Org.gradle.daemon=false But it is recommended to modify the JVM parameters, the default generated properties file will have a line comment, remove the line comment:
    #org. Gradle.jvmargs=-xmx2048m-xx:maxpermsize=512m-xx:+heapdumponoutofmemoryerror-dfile.encoding=utf-8
  • Settings.gradle This file specifies how many moudule are under project, and if Moudule is not included here as being hidden from the project, the simplest way to define it is as follows:
          Include ': App ', ':D ependlib '
    • Local.properties the path used to specify the SDK at the time of this file can be set to Sdk.dir or Android_home, if you do not specify Jenkins will search the default SDK for the machine, which is the SDK developed in the environment variables
    • Other *.gradle files or *.properties,gradle allow users to customize Gradle script text, such as extracting public modules, which need to be loaded via the Apply from: ' A.gradle ' to be introduced, Properties files are generally used to define key-value attributes, which can be loaded in Gradle by the following syntax:
Properties ()
Properties.load (project. Rootproject. File (' common.properties '). Newdatainputstream ())

ext {
Repositoryurl = Properties.getproperty ("Repositoryurl")}
Module's gradle configuration file a new module by default there is only one build.gradle file, the Gradle file contains some basic information about the module, such as belong to the application or library, the specified Android basic editing information, Configuration build information, JDK variant version, signature information, channel pack, etc., briefly described as follows: compilesdkversion (int), compiled using the Android SDK version, corresponding to the usual we know the API version. Buildtoolsversion (String), edit the specific version code number, you can go to the SDK Manager to find the downloaded versions defaultconfig (closure), the default compilation properties, including:
    • ApplicationID (string) app ID, also the package name path
    • minsdkversion (int) supports the Minimum SDK version
    • targetsdkversion (int) Target compilation SDK version, this property will affect the Android part of the show, such as Targetsdkversion under 10, Android bottom Virtual nav bar on the right side of a small menu icon
    • Versioncode (int) version of this module code
    • Versionname (String) version of this module name
Compileoptions (closure) is used to specify the JDK compilation version signingconfigs (closure) to define a signature file Buildtypes (closure) Build instance, by default there are release and build two kinds, and cannot be modified; The build instance contains the following useful parameters (you can also modify the ApplicationID suffix, and so on):
    • Minifyenabled (Boolean) is confusing
    • Proguardfiles (file[]) confusing files
    • Signingconfig (ref) using signature files
    • Zipalignenabled (Boolean) is optimized for APK package
Sourcesets.main (Closure) specifies or redirects the Android resource folder, is not recommended, it is recommended to use the Gradle default directory, which is Jni,jnilibs,aidl,java,rs, The assets folder and the manifest file are placed under the Gradle engineering default directory specified by Studio, which is under Src/main. Where JNI and jnilibs are different folders, JNI is used to specify the resources that need to be compiled by the NDK, i.e. C + + source files and Manifest;jnilibs are compiled so package files that can be directly used by lintoptions (closure). Specifies some properties of the lint task, typically specifying abortonerror false, Ignorewarnings trueproductflavors (closure), for setting up multiple channel packages, Its basic parameters and BuildType similar to applicationvariants application plug-in parameters, specific reference http://tools.android.com/tech-docs/new-build-system/ User-guidelibraryvariants Library plug-in parameters, specific reference http://tools.android.com/tech-docs/new-build-system/ User-guidetestvariants test Plug-in parameters, specific reference http://tools.android.com/tech-docs/new-build-system/user-guide in addition to the build file , you can also create a new gradle.properties file that will load the file by default while the grade is running, and we can throw some common properties to the file. Best Practices: When calling uploadarchives when packaging, you need to specify the group,artifact_id,version,packaging of POM, etc. We can write these attributes in the grade.properties of the respective module, with the same key values, for example:
Pom_name=dependpom
Pom_description=this is just test,do don't pay more attention to if
Pom_group=cn.myapplication
Pom_artifact_id=depend
Pom_packaging=aar
Pom_version=1.0 then writes the Uploadarchives method to a Common.gradle, as follows:
uploadarchives {
repositories {
Mavendeployer {

Repository (Url:rurl) {
Authentication (Username:ruser, Password:rpass)
}

Pom.project {
Name Pom_name
GroupId Pom_group
Artifactid pom_artifact_id
Description Pom_description
Version Pom_version
Packaging pom_packaging
}
}
}
}
Finally, which module needs to be uploaded into the Gradle file, that is, the call to apply from: ' Common.gradle ' configuration warehouse warehouse definition is generally only in project Gradle file Buildscript and all Projects module in the definition of one can, not recommended in the module also repeated definitions, we generally only use the Maven warehouse, the definition format is as follows repositories {mavenlocal () Maven {
url "http://nexus.laohu.com:8081/nexus/content/groups/android_public/"} maven {
URL ' http://repository.sonatype.org/content/groups/public/'} maven {
URL ' http://repository.jboss.com/maven2/'} maven {
The URL ' http://maven.oschina.net/content/groups/public/'} jcenter ()} gradle file will be searched according to the defined warehouse, and in one warehouse it can not find the next, where Mavenlocal () is a local maven repository, Jcenter is the official warehouse of Binatry. Generally recommended, the connection speed of the warehouse, the comparison of the entire front, you can reduce network connection time.     For most of the warehouses are established abroad, the speed is slow, this example gives three agent warehouse, the speed is barely possible, but the speed is still not objective. So I used our own to build our own Android warehouse with the address"Http://nexus.laohu.com:8081/nexus/content/groups/android_public/", when we request a resource, it is requested from this agent repository, if the resource exists, it is downloaded directly, if it does not exist, Then the agent warehouse will request the source address of its agent, download the existing Agent repository and transfer it to us. Using a project repository requires the use of host,If anyone is interested in managing a warehouse, we can access it via the following address and user password.Access Address: http://nexus.laohu.com:8081/nexus/ User name password: *******/****** Theoretically the more warehouses the better , but in one case the exception is that the required resources do not exist in all warehouses, so it takes a lot of time to find the indexes of all the warehouses, causing the compilation to be too slow. For example, Android support repositories, when it is necessary to use a V4 or V7 resource Bundle (AAR), if integrated in studio or IntelliJ, our plugin will take precedence from the locally installed support repository and will not be time consuming. But when integrated with gradle packaging on Jenkins, Gradle will search for the local support warehouse in the order of the warehouse sequence, which will lead to a lot of time loss, especially when our intranet links Jcenter or mavencenter, the efficiency wants to be low. At this point there are two solutions:
    1. Add a local maven repository and place it in mavenlocal (), maven{url "e:\\android-sdk_r21-windows\\android-sdk-windows-new\\android-sdk-windows\\extras\\ Android\\m2repository "}, but such words need to be in different machine adaptation address, need to constantly change the address, of course, the first half of the URL can be changed to $android_home to do the compatibility, but it seems that I am adapting to the Mac, Windows and Linux do not always guarantee success, if who did succeed can tell me direct editing to give a more satisfactory answer
    2. Reduce the number of warehouses, only maintain a good connection mavenlocal and our private repository, so that the query index is also the second level, why do you do this? Because the configuration is a group warehouse (that is, a collection of warehouses), it contains the Jcenter and Mavencenter Agent warehouse, there is no need to develop jcenter (), Mavencenter () or other warehouses, From the repository we will be able to get to the back of the warehouse content, the disadvantage is that it can only be used in the intranet. If it is used inside the company, it is recommended to configure the warehouse as follows
Repositories { mavenlocal () maven { url "http://nexus.laohu.com:8081/nexus/content/groups/android_public/"              }          }   Best Practice: After a successful configuration, the download dependency is fairly fast, in order to avoid time consuming in Libs in SVN, it is not recommended to put the jar package in Libs and then specify the reference, because Libs must follow SVN to transmit simultaneously. And in 114 Jenkins because of the SVN version problem (followed by Git), each time a new copy must be obtained, which is time-consuming. The referenced jar package cannot be in AAR format and is not compatible. The configuration dependencies are as follows: compile ' com.squareup.okhttp:okhttp:2.0.0 '  Uploading items to a database its basic setup in the module's properties best practices mentioned here give some specific explanations, in uploadarchives, we took the following fields: Repository (url:rurl) { Authentication (Username:ruser, Password:rpass)} Here repository represents the remote warehouse, Rurl is the remote warehouse address, our third-party address is "http://nexus.laohu.com:8081/nexus/content/groups/android_3rd/" ( not the warehouse above, NOTE!!!) ), Ruser is the authentication user name, Rname is the password. Define the POM as follows Pom.project {name Pom_name
GroupId Pom_group
Artifactid pom_artifact_id
Description Pom_description
Version Pom_version
Packaging pom_packaging}name is the name of the POM, GroupID can be considered to be the package name of the file, Artifactid can be considered as the specific name of the file, description is described, version is the vers of the ID Ion,packaging is an extension if it is not specified generally for the Jar,application project for the Apk,library project for the war. Generally a POM has only groupid,artifactid and version unique definitions, and these three fields are essential. When the above definition is done and the Gradle uploadarchives is executed at the terminal, we can publish our project to the client, then the Gradle reference to the published document is defined as compile ' groupId:artifactId:version (@ packaing) '. Published to the Jcenter official website need to apply for the user name and password, but also in the Gradle file to add the following words, indicating that you want to publish their own source code and Javadoc:ask Androidjavadoc (Type:javadoc) {
Source = Android.sourceSets.main.java.srcDirs
Exclude ' **/pom.xml '
Exclude ' **/proguard_annotations.pro '
Classpath + = files (android.bootclasspath)
}

Task Androidjavadocjar (Type:jar, Dependson:androidjavadoc) {
classifier = ' Javadoc '
From Androidjavadoc.destinationdir
}

Task Androidsourcesjar (Type:jar) {
classifier = ' sources '
From Android.sourceSets.main.java.srcDirs
}

Artifacts.add (' Archives ', Androidjavadocjar) artifacts.add (' Archives ', Androidsourcesjar) after the successful release, the final need to wait for the Jcenter official website Audit, Reviewed our project can exist in the Jcenter, the outside can also be referenced by Gradle way, I have not tried, t_t, and other people to show off the replacement channel package variables in the channel package we will often need to replace some variables in the manifest file, The most common is to replace the Umeng_value, in the past our code is in the applicationvariants itself read manifest, and then change the manifest in the variable copied to the new folder, for the application to re-develop the manifest file, but this is not necessary , because this is equivalent to reading two times manifest, again is the plugin comes with the task, again is we give the task, and when the need to replace more than one string, will write a lot more code. From Gradle 0.5 or 0. Several versions of the plugin have given a simple solution, which can be used to replace the value of manifest in our settings when reading. The specific wording is as follows:
<meta-data android:name= "channel" Android:value= "${umeng_channel}"/>
<meta-data android:name= "TEST" android:value= "${test}"/>manifest file will need to replace the variable with the dollar sign "$" to enclose the parentheses, Then write in the Android closure in the Gradle file: productflavors {wandoujia {versionname ' alpha '} MC {manifestplaceholders = [umeng_channel:name, test: ' TT ']}}
Productflavors.all {Flavor
Flavor.manifestplaceholders = [Umeng_channel:name, Test:name]} is a code that adds manifestplaceholders=[], in which you want to replace a key-value pair, Where the key corresponds to manifest in ${} inside the east, in the channel package using name, this name is the name of the channel package, which is defined in ProductflavorsWandoujia {versionname ' alpha '} in the Wandoujia, the channel package name is a final constant, can not be changed, and now after this, it should be the previous code is much simpler Replace the APK name in packaging, in order to make it easier to distinguish between the different channel packages and component numbers to form our own rules of the APK name, now you need to implement the replacement package name in the code. The default package name generated by the plug-in is as follows: module name (name of the include in the Settings.gradle file)-flavors-buildtype.apk. We generally need to add versionname and SVN versions. First get the SVN version is obtained by the following code, first through the Gradle to execute the SVN info command to get the string, and then through the regular expression to match the version number assigned to Svnbuildnum, I am not very clear: task Svninfo () {
New Bytearrayoutputstream (). withstream {os-
def result = Exec {
executable = ' SVN '
args = [' info ']
StandardOutput = OS
}
def outputasstring = os.tostring ()
def matchlastchangedrev = outputasstring =~/last Changed Rev: (\d+)/
Svnbuildnum = "${matchlastchangedrev[0][1]}"
}} Then rename the output file name in Applicationvariants as follows: Applicationvariants.all {variant-
Variant.outputs.each {output-
if (HASSVN) {
Output.outputfile = new File (
Output.outputFile.parent,
Output.outputFile.name.replace (". apk", "-" + Defaultconfig.versionname + "-r" + Svnbuildnum + ". apk"))
} else {
Output.outputfile = new File (
Output.outputFile.parent,
Output.outputFile.name.replace (". apk", "-" + Defaultconfig.versionname + ". apk"))
}
}} Improve packaging efficiency any behavior in Gradle is divided into a task, which is then further divided into the action in the task. Plug-ins have a lot of tasks built by default, and we just need to call them. For example, when we run in studio, we rely on the Android build task, which completes the package apk and some check. But relying entirely on the default configuration creates some additional overhead. For example, the build task relies on assemble and check two tasks, the previous task is to package, the following tasks are mainly to complete some inspection and testing, in our actual situation does not need to use check. Assemble task will be divided into Assemeblerelease and assemblebuild two tasks, respectively, marked realease and build when the packaging situation. So most of us can only call assemblerelease, so we can omit the assemebledebug and check two tasks. Best Practice: Task copyapk (type:copy) {
From ' build/outputs/apk '
Into ' APKs '
Exclude ' **/*-unaligned.apk '
}

Task Buildrelease (dependsOn: [Clean, assemblerelease, copyapk, Svninfo]) {
Assemblerelease.mustrunafter Svninfo
Copyapk.mustrunafter Assemblerelease
Clean.mustrunafter copyapk
}
Task Builddebug (dependsOn: [Clean, Assembledebug, copyapk]) {
Copyapk.mustrunafter Assembledebug
    Clean.mustrunafter copyapk}  There are three main tasks defined here, Buildrelease and Builddebug are the main two package build jobs we recommend, The corresponding is release and build. Where the Buildrelease task relies on clean (cleanup output control, the default cleanup build middle file, which will contain the output file and intermediate temporary files), Assemblerelease (package), copyapk (output files to the new folder, To prevent the clean cleanup, which does not contain unaligned.apk), Svninfo (get svn information), that is, the Buildrelease task must be run after these four tasks, and then buildrelease to specify the order in which some tasks are run. So the local build configuration is basically complete, the last part is our own server Jenkins configuration  jenkins configuration Our Jenkins is divided into 34 and 114 jenkins,34jenkins executed on 207 of the server, 114jenkins execution on 13, that is, you need to specify &NBSP;PS here: no matter which Jenkins Gradle and Android SDK are read in the server environment variables first create a new job on Jenkins, then configure source control, The Android side is still using SVN, here is a check-out style,34 for some reason (said below) must choose always check out as a fresh copy, so every time from SVN read, less efficient 114 You can choose the build task under use ' SVN Update ' as much as possible : at build time, 34 must first add an execute shell,command to fill out the SVN upgrade. This is the same reason as the above choice check-out style reason, because Jenkins's SVN plugin only supports to 1.7, while 207 uses the SVN version is 1.8, this will cause the SVN format inconsistent, so before the build must call SVN Upgrade the format to the same version of SVN and upgrades it on the lower versions of the SVN library. 114 You do not need to select this step.   Next Add Build task Mobile App build, under normal packaging choose android, build parameter Select Buildrelease-s instead of the BU that everyone usesild-s; The output path is APP/APKS to the output path specified in copyapk, as shown in:   However, the Gradle version used on the 114 build is 1.10, does not require at least 2.1 for the new version, 34 uses the Gradle version is the latest 2.4, do not worry, to specify the local other Gradle version build, then when the package is not selected Android, but directly select the command Line, enter the local gradle execute the file path and parameters, as shown in the last save, you can be related to packaging.   Theoretically, in this way packaging speed can be increased 1 time times, the actual test, the original method in the local packaging speed around 70-80s, using this method packaging speed around 35-45s, and recommended to use 34jenkins greater than 114jenkins, 114jenkins plug-in version older, the speed has a big discount of about 90s, and 34jenkins on the SVN sync about 8s (recommended to let Tianxin 207 server on the SVN version downgrade, free of our svn on the additional consumption), packaging speed between 30-50s. If you use the new version of the Gradle packaging, you can directly copy my demo code in the past a little configuration can be used, there are questions can be discussed with me at any time, and because of my own level of limitations, may be some of the views are not correct, but also hope that you rectify.   

Studio (IntelliJ) +gradle (1.0+) +jenkins packaged & uploaded by

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.