rc-configuring-the-sdk

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Configuring the RevenueCat Android SDK

配置RevenueCat Android SDK

Use this skill to add and configure RevenueCat (
purchases-kt
) in an Android app. A single
Purchases.configure
call replaces
BillingClient
setup, connection lifecycle management, reconnection handling, and launch-time purchase queries.
Work through the phases in order. The full chapter on revenuecat.com has the complete reference text.
当你需要在Android应用中添加和配置RevenueCat(
purchases-kt
)时使用本技能。单次
Purchases.configure
调用即可替代
BillingClient
的初始化、连接生命周期管理、重连处理以及启动时的购买查询操作。
请按顺序完成以下阶段。revenuecat.com上的完整章节包含完整的参考内容。

Phase 1: Discovery

阶段1:排查

Find out whether RevenueCat is already wired up and where billing code currently lives.
  1. Search for an existing configure call and prior SDK version.
    bash
    rg -n "Purchases\.configure|PurchasesConfiguration" --type kotlin --type java
    rg -n "com\.revenuecat\.purchases" -g '*.gradle*' -g '*.toml'
  2. Search for the existing billing surface you may be replacing.
    bash
    rg -n "BillingClient|PurchasesUpdatedListener|startConnection" --type kotlin --type java
  3. Record answers before moving on.
QuestionWhere to look
Is
Purchases.configure
already called?
App startup,
Application.onCreate
, main
Activity.onCreate
Which module owns billing today?
app/build.gradle(.kts)
, any
:billing
module
Is there an auth system with a stable user id?Login flow, session store
Debug vs release build detection available?
BuildConfig.DEBUG
If
Purchases.configure
already runs, stop and confirm with the user before changing it. Configuration runs once per process.
确认RevenueCat是否已集成,以及当前计费代码的位置。
  1. 搜索现有的configure调用和之前的SDK版本。
    bash
    rg -n "Purchases\.configure|PurchasesConfiguration" --type kotlin --type java
    rg -n "com\.revenuecat\.purchases" -g '*.gradle*' -g '*.toml'
  2. 搜索可能需要替换的现有计费相关代码。
    bash
    rg -n "BillingClient|PurchasesUpdatedListener|startConnection" --type kotlin --type java
  3. 在进行下一步前记录答案。
问题查看位置
是否已调用
Purchases.configure
应用启动处、
Application.onCreate
、主
Activity.onCreate
当前哪个模块负责计费?
app/build.gradle(.kts)
、任何
:billing
模块
是否存在带有稳定用户ID的认证系统?登录流程、会话存储
是否支持区分Debug和Release构建?
BuildConfig.DEBUG
如果
Purchases.configure
已在运行,修改前请先与用户确认。配置每个进程仅需运行一次。

Phase 2: Plan

阶段2:规划

Decide three things before writing code.
编写代码前需确定三件事。

2.1 Where to call configure

2.1 确定调用configure的位置

LocationWhen to choose
Application.onCreate
Default. Ensures the SDK is ready before any
Activity
or background work touches purchases.
First
Activity.onCreate
Only if the app has no custom
Application
class and you are not willing to add one.
Call
configure
exactly once per process. Calling it from an
Activity
risks re-running it on configuration changes if you are not careful; the
Application
path avoids that.
位置选择时机
Application.onCreate
默认选项。确保在任何
Activity
或后台任务处理购买操作前,SDK已准备就绪。
首个
Activity.onCreate
仅当应用没有自定义
Application
类且你不愿添加时选择此方式。
每个进程需恰好调用一次
configure
。若从
Activity
中调用,若处理不当可能会在配置变更时重复运行;通过
Application
调用可避免此问题。

2.2 App user id strategy

2.2 应用用户ID策略

