Migrate Adapty Android SDK lên v. 4.0

Adapty Android SDK 4.0 giới thiệu flows và đổi tên các API paywall cho phù hợp. Các API mới hoạt động với cả Flow Builder mới và Paywall Builder hiện có — không cần thay đổi gì trên Adapty Dashboard.

Tham chiếu nhanh

v3v4
Adapty.getPaywall(placementId, locale)Adapty.getFlow(placementId)
Adapty.getPaywallForDefaultAudience(placementId, locale)Adapty.getFlowForDefaultAudience(placementId)
AdaptyUI.getViewConfiguration(paywall)AdaptyUI.getFlowConfiguration(flow, locale)
AdaptyUI.LocalizedViewConfigurationAdaptyUI.FlowConfiguration
Adapty.getPaywallProducts(paywall)Adapty.getPaywallProducts(flow)
Adapty.logShowPaywall(paywall)Adapty.logShowFlow(flow)
AdaptyPaywallAdaptyFlow
AdaptyUI.getPaywallView(...)AdaptyUI.getFlowView(...)
AdaptyPaywallViewAdaptyFlowView
AdaptyPaywallScreen (Compose)AdaptyFlowScreen
showPaywall(...)showFlow(...)
AdaptyPaywallInsetsAdaptyFlowInsets
AdaptyUiEventListenerAdaptyFlowEventListener
AdaptyUiDefaultEventListenerAdaptyFlowDefaultEventListener
onPaywallShown / onPaywallClosedonFlowShown / onFlowClosed
onRenderingErroronError
Adapty.updateAttribution(attribution, source) (source: String)Adapty.updateAttribution(attribution, source) (source: AdaptyAttributionSource)
Adapty.setIntegrationIdentifier(key, value)Adapty.setIntegrationIdentifier(AdaptyIntegrationIdentifier)
AdaptyPaywallProduct giữ nguyên tên — các sản phẩm vẫn thuộc về một flow, và getPaywallProducts giờ nhận vào một AdaptyFlow. Các phương thức khác của AdaptyFlowEventListener (onProductSelected, onPurchaseStarted, onPurchaseFinished, onPurchaseFailure, onRestoreSuccess, onRestoreFailure, onActionPerformed, onAwaitingPurchaseParams, onLoadingProductsFailure, v.v.) giữ nguyên tên và chữ ký.

Cài đặt

Đặt phiên bản adapty-bom thành 4.0.0 (hoặc mới hơn) và đồng bộ hóa dự án. BOM sẽ tự động phân giải các phiên bản android-sdkandroid-ui tương ứng cho bạn. Xem Cài đặt Adapty SDK để biết cách khai báo dependency.

Các API đã bị xóa và không còn được hỗ trợ

  • Adapty.makePurchase(activity, product, subscriptionUpdateParams, isOfferPersonalized, callback) — đã bị xóa. Overload này đã bị deprecated từ v3. Thay vào đó, hãy truyền các tùy chọn tương tự thông qua AdaptyPurchaseParameters:
- Adapty.makePurchase(activity, product, subscriptionUpdateParams, isOfferPersonalized) { result -> /* ... */ }
+ val params = AdaptyPurchaseParameters.Builder()
+     .withSubscriptionUpdateParams(subscriptionUpdateParams)
+     .withOfferPersonalized(isOfferPersonalized)
+     .build()
+ Adapty.makePurchase(activity, product, params) { result -> /* ... */ }
  • Onboardings đã bị deprecated. AdaptyUI.getOnboardingViewAdaptyUI.getOnboardingConfiguration được đánh dấu @Deprecated trong 4.0 — hãy migrate các onboarding sang flow được xây dựng trong Flow Builder.

Tải flows

getPaywall + getViewConfiguration → getFlow + getFlowConfiguration

Kiểu trả về của lệnh fetch thay đổi từ AdaptyPaywall sang AdaptyFlow, và trình tải cấu hình được đổi tên từ AdaptyUI.getViewConfiguration thành AdaptyUI.getFlowConfiguration (trả về AdaptyUI.FlowConfiguration thay vì AdaptyUI.LocalizedViewConfiguration). Tham số locale được chuyển ra khỏi lệnh fetch và đưa vào getFlowConfiguration:

