使用风格在 AppGallery 和 Google Play 上发布应用
Using flavors for publishing an app on AppGallery and Google Play
我正在尝试弄清楚如何在 AppGallery 和 Google Play 上发布我的应用程序。 (我的应用目前在 Google Play 上可用)
我研究了三个小时,最好的选择是使用 flavors。因为我想为不同的商店使用相同的代码库。为此,我决定添加这样的口味:
productFlavors {
gms {
dimension "services"
buildConfigField "String", "SERVICE_USED", '"g"'
}
hms {
dimension "services"
buildConfigField "String", "SERVICE_USED", '"h"'
}
}
gmsImplementation 'com.google.firebase:firebase-analytics:17.2.0'
gmsImplementation 'com.google.firebase:firebase-messaging:20.0.0'
gmsImplementation 'com.google.firebase:firebase-ads:18.2.0'
gmsImplementation 'com.google.firebase:firebase-crashlytics:17.2.2'
hmsImplementation 'com.huawei.hms:ads-installreferrer:3.4.34.301'
hmsImplementation 'com.huawei.hms:ads-identifier:3.4.34.301'
hmsImplementation 'com.huawei.hms:hianalytics:5.0.5.301'
hmsImplementation 'com.huawei.hms:iap:5.0.4.301'
hmsImplementation 'com.huawei.hms:push:5.0.4.302'
现在我有一个问题:
如果我错了请指正,我需要为公共服务使用抽象层,对吧?例如,如果我需要使用 IAP,我需要一个根据设备类型决定使用 GMS 还是 HMS 的包装器 class。如果我采用这种方式,我需要这样的东西:
需要一个接口,需要在HmsIAP和GmsIAP classes上实现requestProduct方法,purchaseMethod等常用方法。等等
创建这些 class 并管理要使用的 class 的父 class。那将称为“AppIAP”class。逻辑层将使用 class 进行不依赖于平台的 IAP 操作。
这种方法对我来说很有意义,两个平台将有一个代码库。看起来干净利落,方便日后管理。但问题是我为平台依赖添加了风味。因此,如果我尝试构建我的代码的 hms 变体,它将无法编译,因为 Gms 库将丢失。尽管我使用的是 Hms 变体,但我仍然有一个 GmsIAP class 需要构建。
为了解决这个问题,我可以尝试不使用这些风格,通过这种方法,我需要将我的应用程序与两个平台的库一起打包,并且我的应用程序可以正常编译。但如下图所示 link Google 由于 Hms 库,播放将拒绝我的应用程序。
我该如何解决?
我认为最可维护的解决方案是使用依赖注入 different source sets for different flavors. You can put your GMS dependent code inside src/gms/java
and your HMS dependent code inside src/hms/java
. Only the selected product flavor source set will be compiled. Very basic example with Hilt 看起来像这样:
在您的主要源集中,您将拥有
src/main/java/your/package/AppMobileServices.kt
interface AppMobileServices {
val isAvailable: Boolean
}
然后为GMS源集
src/gms/java/your/package/GmsModule.kt
:
@Module
@InstallIn(SingletonComponent::class)
class GmsModule {
@Provides
fun googleMobileServices(@ApplicationContext context: Context): AppMobileServices {
return GmsServices(context)
}
}
src/gms/java/your/package/GmsServices.kt
:
@Singleton
class GmsServices(@ApplicationContext private val context: Context) : AppMobileServices {
override val isAvailable: Boolean
get() = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS
}
然后HMS源集
src/hms/java/your/package/HmsModule.kt
:
@Module
@InstallIn(SingletonComponent::class)
class HmsModule {
@Provides
fun huaweiMobileServices(@ApplicationContext context: Context): AppMobileServices {
return HmsServices(context)
}
}
src/hms/java/your/package/HmsServices.kt
:
@Singleton
class HmsServices(@ApplicationContext private val context: Context) : AppMobileServices {
override val isAvailable: Boolean
get() = HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable(context) == ConnectionResult.SUCCESS
}
然后在您的主要源代码集中,您只需注入 AppMobileServices
即可提供正确的代码。此外,所有依赖于 GMS 或 HMS 的代码都将进入其风格源集中。
@Inject
lateinit var appMobileServices: AppMobileServices
我正在尝试弄清楚如何在 AppGallery 和 Google Play 上发布我的应用程序。 (我的应用目前在 Google Play 上可用)
我研究了三个小时,最好的选择是使用 flavors。因为我想为不同的商店使用相同的代码库。为此,我决定添加这样的口味:
productFlavors {
gms {
dimension "services"
buildConfigField "String", "SERVICE_USED", '"g"'
}
hms {
dimension "services"
buildConfigField "String", "SERVICE_USED", '"h"'
}
}
gmsImplementation 'com.google.firebase:firebase-analytics:17.2.0'
gmsImplementation 'com.google.firebase:firebase-messaging:20.0.0'
gmsImplementation 'com.google.firebase:firebase-ads:18.2.0'
gmsImplementation 'com.google.firebase:firebase-crashlytics:17.2.2'
hmsImplementation 'com.huawei.hms:ads-installreferrer:3.4.34.301'
hmsImplementation 'com.huawei.hms:ads-identifier:3.4.34.301'
hmsImplementation 'com.huawei.hms:hianalytics:5.0.5.301'
hmsImplementation 'com.huawei.hms:iap:5.0.4.301'
hmsImplementation 'com.huawei.hms:push:5.0.4.302'
现在我有一个问题:
如果我错了请指正,我需要为公共服务使用抽象层,对吧?例如,如果我需要使用 IAP,我需要一个根据设备类型决定使用 GMS 还是 HMS 的包装器 class。如果我采用这种方式,我需要这样的东西:
需要一个接口,需要在HmsIAP和GmsIAP classes上实现requestProduct方法,purchaseMethod等常用方法。等等
创建这些 class 并管理要使用的 class 的父 class。那将称为“AppIAP”class。逻辑层将使用 class 进行不依赖于平台的 IAP 操作。
这种方法对我来说很有意义,两个平台将有一个代码库。看起来干净利落,方便日后管理。但问题是我为平台依赖添加了风味。因此,如果我尝试构建我的代码的 hms 变体,它将无法编译,因为 Gms 库将丢失。尽管我使用的是 Hms 变体,但我仍然有一个 GmsIAP class 需要构建。
为了解决这个问题,我可以尝试不使用这些风格,通过这种方法,我需要将我的应用程序与两个平台的库一起打包,并且我的应用程序可以正常编译。但如下图所示 link Google 由于 Hms 库,播放将拒绝我的应用程序。
我该如何解决?
我认为最可维护的解决方案是使用依赖注入 different source sets for different flavors. You can put your GMS dependent code inside src/gms/java
and your HMS dependent code inside src/hms/java
. Only the selected product flavor source set will be compiled. Very basic example with Hilt 看起来像这样:
在您的主要源集中,您将拥有
src/main/java/your/package/AppMobileServices.kt
interface AppMobileServices {
val isAvailable: Boolean
}
然后为GMS源集
src/gms/java/your/package/GmsModule.kt
:
@Module
@InstallIn(SingletonComponent::class)
class GmsModule {
@Provides
fun googleMobileServices(@ApplicationContext context: Context): AppMobileServices {
return GmsServices(context)
}
}
src/gms/java/your/package/GmsServices.kt
:
@Singleton
class GmsServices(@ApplicationContext private val context: Context) : AppMobileServices {
override val isAvailable: Boolean
get() = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS
}
然后HMS源集
src/hms/java/your/package/HmsModule.kt
:
@Module
@InstallIn(SingletonComponent::class)
class HmsModule {
@Provides
fun huaweiMobileServices(@ApplicationContext context: Context): AppMobileServices {
return HmsServices(context)
}
}
src/hms/java/your/package/HmsServices.kt
:
@Singleton
class HmsServices(@ApplicationContext private val context: Context) : AppMobileServices {
override val isAvailable: Boolean
get() = HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable(context) == ConnectionResult.SUCCESS
}
然后在您的主要源代码集中,您只需注入 AppMobileServices
即可提供正确的代码。此外,所有依赖于 GMS 或 HMS 的代码都将进入其风格源集中。
@Inject
lateinit var appMobileServices: AppMobileServices