Crashlytics (Fabric) 为应用程序变体(构建类型、产品风格)分离组织

Posted

技术标签:

【中文标题】Crashlytics (Fabric) 为应用程序变体(构建类型、产品风格)分离组织【英文标题】:Crashlytics (Fabric) separate organizations for application variants (build types, product flavors) 【发布时间】: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?

【问题讨论】:

【参考方案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/release。 See documentation 在构建变体上了解更多详细信息。

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

【讨论】:

以上是关于Crashlytics (Fabric) 为应用程序变体(构建类型、产品风格)分离组织的主要内容,如果未能解决你的问题,请参考以下文章

无法为 DEBUG 版本禁用 Fabric 的 Crashlytics with Firebase

使用Fabric插件为具有groovy插件DSL的Crashlytics建立版本

iOS(Fabric):Crashlytics 在启动时崩溃应用程序

iOS 中的 Crashlytics 不会继续通过 Fabric 应用程序中的“构建您的项目”

Fabric Crashlytics 与 Angular Web 应用程序

无法从 Crashlytics 升级到 Fabric