SDK 运行时对 SDK 启动新 activity 的方式施加了限制。这对通常依赖于启动单独 activity 来增强控制功能和用户体验的全屏广告格式来说是一个挑战。为解决此问题,SDK 运行时为沙盒化 activity 引入了一种新机制。
在 SDK 运行时环境中加载的 SDK 无法在其清单中直接定义 <activity>
标记或启动自己的 activity。而是引入了新的 intent 操作 START_SANDBOXED_ACTIVITY
。
虽然 SDK 也被禁止使用此操作启动 intent,但 SDK 可以请求客户端应用启动此 intent。然后,系统会创建一个平台定义的 activity 并将其传递给 SDK。此 activity 将在与 SDK 相同的进程中运行。
然后,SDK 可以使用此 activity 来实现和管理全屏广告体验。
平台提供的 activity 是一个标准的 android.app.Activity
,作为客户端应用任务的一部分启动。
在 SDK 运行时上创建 activity
您可以通过两种主要方法创建 activity:使用简化的 Jetpack activity 库或直接与平台 API 进行交互。
我们建议使用 activity 库,因为它们可以通过抽象底层复杂性来简化 activity 创建。
activity 库
activity 库具有多种优势:
- 提取注册 activity 处理脚本和与客户端应用共享其标识符的内部详细信息。
- 让应用开发者能够设置要满足的条件(谓词),从而更好地控制 SDK 在其应用中创建 activity 的方式。
- 为 SDK 创建一种统一的方式来定义启动 activity 的 API。
有三个 activity 库:核心库、客户端库和提供方库。
- 核心库提供客户端应用和提供方库使用的接口。
- 提供方库为 SDK 提供了用于启动 activity 的 API。
- 客户端库为客户端应用提供了用于创建 activity 启动器的 API,SDK 可以使用该启动器请求应用启动 activity。
这些库引入了以下 API:
SdkActivityLauncher
:借助 activity 启动器,SDK 可以处理从客户端应用启动 activity 的操作。客户端应用应创建启动器,并将其作为参数传递给启动 activity 的 SDK API。<T : Activity & LifecycleOwner> T.createSdkActivityLauncher(() -> Boolean )
:一个扩展函数,客户端应用可以从其 activity 调用该函数来创建启动器。SdkActivityLauncher.launchSdkActivity(IBinder)
:SDK 用于请求应用启动 activity 的方法。
使用 activity 库启动 activity 的流程如下所示:
- SDK 会向将启动 activity 的任何 API 添加类型为
SdkActivityLauncher
的参数。 - 客户端应用会对其某个 activity 调用
createSdkActivityLauncher
,以创建一个启动器,该启动器可在 API 调用时传递给 SDK。 - SDK 会调用
SdkSandboxControllerCompat.registerSdkSandboxActivityHandler(SdkSandboxActivityHandlerCompat)
并检索标识符令牌。 - SDK 会调用
launchSdkActivity
来启动 activity。
下图显示了使用 activity 库时的流程。
平台 API
该平台引入了以下 API,以便在 SDK 运行时内创建和管理沙盒化 activity:
SdkSandboxActivityHandler
:Activity Handler 用于在创建 activity 时通知 SDK,并由 SDK 注册。- 为了协助注册 activity 处理脚本,SDK 可以使用
SdkSandboxController
下的以下方法:.registerSdkSandboxActivityHandler(SdkSandboxActivityHandler)
:注册SdkSandboxActivityHandler
的实例,该实例会返回IBinder
标识符。.unregisterSdkSandboxActivityHandler(SdkSandboxActivityHandler)
:使用标识符取消注册已注册的SdkSandboxActivityHandler
实例。
SdkSandboxManager.startSdkSandboxActivity(Activity, IBinder)
:此方法从客户端应用调用,用于触发为 SDK 创建 activity。客户端应用必须将其选择的启动 activity 和 SDK 的 activity 处理程序标识符作为参数传递。
如需使用平台 API 启动 activity,SDK 必须遵循以下流程:
- SDK 使用提供的 API 注册 activity 处理脚本,并获取标识符。
- SDK 会与其客户端应用共享此标识符。
- 客户端应用调用该方法,以便使用平台 API
startSdkSandboxActivity(Activity, IBinder)
在 SDK 运行时内启动 activity,并将为此新 activity 选择的启动 activity 和 activity 处理程序的标识符作为参数传递。 - 平台会启动 activity,并通过 activity 处理程序 (
SdkSandboxActivityHandler.onActivityCreated(Activity)
) 中的回调通知 SDK。 - SDK 使用 activity 将广告填充到其中。
使用平台 API 后,SDK 需要负责在适当的时间通过其 API 与客户端应用共享 SdkSandboxActivityHandler 的标识符,并指导客户端应用如何使用该标识符。
在以下流程图中,示例 SDK 有一个方法 launchActivity(AppCallback)
,该方法需要回调(定义为 SDK API 的一部分)。SDK 使用此回调与客户端应用共享 activity 处理程序 (SdkSandboxActivityHandler
) 的标识符。
可见度
在 SDK 运行时内,集成到客户端应用的视图层次结构中的广告会使用边信道将 SDK 视图从 SDK 进程渲染到客户端应用的进程。
SDK 无法使用与它在 SDK 运行时外部使用的相同 View API 来确定是否要向用户展示广告,因为广告视图不会附加到应用窗口(可见度)。
与之相反,平台提供的 activity 在 SDK 运行时进程中原生运行,无需使用边信道,并允许 SDK 使用标准 Android Activity
和 View
API。
由于这些不同的实现方式,我们正在努力统一接口,以便在任何广告加载情境下检索可见度信号。
Lifecycle
通过 SdkSandboxActivityHandlerCompat.onActivityCreated(ActivityHolder)
传递给 SDK 的 ActivityHolder
会实现 LifecycleOwner
,并且可用于了解 Lifecycle.Event
。
返回导航
方法 ActivityHolder.getOnBackPressedDispatcher()
会返回 OnBackPressedDispatcher
,可用于注册 OnBackPressedCallback
实例以处理返回导航。