- Adapty.getPaywall("YOUR_PLACEMENT_ID", locale = "en") { result ->
+ Adapty.getFlow("YOUR_PLACEMENT_ID") { result ->
      if (result is AdaptyResult.Success) {
-         val paywall = result.value
-         if (!paywall.hasViewConfiguration) return@getPaywall
-         AdaptyUI.getViewConfiguration(paywall) { configResult ->
+         val flow = result.value
+         if (!flow.hasViewConfiguration) return@getFlow
+         AdaptyUI.getFlowConfiguration(flow, locale = "en") { configResult ->
              if (configResult is AdaptyResult.Success) {
                  val flowConfiguration = configResult.value
              }
          }
      }
  }

getPaywallProducts(paywall) → getPaywallProducts(flow)

getPaywallProducts hiện nhận một AdaptyFlow được trả về bởi Adapty.getFlow:

- Adapty.getPaywallProducts(paywall) { result -> /* products */ }
+ Adapty.getPaywallProducts(flow) { result -> /* products */ }

Theo dõi lượt xem flow

logShowPaywall → logShowFlow

logShowPaywall được đổi tên thành logShowFlow và bây giờ nhận vào một AdaptyFlow thay vì AdaptyPaywall. Sự kiện vẫn được ghi lại dựa trên cùng một biến thể, vì vậy các chỉ số funnel và A/B test hiện tại vẫn hoạt động bình thường mà không cần thay đổi gì trên dashboard.

- Adapty.logShowPaywall(paywall)
+ Adapty.logShowFlow(flow)

Giống như trong v3, bạn không cần gọi phương thức này khi hiển thị các flow hoặc paywall được dựng bởi Flow Builder hoặc Paywall Builder — Adapty tự động theo dõi những lượt xem đó.

Hiển thị flow

getPaywallView / AdaptyPaywallView → getFlowView / AdaptyFlowView

Đổi tên phương thức factory và kiểu view, đồng thời truyền vào AdaptyUI.FlowConfiguration:

- val paywallView = AdaptyUI.getPaywallView(
-     activity,
-     viewConfiguration,
-     products,
-     eventListener,
- )
+ val flowView = AdaptyUI.getFlowView(
+     activity,
+     flowConfiguration,
+     products,
+     eventListener,
+ )

Nếu bạn tạo view trực tiếp, phương thức show cũng được đổi tên:

- val paywallView = AdaptyPaywallView(activity)
- paywallView.showPaywall(viewConfiguration, products, eventListener)
+ val flowView = AdaptyFlowView(activity)
+ flowView.showFlow(flowConfiguration, products, eventListener)

Trong XML layouts, cập nhật thẻ view:

- <com.adapty.ui.AdaptyPaywallView ... />
+ <com.adapty.ui.AdaptyFlowView ... />

Tham số tùy chọn personalizedOfferResolver đã bị xóa khỏi getFlowView / showFlow / AdaptyFlowScreen. Để chỉ định giá cá nhân hóa, hãy thiết lập theo từng sản phẩm thông qua onAwaitingPurchaseParams (AdaptyPurchaseParameters.Builder().withOfferPersonalized(true)). Một tham số tùy chọn mới customAssets cho phép bạn ghi đè hình ảnh và video tại runtime — xem Tùy chỉnh assets.

AdaptyPaywallScreen → AdaptyFlowScreen

Trong Jetpack Compose, đổi tên composable và cập nhật tham số cấu hình:

- AdaptyPaywallScreen(
-     viewConfiguration,
+ AdaptyFlowScreen(
+     flowConfiguration,
      products,
      eventListener,
  )

Xử lý sự kiện

Event listener được đổi tên từ AdaptyUiEventListener thành AdaptyFlowEventListener (và AdaptyUiDefaultEventListener thành AdaptyFlowDefaultEventListener). Hầu hết các tên phương thức không thay đổi; các callback vòng đời và rendering được đổi tên:

- class YourListener : AdaptyUiDefaultEventListener() {
+ class YourListener : AdaptyFlowDefaultEventListener() {

-     override fun onPaywallShown(context: Context) {}
-     override fun onPaywallClosed() {}
+     override fun onFlowShown(context: Context) {}
+     override fun onFlowClosed() {}

-     override fun onRenderingError(error: AdaptyError, context: Context) {}
+     override fun onError(error: AdaptyError, context: Context) {}
  }

Phần thân handler hiện có không cần thay đổi code — chỉ cần đổi tên kiểu và các override. onError sẽ kích hoạt cho cùng các lỗi render như onRenderingError đã làm, cộng thêm các lỗi runtime không liên quan đến mua hàng. Xem Xử lý sự kiện flow & paywall để biết danh sách đầy đủ các callback. v4 cũng bổ sung callback onBackPressed(context): Boolean, và giá trị mặc định của nó thay đổi cách nút back hệ thống hoạt động. Trước đây, nút back (hoặc cử chỉ vuốt back) sẽ được chuyển xuống activity hoặc fragment của bạn, thường là đóng paywall lại. Trong v4, implementation mặc định sẽ tiêu thụ sự kiện đó, vì vậy nút back hệ thống không còn tự đóng flow nữa — giống với iOS, nơi flow không thể bị đóng bằng cử chỉ hệ thống. Hãy cung cấp cho người dùng một cách thoát rõ ràng (nút Close hoặc action on_device_back), hoặc override onBackPressed trả về false để khôi phục hành vi cũ. Xem Nút back hệ thống để biết thêm chi tiết. Handler mua hàng mặc định cũng không còn tự động đóng màn hình nữa. Trong v3, onPurchaseFinished mặc định sẽ đóng paywall sau bất kỳ giao dịch mua hàng nào đã hoàn thành mà không phải do người dùng hủy (giao dịch thành công hoặc đang chờ xử lý). Trong v4, nó là no-op, vì vậy flow vẫn mở sau khi mua hàng cho đến khi bạn tự đóng nó — điều này cũng tương tự như iOS. Nếu bạn đang dựa vào tính năng tự động đóng đó, hãy tự đóng màn hình sau khi giao dịch mua hàng hoàn tất. Xem Mua hàng thành công, bị hủy hoặc đang chờ xử lý để xem ví dụ.

Mã định danh attribution và tích hợp

updateAttribution

Tham số source thay đổi từ String sang kiểu AdaptyAttributionSource mới, và attribution hiện là Map<String, Any> (cũng có thể dùng overload String dạng JSON). Sử dụng một trong các nguồn được định nghĩa sẵn:

- Adapty.updateAttribution(attribution, "appsflyer") { error -> /* handle the error */ }
+ Adapty.updateAttribution(attribution, AdaptyAttributionSource.APPSFLYER) { error -> /* handle the error */ }

Các nguồn được định sẵn: AdaptyAttributionSource.APPLE_ADS, .ADJUST, .APPSFLYER, .BRANCH, .TENJIN. Với bất kỳ nguồn nào khác, hãy tạo từ một chuỗi: AdaptyAttributionSource("your_source").

setIntegrationIdentifier

setIntegrationIdentifier(key, value) được thay thế bằng một phương thức nhận một hoặc nhiều giá trị AdaptyIntegrationIdentifier. Tạo từng identifier bằng convenience method thay vì truyền trực tiếp chuỗi key:

- Adapty.setIntegrationIdentifier("appsflyer_id", appsFlyerId) { error -> /* handle the error */ }
+ Adapty.setIntegrationIdentifier(AdaptyIntegrationIdentifier.appsflyerId(appsFlyerId)) { error -> /* handle the error */ }

Bạn có thể đặt nhiều identifier trong một lần gọi:

Adapty.setIntegrationIdentifier(
    listOf(
        AdaptyIntegrationIdentifier.appsflyerId(appsFlyerId),
        AdaptyIntegrationIdentifier.adjustDeviceId(adjustDeviceId),
    )
) { error -> /* handle the error */ }

Thay thế mỗi chuỗi key cũ bằng phương thức tiện lợi tương ứng:

Khóa v3Phương thức AdaptyIntegrationIdentifier v4
"adjust_device_id"adjustDeviceId(value)
"airbridge_device_id"airbridgeDeviceId(value)
"amplitude_user_id"amplitudeUserId(value)
"amplitude_device_id"amplitudeDeviceId(value)
"appmetrica_device_id"appmetricaDeviceId(value)
"appmetrica_profile_id"appmetricaProfileId(value)
"appsflyer_id"appsflyerId(value)
"branch_id"branchId(value)
"facebook_anonymous_id"facebookAnonymousId(value)
"firebase_app_instance_id"firebaseAppInstanceId(value)
"mixpanel_user_id"mixpanelUserId(value)
"one_signal_subscription_id"oneSignalSubscriptionId(value)
"one_signal_player_id"oneSignalPlayerId(value)
"posthog_distinct_user_id"posthogDistinctUserId(value)
"pushwoosh_hwid"pushwooshHWID(value)
"tenjin_analytics_installation_id"tenjinAnalyticsInstallationId(value)
Đối với khóa không có trong danh sách này, hãy tạo mã định danh trực tiếp từ Key tùy chỉnh: AdaptyIntegrationIdentifier(AdaptyIntegrationIdentifier.Key("custom"), customValue).