Upgrade to Pro — share decks privately, control downloads, hide ads and more …

In gradle we trust

Avatar for Iñaki Villar Iñaki Villar
November 25, 2014

In gradle we trust

Avatar for Iñaki Villar

Iñaki Villar

November 25, 2014
Tweet

More Decks by Iñaki Villar

Other Decks in Technology

Transcript

  1. CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
 # Determine the Java command to use to

    start the JVM.
 if [ -n "$JAVA_HOME" ] ; then
 if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
 # IBM's JDK on AIX uses strange locations for the executables
 JAVACMD="$JAVA_HOME/jre/sh/java"
 else
 JAVACMD="$JAVA_HOME/bin/java"
 fi
 if [ ! -x "$JAVACMD" ] ; then
 die "ERROR: JAVA_HOME is set to an invalid directory: 
 Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
 fi
 else
 JAVACMD="java"
 which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not
 Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
 fi
 exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath “$CLASSPATH" GradleWrapperMain "$@"

  2. CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
 # Determine the Java command to use to

    start the JVM.
 if [ -n "$JAVA_HOME" ] ; then
 if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
 # IBM's JDK on AIX uses strange locations for the executables
 JAVACMD="$JAVA_HOME/jre/sh/java"
 else
 JAVACMD="$JAVA_HOME/bin/java"
 fi
 if [ ! -x "$JAVACMD" ] ; then
 die "ERROR: JAVA_HOME is set to an invalid directory: 
 Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
 fi
 else
 JAVACMD="java"
 which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not
 Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
 fi
 exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath “$CLASSPATH" GradleWrapperMain "$@"
 gradlew
  3. include ':app' include ':app', ':core' 
 buildscript {
 repositories {


    jcenter()
 }
 dependencies {
 classpath 'com.android.tools.build:gradle:0.14'
 
 }
 }
 
 allprojects {
 repositories {
 jcenter()
 }
 }

  4. 
 buildscript {
 repositories {
 jcenter()
 }
 dependencies {
 classpath

    'com.android.tools.build:gradle:0.14'
 
 }
 }
 
 allprojects {
 repositories {
 jcenter()
 }
 }
 include ':app' include ':app', ':core'
  5. include ':app' include ':app', ':core' 
 buildscript {
 repositories {


    jcenter()
 }
 dependencies {
 classpath 'com.android.tools.build:gradle:0.14'
 
 }
 }
 
 allprojects {
 repositories {
 jcenter()
 }
 }

  6. apply plugin: 'com.android.application'
 
 android {
 compileSdkVersion 21
 buildToolsVersion "21.0.2"


    
 defaultConfig {
 applicationId "gdg.gdgdublin"
 minSdkVersion 15
 targetSdkVersion 21
 versionCode 1
 versionName "1.0"
 }
 buildTypes {
 release { minifyEnabled true shrinkResources true }
 }
 }
 
 dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 }

  7. apply plugin: 'com.android.application'
 
 android {
 compileSdkVersion 21
 buildToolsVersion "21.0.2"


    
 defaultConfig {
 applicationId "gdg.gdgdublin"
 minSdkVersion 15
 targetSdkVersion 21
 versionCode 1
 versionName "1.0"
 }
 buildTypes {
 release { minifyEnabled true shrinkResources true }
 }
 }
 
 dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 }

  8. apply plugin: 'com.android.application'
 
 android {
 compileSdkVersion 21
 buildToolsVersion "21.0.2"


    
 defaultConfig {
 applicationId "gdg.gdgdublin"
 minSdkVersion 15
 targetSdkVersion 21
 versionCode 1
 versionName "1.0"
 }
 buildTypes {
 release { minifyEnabled true shrinkResources true }
 }
 }
 
 dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 }

  9. apply plugin: 'com.android.application'
 
 android {
 compileSdkVersion 21
 buildToolsVersion "21.0.2"


    
 defaultConfig {
 applicationId "gdg.gdgdublin"
 minSdkVersion 15
 targetSdkVersion 21
 versionCode 1
 versionName "1.0"
 }
 buildTypes {
 release { minifyEnabled true shrinkResources true }
 }
 }
 
 dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 }

  10. ! debuggable 
 renderscriptOptimLevel 
 applicationIdSuffix 
 versionNameSuffix 
 signingConfig

    ! zipAlignEnabled 
 minifyEnabled debug {
 debuggable true
 renderscriptOptimLevel 3
 applicationIdSuffix ".debug"
 versionNameSuffix "debug"
 zipAlignEnabled false
 minifyEnabled false
 } ! 
 build types
  11. ! debuggable 
 renderscriptOptimLevel 
 applicationIdSuffix 
 versionNameSuffix 
 signingConfig

    ! zipAlignEnabled 
 minifyEnabled debug {
 debuggable true
 renderscriptOptimLevel 3
 applicationIdSuffix ".debug"
 versionNameSuffix "debug"
 zipAlignEnabled false
 minifyEnabled false
 } ! 
 release {
 debuggable false
 renderscriptOptimLevel 3
 signingConfig android.signingConfigs.release
 zipAlignEnabled true
 minifyEnabled true
 proguardFiles getDefaultProguardFile(‘proguard-android.txt') } build types
  12. ! debuggable 
 renderscriptOptimLevel 
 applicationIdSuffix 
 versionNameSuffix 
 signingConfig

    ! zipAlignEnabled 
 minifyEnabled debug {
 debuggable true
 renderscriptOptimLevel 3
 applicationIdSuffix ".debug"
 versionNameSuffix "debug"
 zipAlignEnabled false
 minifyEnabled false
 } ! 
 release {
 debuggable false
 renderscriptOptimLevel 3
 signingConfig android.signingConfigs.release
 zipAlignEnabled true
 minifyEnabled true
 proguardFiles getDefaultProguardFile(‘proguard-android.txt') } hockey {
 debuggable false
 renderscriptOptimLevel 3
 applicationIdSuffix ".hockey"
 versionNameSuffix "hockey"
 } ! build types
  13. apply plugin: 'com.android.application'
 
 android {
 compileSdkVersion 21
 buildToolsVersion "21.0.2"


    
 defaultConfig {
 applicationId "gdg.gdgdublin"
 minSdkVersion 15
 targetSdkVersion 21
 versionCode 1
 versionName "1.0"
 }
 buildTypes {
 release { minifyEnabled true shrinkResources true }
 }
 }
 
 dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 }

  14. repositories {
 jcenter()
 maven { url 'http://download.crashlytics.com/maven' }
 } dependencies

    {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 compile 'com.android.support:recyclerview-v7:21.0.0'
 compile 'com.android.support:support-annotations:21.0.0'
 compile 'javax.inject:javax.inject:1@jar'
 compile 'com.squareup.picasso:picasso:2.4.0'
 compile 'com.squareup.dagger:dagger:1.2.2'
 } dependencies
  15. repositories {
 jcenter()
 maven { url 'http://download.crashlytics.com/maven' }
 } dependencies

    {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 compile 'com.android.support:recyclerview-v7:21.0.0'
 compile 'com.android.support:support-annotations:21.0.0'
 compile 'javax.inject:javax.inject:1@jar'
 compile 'com.squareup.picasso:picasso:2.4.0'
 compile 'com.squareup.dagger:dagger:1.2.2'
 } dependencies {
 compile ':lib'
 }
 dependencies
  16. dependencies {
 androidTestCompile "com.google.android:android-espresso-bundled:1.1.0"
 androidTestCompile "com.squareup.spoon:spoon-client:1.1.0" }
 dependencies {
 amazonCompile

    "com.amazon.xxx"
 googleCompile “com.google.xxx" } 
 dependencies {
 compile project(':lib')
 compile('com.google.api-client:google-api-client:1.+') {
 exclude group: 'xpp3', module: 'shared'
 exclude group: 'org.apache.httpcomponents', module: 'httpclient'
 exclude group: 'junit', module: 'junit'
 exclude group: 'com.google.android', module: 'android'
 }
 } dependencies
  17. assemble check build clean ./gradlew tasks ------------------------------------------------------------ All tasks runnable

    from root project ------------------------------------------------------------ Android tasks ------------- androidDependencies - Displays the Android dependencies of the project signingReport - Displays the signing info for each variant Build tasks ----------- assemble - Assembles all variants of all applications and secondary packages. assembleDebug - Assembles all Debug builds assembleDebugTest - Assembles the Test build for the Debug build assembleRelease - Assembles all Release builds build - Assembles and tests this project. buildDependents - Assembles and tests this project and all projects that depend on it. buildNeeded - Assembles and tests this project and all projects it depends on. clean - Deletes the build directory. tasks
  18. ./gradlew assembleDebug ! :app:preBuild :app:compileDebugNdk UP-TO-DATE :app:preDebugBuild :app:checkDebugManifest :app:prepareDebugDependencies :app:compileDebugAidl

    UP-TO-DATE :app:compileDebugRenderscript UP-TO-DATE :app:generateDebugBuildConfig UP-TO-DATE :app:generateDebugAssets UP-TO-DATE :app:mergeDebugAssets UP-TO-DATE :app:generateDebugResValues UP-TO-DATE :app:generateDebugResources UP-TO-DATE :app:mergeDebugResources UP-TO-DATE :app:processDebugManifest UP-TO-DATE :app:processDebugResources UP-TO-DATE :app:generateDebugSources UP-TO-DATE :app:compileDebugJava UP-TO-DATE :app:preDexDebug UP-TO-DATE :app:dexDebug UP-TO-DATE :app:processDebugJavaRes UP-TO-DATE :app:validateDebugSigning :app:packageDebug UP-TO-DATE :app:zipalignDebug UP-TO-DATE :app:assembleDebug UP-TO-DATE BUILD SUCCESSFUL
  19. ./gradlew projects Root project 'GDGDublin' \--- Project ':app' ./gradlew dependencies

    _debugApk - ## Internal use, do not manually configure ## \--- project :core \--- com.google.code.gson:gson:2.2.4 _debugCompile - ## Internal use, do not manually configure ## \--- project :core \--- com.google.code.gson:gson:2.2.4 _debugTestApk - ## Internal use, do not manually configure ## +--- com.google.android:android-espresso-bundled:1.1.0-SNAPSHOT \--- com.squareup.spoon:spoon-client:1.1.0 _debugTestCompile - ## Internal use, do not manually configure ## +--- com.google.android:android-espresso-bundled:1.1.0-SNAPSHOT \--- com.squareup.spoon:spoon-client:1.1.0 _releaseApk - ## Internal use, do not manually configure ## \--- project :core \--- com.google.code.gson:gson:2.2.4 _releaseCompile - ## Internal use, do not manually configure ## \--- project :core \--- com.google.code.gson:gson:2.2.4
  20. task foo << {
 println "First task"
 } task second(dependsOn:

    foo) << {
 println "Second task"
 } tasks.whenTaskAdded { task ->
 if (task.name == 'preDebugBuild') {
 task.dependsOn second
 }
 }
  21. task foo << {
 println "First task"
 } task second(dependsOn:

    foo) << {
 println "Second task"
 } tasks.whenTaskAdded { task ->
 if (task.name == 'preDebugBuild') {
 task.dependsOn second
 }
 } :app:preBuild :app:compileDebugNdk UP-TO-DATE :app:foo First task :app:second Second task :app:preDebugBuild :app:checkDebugManifest :app:prepareDebugDependencies :app:compileDebugAidl UP-TO-DATE :app:compileDebugRenderscript UP-TO-DATE :app:generateDebugBuildConfig UP-TO-DATE :app:generateDebugAssets UP-TO-DATE :app:mergeDebugAssets UP-TO-DATE :app:generateDebugResValues UP-TO-DATE :app:generateDebugResources UP-TO-DATE :app:mergeDebugResources UP-TO-DATE :app:processDebugManifest UP-TO-DATE :app:processDebugResources UP-TO-DATE :app:generateDebugSources UP-TO-DATE :app:compileDebugJava UP-TO-DATE :app:preDexDebug UP-TO-DATE :app:dexDebug UP-TO-DATE :app:processDebugJavaRes UP-TO-DATE :app:validateDebugSigning :app:packageDebug UP-TO-DATE :app:zipalignDebug UP-TO-DATE :app:assembleDebug UP-TO-DATE BUILD SUCCESSFUL
  22. task foo << {
 println "First task"
 } task second(dependsOn:

    foo) << {
 println "Second task"
 } tasks.whenTaskAdded { task ->
 if (task.name == 'preDebugBuild') {
 task.dependsOn second
 }
 } :app:preBuild :app:compileDebugNdk UP-TO-DATE :app:foo First task :app:second Second task :app:preDebugBuild :app:checkDebugManifest :app:prepareDebugDependencies :app:compileDebugAidl UP-TO-DATE :app:compileDebugRenderscript UP-TO-DATE :app:generateDebugBuildConfig UP-TO-DATE :app:generateDebugAssets UP-TO-DATE :app:mergeDebugAssets UP-TO-DATE :app:generateDebugResValues UP-TO-DATE :app:generateDebugResources UP-TO-DATE :app:mergeDebugResources UP-TO-DATE :app:processDebugManifest UP-TO-DATE :app:processDebugResources UP-TO-DATE :app:generateDebugSources UP-TO-DATE :app:compileDebugJava UP-TO-DATE :app:preDexDebug UP-TO-DATE :app:dexDebug UP-TO-DATE :app:processDebugJavaRes UP-TO-DATE :app:validateDebugSigning :app:packageDebug UP-TO-DATE :app:zipalignDebug UP-TO-DATE :app:assembleDebug UP-TO-DATE BUILD SUCCESSFUL
  23. task copyFiles(type: Copy)
 
 copyFiles {
 description = 'Copies html5

    files'
 from '../../www'
 into 'assets/www'
 include('**/*')
 }
  24. task copyFiles(type: Copy)
 
 copyFiles {
 description = 'Copies html5

    files'
 from '../../www'
 into 'assets/www'
 include('**/*')
 } tasks.whenTaskAdded { task ->
 if (task.name == 'assemble') {
 task.dependsOn copyFiles
 }
 }
  25. Verification tasks ------------------ check - Runs all checks. connectedAndroidTest -

    Installs and runs the tests for Build 'debug' on connectedCheck - Runs all device checks on currently connected devices. deviceCheck - Runs all device checks using Device Providers and Test Servers. lint - Runs lint on all variants. lintDebug - Runs lint on the Debug build lintRelease - Runs lint on the Release build plugins apply plugin: ‘com.android.library’ apply plugin: ‘com.android.application’
  26. apply plugin: ‘maven’ uploadArchives {
 repositories {
 mavenDeployer {
 repository(url:

    "http://nexus") {
 authentication(userName: "xxx", password: "xxx")
 }
 pom.version = "x"
 pom.artifactId = "x"
 pom.groupId = "com.x"
 pom.packaging = "aar"
 
 }
 }
 } plugins
  27. apply plugin: ‘checkstyle’
 apply plugin: ‘findbugs’
 apply plugin: ‘pmd’ check.dependsOn

    ‘checkstyle’, ‘findbugs’, ‘pmd’
 
 task checkstyle(type: Checkstyle) {
 classpath = files()
 }
 
 task findbugs(type: FindBugs) {
 classpath = files()
 }
 
 task pmd(type: Pmd) {
 ignoreFailures = true
 } plugins
  28. 
 class FooTask extends DefaultTask {
 String greeting = 'hello

    from GreetingTask'
 
 @TaskAction
 def foo() {
 println greeting
 }
 }
  29. 
 class FooTask extends DefaultTask {
 String greeting = 'hello

    from GreetingTask'
 
 @TaskAction
 def foo() {
 println greeting
 }
 } class FooPlugin implements Plugin<Project> {
 void apply(Project target) {
 target.task('foo', type: FooTask)
 }
 }

  30. 
 class FooTask extends DefaultTask {
 String greeting = 'hello

    from GreetingTask'
 
 @TaskAction
 def foo() {
 println greeting
 }
 } class FooPlugin implements Plugin<Project> {
 void apply(Project target) {
 target.task('foo', type: FooTask)
 }
 }
 apply plugin: 'org.samples.foo'
  31. apply plugin: 'com.android.application'
 
 android {
 compileSdkVersion 21
 buildToolsVersion "21.0.2"


    
 defaultConfig {
 applicationId "com.gdg"
 minSdkVersion 15
 targetSdkVersion 21
 versionCode 1
 versionName "1.0"
 }
 buildTypes {
 release {
 }
 }
 
 productFlavors {
 dublin {
 applicationId "com.gdg.dublin"
 }
 
 cork {
 applicationId "com.gdg.cork"
 }
 
 }
 } Flavors
  32. apply plugin: 'com.android.application'
 
 android {
 compileSdkVersion 21
 buildToolsVersion "21.0.2"


    
 defaultConfig {
 applicationId "com.gdg"
 minSdkVersion 15
 targetSdkVersion 21
 versionCode 1
 versionName "1.0"
 }
 buildTypes {
 release {
 }
 }
 
 productFlavors {
 dublin {
 applicationId "com.gdg.dublin"
 }
 
 cork {
 applicationId "com.gdg.cork"
 }
 
 }
 } Flavors
  33. ! minSdkVersion targetSdkVersion versionCode versionName applicationId release signing info BuildConfig

    test app/ |--libs/ |--src/ |--cork/ | |--res/ | |--drawable/ | | |--ic_launcher.png |--dublin/ | |--res/ | |--drawable/ | | |--ic_launcher.png |--main/ |--java/ | |--... |--res/ | |--layout/ | | |--activity_main.xml | |--... |--AndroidManifest.xml Flavors
  34. import android.app.Activity;
 import gdgdublin.com.myapplication.Locations;
 import android.os.Bundle;
 
 
 public class

    MyActivity extends Activity {
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 Locations locations = new Locations();
 setContentView(R.layout.activity_my);
 }
 } }
 Flavors
  35. import android.app.Activity;
 import gdgdublin.com.myapplication.Locations;
 import android.os.Bundle;
 
 
 public class

    MyActivity extends Activity {
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 Locations locations = new Locations();
 setContentView(R.layout.activity_my);
 }
 } }
 Flavors
  36. 
 public class Locations {
 
 private int mLocations;
 


    public Locations() {
 mLocations = 3;
 }
 
 public int getmLocations() {
 return mLocations;
 }
 } Flavors
  37. 
 public class Locations {
 
 private int mLocations;
 


    public Locations() {
 mLocations = 3;
 }
 
 public int getmLocations() {
 return mLocations;
 }
 } 
 public class Locations {
 
 private int mLocations;
 
 public Locations() {
 mLocations = 5;
 }
 
 public int getmLocations() {
 return mLocations;
 }
 } Flavors
  38. 
 public class Locations {
 
 private int mLocations;
 


    public Locations() {
 mLocations = 3;
 }
 
 public int getmLocations() {
 return mLocations;
 }
 } 
 public class Locations {
 
 private int mLocations;
 
 public Locations() {
 mLocations = 5;
 }
 
 public int getmLocations() {
 return mLocations;
 }
 } 
 Locations locations = new Locations();
 ((TextView) findViewById(R.id.text)).setText(locations.getmLocations()); Flavors
  39. 
 productFlavors {
 dublin {
 applicationId "com.gdg.dublin"
 buildConfigField "String", "API_KEY",

    "\"xxxxx\""
 
 }
 
 cork {
 applicationId "com.gdg.cork"
 buildConfigField "String", "API_KEY", "\"yyyy\""
 }
 } Flavors
  40. Flavors 
 public final class BuildConfig {
 public static final

    boolean DEBUG = Boolean.parseBoolean("true");
 public static final String PACKAGE_NAME = "com.gdg.dublin";
 public static final String BUILD_TYPE = "debug";
 public static final String FLAVOR = "dublin";
 public static final int VERSION_CODE = 1;
 public static final String VERSION_NAME = "1.0";
 // Fields from product flavor: dublin
 public static final String API_KEY = "xxxxx";
 }
  41. Flavors 
 public final class BuildConfig {
 public static final

    boolean DEBUG = Boolean.parseBoolean("true");
 public static final String PACKAGE_NAME = "com.gdg.dublin";
 public static final String BUILD_TYPE = "debug";
 public static final String FLAVOR = "dublin";
 public static final int VERSION_CODE = 1;
 public static final String VERSION_NAME = "1.0";
 // Fields from product flavor: dublin
 public static final String API_KEY = "xxxxx";
 } 
 public final class BuildConfig {
 public static final boolean DEBUG = Boolean.parseBoolean("true");
 public static final String PACKAGE_NAME = "com.gdg.cork";
 public static final String BUILD_TYPE = "debug";
 public static final String FLAVOR = "cork";
 public static final int VERSION_CODE = 1;
 public static final String VERSION_NAME = "1.0";
 // Fields from product flavor: cork
 public static final String API_KEY = "yyyy";
 }
  42. Flavors 
 public final class BuildConfig {
 public static final

    boolean DEBUG = Boolean.parseBoolean("true");
 public static final String PACKAGE_NAME = "com.gdg.dublin";
 public static final String BUILD_TYPE = "debug";
 public static final String FLAVOR = "dublin";
 public static final int VERSION_CODE = 1;
 public static final String VERSION_NAME = "1.0";
 // Fields from product flavor: dublin
 public static final String API_KEY = "xxxxx";
 } 
 public final class BuildConfig {
 public static final boolean DEBUG = Boolean.parseBoolean("true");
 public static final String PACKAGE_NAME = "com.gdg.cork";
 public static final String BUILD_TYPE = "debug";
 public static final String FLAVOR = "cork";
 public static final int VERSION_CODE = 1;
 public static final String VERSION_NAME = "1.0";
 // Fields from product flavor: cork
 public static final String API_KEY = "yyyy";
 } 
 ((TextView) findViewById(R.id.text)).setText(BuildConfig.API_KEY);
  43. Manifest PlaceHolders defaultConfig {
 manifestPlaceholders = [label: "defaultName"]
 manifestPlaceholders =

    [mapKey: "your_debug_key"]
 
 }
 buildTypes {
 release {
 manifestPlaceholders = [mapKey: "your_release_key"]
 }
 }
 productFlavors {
 
 flavor1 {
 manifestPlaceholders = [label: "flavor1"]
 }
 flavor2 {
 manifestPlaceholders = [label: "flavor2"]
 }
 }
  44. <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.myapplication" >
 
 <application
 android:allowBackup="true"


    android:icon="@drawable/ic_launcher"
 android:label="@string/app_name"
 android:theme="@style/AppTheme" >
 <activity
 android:name=".MyActivity"
 android:label="${label}" >
 <intent-filter>
 <action android:name="android.intent.action.MAIN" />
 
 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>
 <meta-data
 android:name="com.google.android.maps.v2.API_KEY"
 android:value="${mapKey}" />
 </application>
 
 </manifest> Manifest PlaceHolders
  45. <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.myapplication" >
 
 <application
 android:allowBackup="true"


    android:icon="@drawable/ic_launcher"
 android:label="@string/app_name"
 android:theme="@style/AppTheme" >
 <activity
 android:name=".MyActivity"
 android:label="${label}" >
 <intent-filter>
 <action android:name="android.intent.action.MAIN" />
 
 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>
 <meta-data
 android:name="com.google.android.maps.v2.API_KEY"
 android:value="${mapKey}" />
 </application>
 
 </manifest> Manifest PlaceHolders