StrategyPass to
appUserID
Use when
Anonymous
null
Users can purchase before signing in, or you have no auth. Later call
Purchases.sharedInstance.logIn(id)
to merge history.
Known userYour stable backend id (for example
"user_12345"
)
Users are always authenticated before purchase.
Do not pass device ids, email addresses, or values that can change. If you do not have the id at startup, configure anonymously and call
logIn
after authentication.
策略传入
appUserID
的值
使用场景
匿名用户
null
用户可在登录前进行购买,或应用无认证系统。后续可调用
Purchases.sharedInstance.logIn(id)
合并购买历史。
已知用户你的后端稳定ID(例如
"user_12345"
用户始终在认证后进行购买。
请勿传入设备ID、电子邮件地址或可能变更的值。若启动时无法获取用户ID,可先以匿名方式配置,认证完成后调用
logIn

2.3 Log level

2.3 日志级别

BuildLog level
Debug
LogLevel.DEBUG
or
VERBOSE
while integrating
Release
LogLevel.INFO
(default) or
WARN
Switch on
BuildConfig.DEBUG
so production builds stay quiet.
构建类型日志级别
Debug集成期间使用
LogLevel.DEBUG
VERBOSE
Release使用
LogLevel.INFO
(默认)或
WARN
通过
BuildConfig.DEBUG
控制日志级别,确保生产构建日志保持简洁。

Phase 3: Execute

阶段3:实施

3.1 Add the Gradle dependency

3.1 添加Gradle依赖

In the app module
build.gradle.kts
:
kotlin
dependencies {
    implementation("com.revenuecat.purchases:purchases:<latest>")
}
Replace
<latest>
with the current published version. If the project uses a Groovy
build.gradle
, use
implementation 'com.revenuecat.purchases:purchases:<latest>'
. Sync Gradle after the change.
在应用模块的
build.gradle.kts
中:
kotlin
dependencies {
    implementation("com.revenuecat.purchases:purchases:<latest>")
}
<latest>
替换为当前发布的最新版本。若项目使用Groovy版
build.gradle
,则使用
implementation 'com.revenuecat.purchases:purchases:<latest>'
。修改后同步Gradle。

3.2 Call configure at startup

3.2 在启动时调用configure

In your
Application
subclass:
kotlin
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Purchases.logLevel =
            if (BuildConfig.DEBUG) LogLevel.DEBUG else LogLevel.INFO
        Purchases.configure(
            PurchasesConfiguration.Builder(this, BuildConfig.RC_API_KEY)
                .appUserID(null) // or your stable user id
                .build()
        )
    }
}
Register the class in
AndroidManifest.xml
with
android:name=".App"
on
<application>
. Keep the public Android SDK key out of source; inject it through
BuildConfig
or a secret manager.
在你的
Application
子类中:
kotlin
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Purchases.logLevel =
            if (BuildConfig.DEBUG) LogLevel.DEBUG else LogLevel.INFO
        Purchases.configure(
            PurchasesConfiguration.Builder(this, BuildConfig.RC_API_KEY)
                .appUserID(null) // 或你的稳定用户ID
                .build()
        )
    }
}
AndroidManifest.xml
<application>
标签中通过
android:name=".App"
注册该类。请勿将公开的Android SDK密钥存入源码;通过
BuildConfig
或密钥管理器注入。

3.3 Confirm the wiring with a minimal offerings fetch

3.3 通过获取最小化产品包确认集成成功

From any coroutine scope after
configure
has run:
kotlin
lifecycleScope.launch {
    val offerings = Purchases.sharedInstance.awaitOfferings()
    Log.d("RC", "current=${offerings.current?.identifier}")
}
A non-null
offerings.current
identifier means the API key, package name, and network path are working. If you see
null
, check the dashboard offering setup and the package name match before touching code.
configure
运行后的任何协程作用域中执行:
kotlin
lifecycleScope.launch {
    val offerings = Purchases.sharedInstance.awaitOfferings()
    Log.d("RC", "current=${offerings.current?.identifier}")
}
offerings.current?.identifier
不为空,说明API密钥、包名和网络路径均正常工作。若返回
null
,请先检查控制台产品包设置与包名是否匹配,再修改代码。

What the SDK handles for you

SDK为你处理的事项

Once configured, you do not need to:
  • Create or close a
    BillingClient
  • Call
    startConnection
    or
    endConnection
  • Check
    isReady
    or write reconnection logic for
    SERVICE_DISCONNECTED
  • Call
    queryPurchasesAsync
    at launch; the SDK posts unfinished transactions automatically
配置完成后,你无需再:
  • 创建或关闭
    BillingClient
  • 调用
    startConnection
    endConnection
  • 检查
    isReady
    或编写
    SERVICE_DISCONNECTED
    的重连逻辑
  • 启动时调用
    queryPurchasesAsync
    ;SDK会自动处理未完成的交易

Common pitfalls

常见问题

SymptomLikely cause
IllegalStateException: There is no singleton instance
Code touched
Purchases.sharedInstance
before
configure
ran. Move
configure
to
Application.onCreate
.
Offerings always
null
Package name mismatch between Play Console and dashboard, or offering not marked current.
Duplicate anonymous users
configure
called more than once per process, or an unstable id passed as
appUserID
.
Verbose logs in productionLog level not gated on
BuildConfig.DEBUG
.
症状可能原因
IllegalStateException: There is no singleton instance
configure
运行前调用了
Purchases.sharedInstance
。将
configure
移至
Application.onCreate
产品包始终返回
null
Play控制台与后台的包名不匹配,或产品包未标记为当前可用。
重复的匿名用户每个进程多次调用
configure
,或传入了不稳定的ID作为
appUserID
生产环境日志过于冗长日志级别未通过
BuildConfig.DEBUG
进行控制。

References

参考资料