Documentation Index
Fetch the complete documentation index at: https://docs.kontext.so/llms.txt
Use this file to discover all available pages before exploring further.
这是 5 分钟接入的完整流程。开始之前,请确认你已经完成 安装。
1. 创建会话
入口是 KontextAds.createSession(context, options),它返回一个 Session——后续整个对话生命周期都通过它来操作。
import so.kontext.ads.KontextAds
import so.kontext.ads.model.Character
import so.kontext.ads.model.SessionOptions
val session = KontextAds.createSession(
context = applicationContext,
options = SessionOptions(
publisherToken = "<your-publisher-token>",
userId = "user-1234",
conversationId = "conv-5678",
character = Character(
id = "character-1234",
name = "John Doe",
avatarUrl = "https://example.com/avatar.png",
greeting = "Hello, how can I help you today?",
),
onEvent = { event ->
// 处理广告生命周期事件
android.util.Log.d("kontext", "${event.name} $event")
},
),
)
会话在其生命周期内会固定 publisherToken、userId 和 conversationId。当这些值变化时(例如用户开始新对话),请重建会话。
请传入 context.applicationContext 而不是 Activity 上下文——Session 的生命周期通常长于任意单个 Activity,SDK 会内部管理 WebView 资源。
2. 喂入对话消息
每条消息出现时都要 add 到会话中。用户消息会在后台触发一次防抖后的预加载;助手消息让 SDK 把匹配到的广告绑定到对应的广告位上。
import so.kontext.ads.model.Message
import so.kontext.ads.model.Role
session.addMessage(
Message(id = "msg-1", role = Role.USER, content = "Hello, how are you?"),
)
session.addMessage(
Message(id = "msg-2", role = Role.ASSISTANT, content = "I am good, thank you!"),
)
addMessage(...) 是同步返回的——它不是 suspend 函数。预加载的结果会稍后通过 onEvent 回调送达(Filled、NoFill、Error ……)——不会通过返回值返回。
3. 渲染广告
推荐使用 InlineAd composable。传入助手消息的 messageId 与 Session 即可,剩下的它都会处理:
import androidx.compose.runtime.Composable
import so.kontext.ads.ui.InlineAd
@Composable
fun ChatRow(message: ChatMessage, session: Session) {
MessageBubble(message)
if (message.role == Role.ASSISTANT) {
InlineAd(messageId = message.id, session = session)
}
}
InlineAd 在重组之间是幂等的——它内部调用 session.createAd(messageId),对同一个 (messageId, code, theme) 已存在的 Ad 直接复用。把广告滚出可视区再滚回来不会重建 iframe。
如果你的应用没有使用 Compose,请改用 InlineAdView——见 实践指南 → View 互操作。
4. 释放资源
对话结束或页面关闭时调用 session.destroy()。该方法是幂等的,且是取消待处理网络请求、释放 WebView 资源的必要操作。
在 Compose 中:
DisposableEffect(session) {
onDispose { session.close() } // 等价于 session.destroy()
}
订阅事件
AdEvent 既可以通过 SessionOptions 里的 onEvent 回调拿到,也可以通过 Session.events Flow 拿到——任选其一。两者会在主线程上送达相同的事件。
onEvent 回调
val session = KontextAds.createSession(
context = applicationContext,
options = SessionOptions(
publisherToken = "...",
userId = "...",
conversationId = "...",
onEvent = { event ->
when (event) {
is AdEvent.Filled -> println("ad filled: ${event.bidId} revenue=${event.revenue}")
is AdEvent.Clicked -> println("clicked: ${event.url}")
else -> Unit
}
},
),
)
Flow
import kotlinx.coroutines.flow.collect
lifecycleScope.launch {
session.events.collect { event ->
println("event: ${event.name}")
}
}
完整事件列表见 API 参考。