feat: 适配微信 CPM 小游戏的曝光上报逻辑

This commit is contained in:
chenjuntao
2025-01-02 14:39:04 +08:00
parent 3cca6b5cb5
commit bf30aef686
3 changed files with 31 additions and 19 deletions

View File

@ -1,5 +1,6 @@
package com.gh.common.exposure
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.IExposureStateChangeListener
import com.gh.gamecenter.feature.exposure.RecyclerViewExposureHelper
@ -14,17 +15,28 @@ class DefaultExposureStateChangeListener : IExposureStateChangeListener {
) {
val exposureStatus = if (inExposure) "曝光中" else "结束曝光"
val isCPMExposureEvent = exposureEvent.payload.miniGameType == Constants.WECHAT_MINI_GAME_CPM
Utils.log(
RecyclerViewExposureHelper.TAG,
"onExposureStateChange: 名称 ${exposureEvent.payload.gameName} 位置 $position, $exposureStatus"
)
if (isCPMExposureEvent && inExposure) {
Utils.log(
RecyclerViewExposureHelper.TAG,
"上报 CPM 曝光 ${exposureEvent.payload.gameName} ${exposureEvent.id}"
)
ExposureManager.logCPM(exposureEvent)
}
if (!inExposure
&& System.currentTimeMillis() - exposureEvent.timeInMillisecond > RecyclerViewExposureHelper.VALID_EXPOSURE_THRESHOLD
&& System.currentTimeMillis() - exposureEvent.timeInMillisecond > DEFAULT_VALID_EXPOSURE_THRESHOLD
) {
Utils.log(
RecyclerViewExposureHelper.TAG,
"上报列表曝光 ${exposureEvent.payload.gameName} ${exposureEvent.id}曝光时长为 ${System.currentTimeMillis() - exposureEvent.timeInMillisecond}ms"
"上报曝光 ${exposureEvent.payload.gameName} ${exposureEvent.id}是否为 CPM 小游戏 -> ${isCPMExposureEvent}" +
"曝光时长为 ${System.currentTimeMillis() - exposureEvent.timeInMillisecond}ms"
)
// 标记当前 ExposureEvent 已经被使用过
@ -33,4 +45,9 @@ class DefaultExposureStateChangeListener : IExposureStateChangeListener {
}
}
companion object {
// 默认曝光有效时长
const val DEFAULT_VALID_EXPOSURE_THRESHOLD = 1000L
}
}

View File

@ -90,6 +90,15 @@ object ExposureManager {
}
}
/**
* Log a wechat mini game cpm collection of exposure event.
*/
fun logCPM(event: ExposureEvent) {
AppExecutor.logExecutor.execute {
WGameSubjectCPMListReportHelper.reportExposure(event)
}
}
/**
* @param forcedUpload Ignore all restrictions.
*/

View File

@ -55,7 +55,7 @@ import java.util.concurrent.TimeUnit
class RecyclerViewExposureHelper(
private val recyclerView: RecyclerView,
private val lifecycleOwner: LifecycleOwner?,
private val exposureStateChangeListener: IExposureStateChangeListener
private val exposureStateChangeListener: IExposureStateChangeListener,
) : RecyclerView.OnScrollListener() {
// 处于曝光中的Item数据集合
private val inExposureDataList = ArrayList<InExposureData<ExposureEvent>>()
@ -223,14 +223,11 @@ class RecyclerViewExposureHelper(
visiblePositionExposureEvent.data.refreshTime()
// 当前可见位置不在曝光中集合,代表是从不可见变为可见,那么此 position 开始曝光
inExposureDataList.add(visiblePositionExposureEvent)
invokeExposureStateChange(
visiblePositionExposureEvent.data,
visiblePosition,
true
)
invokeExposureStateChange(visiblePositionExposureEvent.data, visiblePosition, true)
}
}
}
inExposureDataList.filter { inExposureData ->
// 过滤出处于曝光中的 position 在当前扫描的时候不再处于可见位了
inExposureData !in currentVisibleExposureEventList
@ -300,12 +297,6 @@ class RecyclerViewExposureHelper(
// 获取 position 绑定的曝光数据
private fun getExposureDataListByPosition(position: Int): List<InExposureData<ExposureEvent>>? {
// // 获取 PageLevel 信息 (覆写在 ExposureEvent.create 时填充的 PageLevel避免因为线程不一样导致的数据异常
// val pageLevelString = if ((recyclerView.context) is IPageLevelProvider) {
// (recyclerView.context as IPageLevelProvider).getPageLevel().toFormatedString()
// } else {
// ""
// }
val provideExposureDataViewList =
findAllExposureProviderAndAddOnScrollListener(recyclerView.layoutManager?.findViewByPosition(position))
if (provideExposureDataViewList.isNullOrEmpty()) {
@ -323,8 +314,6 @@ class RecyclerViewExposureHelper(
val exposureEventList = it.provideExposureDataList()
if (exposureEventList != null) {
for (exposureEvent in exposureEventList) {
// // 附加 PageLevel 信息
// exposureEvent.payload.pageLevel = pageLevelString
// 添加到队列里
inExposureDataListResult.add(InExposureData(exposureEvent, position))
}
@ -333,8 +322,6 @@ class RecyclerViewExposureHelper(
// 若实现了 IExposureProvider 接口,则调用 provideExposureData 方法获取曝光数据
val exposureEvent = it.provideExposureData()
if (exposureEvent != null) {
// // 附加 PageLevel 信息
// exposureEvent.payload.pageLevel = pageLevelString
// 添加到队列里
inExposureDataListResult.add(InExposureData(exposureEvent, position))
}
@ -431,7 +418,6 @@ class RecyclerViewExposureHelper(
const val TAG = "RecyclerViewExposureHelper"
const val VALID_VISIBLE_RECT_PERCENTAGE = 0.7F
const val VALID_EXPOSURE_THRESHOLD = 1000L
const val SAMPLE_RATE = 100L
}
}