Crashlytics (Fabric) 为应用程序变体(构建类型、产品风格)分离组织
Crashlytics (Fabric) separate organizations for application variants (build types, product flavors)
这是一个自我回答的问题,用于分享我的知识。
我有一个包含多种产品风格的项目,我想为每种产品风格使用单独的组织来集成 Fabric。
我尝试使用 Android Studio Fabric 插件集成 Fabric。它增加了
<meta-data
android:name="io.fabric.ApiKey"
android:value="DEFAULT_ORGANIZATION_API_KEY" />
进入 main
个源集的 AndroidManifest.xml
。
我决定在特定于应用程序变体的源集中重写此条目:
<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 插件在构建期间生成带有 fabric api 秘密(也称为构建秘密)的 crashlytics.properties
文件,我应该将此文件包含到源代码管理中。但是每次我构建特定的应用程序变体时,这个文件都会被覆盖,因为 api 秘密对于每个应用程序都是唯一的。
如何为每个应用程序变体使用单独的组织来集成 Fabric?
在构建过程中调用 fabricGenerateResources
任务,它会查找名为 fabric.properties
的文件,其中包含以下内容:
apiSecret=YOUR_BUILD_SECRET
apiKey=YOUR_API_KEY
所以我们只需要在此之前生成 fabric.properties
文件。
我发现 this solution 并稍微修改它以完全支持应用程序变体,而不仅仅是构建类型。
将此代码添加到 build.gradle
的 android
部分:
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 插件生成应用程序资源后删除此文件的任务。
您现在所需要做的就是定义产品风味或特定构建类型 fabricApiKey
和 fabricApiSecret
:
productFlavors {
flavor1 {
ext.fabricApiKey = "FLAVOR1_API_KEY"
ext.fabricApiSecret = "FLAVOR1_API_SECRET"
}
}
ext
是一个 ExtraPropertiesExtention object provided by every ExtensionAware 对象。它允许将新属性添加到现有对象。在我的例子中 flavor1
是 ExtensionAware
对象,它可以通过使用 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());
如果您不反对使用应用程序 ID 后缀,则不需要单独的组织。崩溃和答案将被视为单独的应用程序。
例如,假设我的应用程序 ID 是 io.example
在你的 build.gradle:
buildTypes {
debug {
applicationIdSuffix ".debug"
}
release {
//options
}
}
将调试版本部署到设备或模拟器后,您将在 Fabric 站点上看到两个应用程序:
io.example
io.example.debug
这种方法的一个优点是您还可以单独跟踪其他构建风格:io.exmaple.free
、io.exmaple.paid
、io.example.exterprise
等。
一个更简单的解决方案,也与 Gradle 5.x+ 兼容,是为每个需要独特结构的构建变体创建单独的 fabric.properties
文件 [=31= 】 钥匙和秘密。将 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
将 YOUR_API_SECRET
替换为构建变体的 API 秘密,将 YOUR_API_KEY
替换为构建变体的 API 密钥。
然后将每个变体的 fabric.properties
放在项目 src/variant
文件夹下,例如app/src/debug
或 app/src/release
。 See documentation 有关构建变体的更多详细信息。
在构建时,将使用正在构建的变体的 fabric.properties
。
这是一个自我回答的问题,用于分享我的知识。
我有一个包含多种产品风格的项目,我想为每种产品风格使用单独的组织来集成 Fabric。
我尝试使用 Android Studio Fabric 插件集成 Fabric。它增加了
<meta-data
android:name="io.fabric.ApiKey"
android:value="DEFAULT_ORGANIZATION_API_KEY" />
进入 main
个源集的 AndroidManifest.xml
。
我决定在特定于应用程序变体的源集中重写此条目:
<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 插件在构建期间生成带有 fabric api 秘密(也称为构建秘密)的 crashlytics.properties
文件,我应该将此文件包含到源代码管理中。但是每次我构建特定的应用程序变体时,这个文件都会被覆盖,因为 api 秘密对于每个应用程序都是唯一的。
如何为每个应用程序变体使用单独的组织来集成 Fabric?
在构建过程中调用 fabricGenerateResources
任务,它会查找名为 fabric.properties
的文件,其中包含以下内容:
apiSecret=YOUR_BUILD_SECRET
apiKey=YOUR_API_KEY
所以我们只需要在此之前生成 fabric.properties
文件。
我发现 this solution 并稍微修改它以完全支持应用程序变体,而不仅仅是构建类型。
将此代码添加到 build.gradle
的 android
部分:
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 插件生成应用程序资源后删除此文件的任务。
您现在所需要做的就是定义产品风味或特定构建类型 fabricApiKey
和 fabricApiSecret
:
productFlavors {
flavor1 {
ext.fabricApiKey = "FLAVOR1_API_KEY"
ext.fabricApiSecret = "FLAVOR1_API_SECRET"
}
}
ext
是一个 ExtraPropertiesExtention object provided by every ExtensionAware 对象。它允许将新属性添加到现有对象。在我的例子中 flavor1
是 ExtensionAware
对象,它可以通过使用 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());
如果您不反对使用应用程序 ID 后缀,则不需要单独的组织。崩溃和答案将被视为单独的应用程序。
例如,假设我的应用程序 ID 是 io.example
在你的 build.gradle:
buildTypes {
debug {
applicationIdSuffix ".debug"
}
release {
//options
}
}
将调试版本部署到设备或模拟器后,您将在 Fabric 站点上看到两个应用程序:
io.example
io.example.debug
这种方法的一个优点是您还可以单独跟踪其他构建风格:io.exmaple.free
、io.exmaple.paid
、io.example.exterprise
等。
一个更简单的解决方案,也与 Gradle 5.x+ 兼容,是为每个需要独特结构的构建变体创建单独的 fabric.properties
文件 [=31= 】 钥匙和秘密。将 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
将 YOUR_API_SECRET
替换为构建变体的 API 秘密,将 YOUR_API_KEY
替换为构建变体的 API 密钥。
然后将每个变体的 fabric.properties
放在项目 src/variant
文件夹下,例如app/src/debug
或 app/src/release
。 See documentation 有关构建变体的更多详细信息。
在构建时,将使用正在构建的变体的 fabric.properties
。