Different app names for different build flavors?

前端 未结 9 1685
-上瘾入骨i
-上瘾入骨i 2020-12-07 11:07

I have 2 build flavors, say, flavor1 and flavor2.

I would like my application to be named, say, \"AppFlavor1\" when I build for flavor1 an

相关标签:
9条回答
  • 2020-12-07 11:11

    Another option that I actually use is change the manifest for each application. Instead of copy the resource folder, you can create a manifest for each flavour.

    sourceSets {
      main {
     }
    
      release {
        manifest.srcFile 'src/release/AndroidManifest.xml'
     }
    
      debug {
        manifest.srcFile 'src/debug/AndroidManifest.xml'
     }
    }
    

    You have to have a principal AndroidManifest in your src main that will be the principal. Then you can define a manifest with only some options for each flavour like (src/release/AndroidManifest.xml):

    <manifest package="com.application.yourapp">
      <application android:icon="@drawable/ic_launcher">
      </application>
    </manifest>
    

    For debug, AndroidManifest (src/debug/AndroidManifest.xml):

    <manifest package="com.application.yourapp">
      <application android:icon="@drawable/ic_launcher2">
      </application>
    </manifest>
    

    Compiler will do a merge of the manifest and you can have a icon for each flavour.

    0 讨论(0)
  • 2020-12-07 11:11

    In AndroidManifest file, in the application tag you have this line:

    android:label
    

    And there you can say how to application label will appear in applications menu on device

    0 讨论(0)
  • 2020-12-07 11:15

    How do I make string/app_name different per flavor though?

    I wanted to write an update, but realized that it is bigger than the original answer saying that I use a Python script that patches the source.

    The Python script has a parameter, a directory name. That directory contains per-flavor assets, resources like launcher icons, and the file properties.txt with a Python dictionary.

    { 'someBoolean' : True
    , 'someParam' : 'none'
    , 'appTitle' : '@string/x_app_name_xyz'
    }
    

    The Python script loads the dictionary from that file and replaces the value between <string name="app_name"> and </string> by the value of properties['appTitle'].

    The below code is provided on the as-is/as-was basis etc.

    for strings_xml in glob.glob("res/values*/strings.xml"):
        fileReplace(strings_xml,'<string name="app_name">',properties['appTitle'],'</string>',oldtextpattern=r"[a-zA-Z0-9_/@\- ]+")
    

    to read properties from one or more such file:

    with open(filename1) as f:
        properties = eval(f.read())
    with open(filename2) as f:
        properties.update(eval(f.read()))
    

    and the fileReplace function is:

    really = True
    #False for debugging
    
    # In the file 'fname',
    # find the text matching "before oldtext after" (all occurrences) and
    # replace 'oldtext' with 'newtext' (all occurrences).
    # If 'mandatory' is true, raise an exception if no replacements were made.
    def fileReplace(fname,before,newtext,after,oldtextpattern=r"[\w.]+",mandatory=True):
        with open(fname, 'r+') as f:
            read_data = f.read()
            pattern = r"("+re.escape(before)+r")"+oldtextpattern+"("+re.escape(after)+r")"
            replacement = r"\g<1>"+newtext+r"\g<2>"
            new_data,replacements_made = re.subn(pattern,replacement,read_data,flags=re.MULTILINE)
            if replacements_made and really:
                f.seek(0)
                f.truncate()
                f.write(new_data)
                if verbose:
                    print "patching ",fname," (",replacements_made," occurrence" + ("s" if 1!=replacements_made else ""),")",newtext,("-- no changes" if new_data==read_data else "-- ***CHANGED***")
            elif replacements_made:
                print fname,":"
                print new_data
            elif mandatory:
                raise Exception("cannot patch the file: "+fname+" with ["+newtext+"] instead of '"+before+"{"+oldtextpattern+"}"+after+"'")
    

    The first lines of the script are:

    #!/usr/bin/python
    # coding: utf-8
    
    import sys
    import os
    import re
    import os.path
    import shutil
    import argparse
    import string
    import glob
    from myutils import copytreeover
    
    0 讨论(0)
  • 2020-12-07 11:20

    Remove app_name from strings.xml (else gradle will complain of duplicate resources). Then modify build file like this:

    productFlavors {
        flavor1{
            resValue "string", "app_name", "AppNameFlavor1"
        }
    
        flavor2{
            resValue "string", "app_name", "AppNameFlavor2"
        }
       } 
    

    Also make sure @string/app_name value is assigned for android:label attribute in the manifest.

    <application
            ...
            android:label="@string/app_name"
            ...
    

    This is less disruptive than creating new strings.xml under different built sets or writing custom scripts.

    0 讨论(0)
  • 2020-12-07 11:26

    Instead of changing your main strings.xml with a script and risk messing up your source control, why not rely on the standard merging behavior of the Android Gradle build?

    My build.gradle contains

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }
    
        release {
            res.srcDir 'variants/release/res'
        }
    
        debug {
            res.srcDir 'variants/debug/res'
        }
    }
    

    So now I can define my app_name string in the variants/[release|debug]/res/strings.xml. And anything else I want to change, too!

    0 讨论(0)
  • 2020-12-07 11:29

    This can easily be accomplished under buildTypes

    buildTypes {
        debug {
            buildConfigField("String", "server_type", "\"TEST\"")
            resValue "string", "app_name", "Eventful-Test"
            debuggable true
            signingConfig signingConfigs.debug_key_sign
        }
    
        stage {
            buildConfigField("String", "server_type", "\"STAGE\"")
            resValue "string", "app_name", "Eventful-Stage"
            debuggable true
            signingConfig signingConfigs.debug_key_sign
        }
    
        release {
            buildConfigField("String", "server_type", "\"PROD\"")
            resValue "string", "app_name", "Eventful"
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            //TODO - add release signing
        }
    }
    

    Just make sure to remove app_name from strings.xml

    0 讨论(0)
提交回复
热议问题