【问题标题】:Crashlytics (Fabric) separate organizations for application variants (build types, product flavors)Crashlytics (Fabric) 为应用程序变体(构建类型、产品风格)分离组织
【发布时间】:2016-03-31 10:42:19
【问题描述】:

这是一个自我回答的问题,分享我的知识。

我有一个包含多种产品风格的项目,我想为每种产品风格使用不同的组织来集成 Fabric。

我尝试使用 Android Studio Fabric 插件集成 Fabric。它增加了

<meta-data
    android:name="io.fabric.ApiKey"
    android:value="DEFAULT_ORGANIZATION_API_KEY" />

AndroidManifest.xmlmain 源集的条目。

我决定在应用程序变体特定的源集中重写此条目:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application>
        <meta-data
            android:name="io.fabric.ApiKey"
            android:value="SECOND_ORGANIZATION_API_KEY"
            tools:replace="android:value" />
    </application>
</manifest>

然后我发现 Fabric Gradle 插件在构建过程中生成了 crashlytics.properties 带有结构 api 秘密(AKA 构建秘密)的文件,我应该将此文件包含到源代码控制中。但是每次我构建特定的应用程序变体时,这个文件都会被覆盖,因为每个应用程序的 api secret 都是唯一的。

如何为每个应用程序变体使用不同的组织来集成 Fabric?

【问题讨论】:

    标签: android gradle crashlytics twitter-fabric android-productflavors


    【解决方案1】:

    在构建过程中调用fabricGenerateResources 任务并查找名为fabric.properties 的文件,其内容如下:

    apiSecret=YOUR_BUILD_SECRET
    apiKey=YOUR_API_KEY
    

    所以我们只需要在此之前生成fabric.properties 文件。

    我找到了this solution 并对其稍作修改以完全支持应用程序变体,而不仅仅是构建类型。

    将此代码添加到build.gradleandroid 部分:

    File crashlyticsProperties = new File("${project.projectDir.absolutePath}/fabric.properties")
    applicationVariants.all { variant ->
        variant.productFlavors.each { flavor ->
            def variantSuffix = variant.name.capitalize()
            def generatePropertiesTask = task("fabricGenerateProperties${variantSuffix}") << {
                Properties properties = new Properties()
                properties.put("apiKey", flavor.fabricApiKey)
                properties.put("apiSecret", flavor.fabricApiSecret)
                properties.store(new FileWriter(crashlyticsProperties), "")
            }
    
            def generateResourcesTask = project.tasks.getByName("fabricGenerateResources${variantSuffix}")
            generateResourcesTask.dependsOn generatePropertiesTask
            generateResourcesTask.doLast {
                println "Removing fabric.properties"
                crashlyticsProperties.delete()
            }
        }
    }
    

    它迭代应用程序变体,并为每个应用程序变体创建生成 fabric.properties 文件的任务和在 Fabric Gradle 插件生成应用程序资源后删除此文件的任务。

    您现在只需要定义产品风味或构建类型特定的fabricApiKeyfabricApiSecret

    productFlavors {
        flavor1 {
            ext.fabricApiKey = "FLAVOR1_API_KEY"
            ext.fabricApiSecret = "FLAVOR1_API_SECRET"
        }
    }
    

    ext 是每个ExtensionAware 对象提供的ExtraPropertiesExtention 对象。它允许将新属性添加到现有对象。在我的例子中,flavor1ExtensionAware 对象,它可以通过使用ext.someProperty = "value" 语法来扩展新属性,之后这些属性可以用作flavor.someProperty, flavor.fabricApiKey

    另外最好将fabric.properties 包含到.gitignore

    如果您在调试期间使用它来禁用 Crashlytics,请不要忘记从调试构建类型中删除 ext.enableCrashlytics = false。取而代之的是,您可以在 Application.onCreate 中禁用它:

    Fabric.with(this, new Crashlytics.Builder().core(
        new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()).build());
    

    【讨论】:

    • ext 对象是什么?
    • 这个方法还能用吗?我正在使用 Crashlytics 2.5.7 和 Fabric 工具 1.21.7。我收到 gradle 错误“在项目 ':app' 中找不到名称为 'fabricGenerateResourcesDebug' 的任务。”
    • 好的,我想通了。我需要从调试构建类型中删除 ext.enableCrashlytics = false 才能生成该 gradle 任务。现在测试一下。我确实有关于 fabric.properties 中的 apiKey 如何工作的问题。这是否取代了在 AndroidManifest.xml 中的需要?
    • 是的,你只需要 fabric.properties。
    • Gradle 抱怨没有 fabricGenerateResourcesDevelopmentDebug 任务.. 我该怎么办?
    【解决方案2】:

    如果您不反对使用应用程序 ID 后缀,则不需要单独的组织。崩溃和答案将被视为单独的应用程序。

    例如,假设我的应用程序 ID 是 io.example

    在你的 build.gradle 中:

    buildTypes {
      debug {
        applicationIdSuffix ".debug"
      }
      release {
        //options
      }
    }
    

    将调试版本部署到设备或模拟器后,在 Fabric 站点上,您将看到两个应用程序:

    • io.example
    • io.example.debug

    这种方法的一个优点是您还可以单独跟踪其他构建风格:io.exmaple.freeio.exmaple.paidio.example.exterprise 等等。

    【讨论】:

    • 这是失败的错误No matching client found for package name com.xxx.xxx.debug。这个错误是由:app:processLiveGoogleServices引起的
    • @CerlinBoss 这是一个不同的错误。您尚未为此“新”应用设置 Google API。 .debug 是一个新应用!
    • 我认为问题在于何时必须为不同的风格使用不同的组织(即不同的 API 机密)。
    【解决方案3】:

    另一个与 Gradle 5.x+ 兼容的更简单的解决方案是为每个需要唯一 Fabric API 密钥和机密的构建变体创建单独的 fabric.properties 文件。将fabric.properties 文件创建为:

    #Contains API Secret used to validate your application. Commit to internal source control; avoid making secret public.
    apiSecret=YOUR_API_SECRET
    apiKey=YOUR_API_KEY
    

    用构建变体的 API 密钥替换 YOUR_API_SECRET,用构建变体的 API 密钥替换 YOUR_API_KEY

    然后将每个变体的fabric.properties 放在项目src/variant 文件夹下,例如app/src/debugapp/src/releaseSee documentation 在构建变体上了解更多详细信息。

    在构建时,将使用正在构建的变体的fabric.properties

    【讨论】:

      猜你喜欢
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-20
      • 1970-01-01
      • 2015-07-09
      相关资源
      最近更新 更多