如何为不同的gradle buildTypes 提供不同的Android应用程序图标?

151

我的gradle文件中设置了两种构建类型:debugrelease。我想为debug构建类型设置不同的应用程序图标。是否有一种只通过构建类型而不涉及产品风格就能实现这个目标的方法?build.gradle文件如下所示。

apply plugin: 'android'

//...

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 19
        versionCode 30
        versionName "2.0"
    }
    buildTypes {
        debug {
            packageNameSuffix '.debug'
            versionNameSuffix '-SNAPSHOT'
        }
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

请查看此链接:https://dev59.com/aGMl5IYBdhLWcg3wXWAT。 - Libin
3
可能是与Android - app icon for debug and release mode重复的问题。 - Jose Gómez
5个回答

218

已经弄清楚了。你需要做的是创建一个名为 debug 的单独的 src 文件夹,其中包含不同的图标。例如,如果您的项目布局如下所示,并且您的启动器图标称为 ic_launcher.png

[Project Root]
  -[Module]
    -src
      -main
        -res
          -drawable-*
            -ic_launcher.png

要为调试构建类型添加单独的图标,您需要添加:

[Project Root]
  -[Module]
    -src
      -main
        -res
          -drawable-*
            -ic_launcher.png
      -debug
        -res
          -drawable-*
            -ic_launcher.png

那么,当您使用调试构建类型进行构建时,它将使用在 debug 文件夹中找到的 ic_launcher。


1
@ncoronges 我没有。看起来由于调试是内置的构建类型,因此它的源集也是内置的。 - InsanityOnABun
1
@Scott 如果我只是将我的图标放在每个drawable文件夹中,例如drawable-mdpi、drawable-hdpi等,那么使用“debug”对我有效。 我不需要调试文件夹中的任何其他资源或代码。 - roarster
3
运行得非常好。只需将所有的mipmap文件夹复制到debug文件夹中即可。 - Amit Bhandari
3
如何修改应用程序名称? - DKV
1
对我来说不起作用,因为我必须添加drawable-v24,因为我在主文件中有一个。 - JPM
显示剩余4条评论

130

虽然这是一种方便的方法,但它有一个重要的缺点......两个启动器都会被放入您的apk。Bartek Lipinski

更好的方法:InsanityOnABun的答案

AndroidManifest.xml

<manifest 

    ...
        <application
        android:allowBackup="true"
        android:icon="${appIcon}"
        android:roundIcon="${appIconRound}"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

    ...

    </application>

</manifest>

build.gradle

android {

    ...
        productFlavors{
        Test{
            versionName "$defaultConfig.versionName" + ".test"
            resValue "string", "app_name", "App-Test"
            manifestPlaceholders = [
                    appIcon: "@mipmap/ic_launcher_test",
                    appIconRound: "@mipmap/ic_launcher_test_round"
            ]
        }

        Product{
            resValue "string", "app_name", "App"
            manifestPlaceholders = [
                    appIcon: "@mipmap/ic_launcher",
                    appIconRound: "@mipmap/ic_launcher_round"
            ]
        }
    }
}

Github链接:使用Gradle构建多版本应用程序


2
这是一个方便的方法,尽管它有一个重要的缺点... 两个启动器都将被放入您的apk中。 - Bartek Lipinski
3
为什么这个重要的缺点?在我看来,它并不是太重要,而且这是一个好的、干净的Gradle解决方案。 - luky
2
我支持 @luky 的问题。为什么这是一个不利因素?我认为添加额外的顶层目录(我的项目中有四个不同的构建变体)比使用清单占位符更不干净。特别是当这些目录只包含一个图标时。 - Greg
如果您想使用此方法并停止将两个图标添加到生产 APK 中,您可以仅在执行阶段或 if 语句后设置 manifestPlaceholders。我这样做是因为我有一个非生产构建类型,可以具有两个不同的图标(我不想将整个构建类型与其他构建类型仅有1个差异)。 - Nahuel Barrios
我认为这是最好的解决方案,但你应该同时使用这两个解决方案(这个解决方案和这个问题的第一个解决方案),它们在组合使用时非常好。 - Arsen Tagaev
显示剩余6条评论

17
你还可以在产品风味的部分AndroidManifest.xml文件中指定图标:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">
    <application
        tools:replace="android:icon"
        android:icon="@drawable/alternative_icon" />
</manifest>

这将覆盖在原始的 AndroidManifest.xml 文件中指定的图标。


6
请检查问题:“有没有办法只通过构建类型来完成这个,而不涉及产品口味?” - InsanityOnABun
8
虽然不是我要求的,但它确实帮了我很多!用了一些口味。 - Flummox - don't be evil SE
2
如果您已经有特定于口味的清单文件,则最好的方法是使用它。 - Zax
到目前为止,这是我见过的唯一一个可以维护启动器图标的唯一名称的解决方案,而不是有10多个版本的ic_launcher.png,只能通过其位置或实际打开它来知道哪个是哪个(不太好)。我不知道这种扩展清单文件的方式甚至是可能的,在SO或其他地方之前都没有看到过。肯定很优雅。 - Gene Bo

8

在使用多个维度(例如多种尺寸)的不同风格时,需要获得不同的图标,例如:

flavorDimensions "color", "size"
productFlavors {
    black {
        dimension "color"
    }
    white {
        dimension "color"
    }

    big {
        dimension "size"
    }
    small {
        dimension "size"
    }
}

这可以通过以下方式实现:
首先,将调试资源放置在单独的文件夹中,例如:
src/blackDebug/res
src/whiteDebug/res

其次,对于具有多个口味维度的密钥,必须在sourceset名称中包含所有可能的口味组合,即使其中一些维度不影响图标。

sourceSets {
    // Override the icons in debug mode
    blackBigDebug.res.srcDir 'src/blackDebug/res'
    blackSmallDebug.res.srcDir 'src/blackDebug/res'
    whiteBigDebug.res.srcDir 'src/whiteDebug/res'
    whiteSamllDebug.res.srcDir 'src/whiteDebug/res'
}

需要明确的是,当使用多个维度时,以下不起作用

sourceSets {
    // Override the icons in debug mode
    blackDebug.res.srcDir 'src/blackDebug/res'
    whiteDebug.res.srcDir 'src/whiteDebug/res'
}

不确定这会如何帮助,因为启动图标已在清单文件中声明。您能解决这个问题吗? - David Rector
4
资源名称已在清单中声明,但是根据我的帖子中所述,在不同的特定于口味的文件夹中可以使用相同文件名的不同图标。 - Jose Gómez

6

逐步解决方案,包括替换mipmap-anydpi-v26并保留所有维度的文件:

首先在build.gradle(Module:app)中定义您的构建类型,即android -> buildTypes -> debug,internal等

在项目层次结构下,单击Android下的app -> New -> Image Asset -> 在路径中选择您的图标 -> 在Background Layer和Legacy上进行任何其他更改 -> Next -> 在Res Directory中选择您想要的构建类型(debug、internal、main等) -> Finish

这样一来,图标将替换您以前拥有的每个旧图标。


干净的解决方案。 - Olek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接