Compare commits

...

40 Commits

Author SHA1 Message Date
dbf37e03eb feat: 移除开屏广告
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-11-08 13:42:08 +08:00
60ca040c94 feat: 移除开屏广告 2024-11-08 12:13:29 +08:00
e688ca1899 feat: 请求头添加包名
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-11-08 11:49:51 +08:00
ac19644333 feat: 更改包名,屏蔽部分模块
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-11-08 11:41:01 +08:00
2c5471d524 Merge branch 'fix/sentry-418688' into 'release'
fix: Sentry-418688 SearchActivity回调onSavedInstance后,调用FragmentManager的popBackStack引发的崩溃问题

See merge request halo/android/assistant-android!1968
2024-11-07 13:42:39 +08:00
cf527db60e fix: Sentry-418688 SearchActivity回调onSavedInstance后,调用FragmentManager的popBackStack引发的崩溃问题 2024-11-07 13:42:39 +08:00
ab66621751 chore: 版本更新至 5.38.4 2024-11-04 17:59:19 +08:00
af262c624a Merge branch 'feat/GHZSCY-6904' into 'release'
feat:【光环助手】搜索bug https://jira.shanqu.cc/browse/GHZSCY-6904

See merge request halo/android/assistant-android!1966
2024-11-04 16:28:48 +08:00
d2813ecbda feat:【光环助手】搜索bug https://jira.shanqu.cc/browse/GHZSCY-6904 2024-11-04 16:28:48 +08:00
0ea932e36d Merge branch 'hotfix/v5.38.3-1113/aidl_npe_crash' into 'release'
fix: 尝试修复aidl获取对象为空导致NPE。https://sentry.shanqu.cc/organizations/lightgame/issues/399032/?project=22

See merge request halo/android/assistant-android!1965
2024-11-04 14:35:50 +08:00
68151ed6f9 fix: 尝试修复aidl获取对象为空导致NPE。https://sentry.shanqu.cc/organizations/lightgame/issues/399032/?project=22 2024-11-04 14:34:53 +08:00
e6d2361008 Merge branch 'hotfix/v5.38.3-1113/concurrent_crash' into 'release'
fix: 修复部分 5.38.3 的线上闪退问题

See merge request halo/android/assistant-android!1964
2024-11-04 13:43:00 +08:00
570b777c8e Merge branch 'hotfix/v5.38.3-1113/crashes' into 'release'
修复Sentry上的闪退问题

See merge request halo/android/assistant-android!1963
2024-11-04 11:50:45 +08:00
0e557b2246 fix: 修复启动游戏时多线程操作闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/406116/?project=22
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-11-04 11:50:41 +08:00
f155440814 fix: 修复下载 exception 异常为空时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/416995/?project=22
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-11-04 11:49:57 +08:00
62ba9fc7bf fix: 修复游戏详情评论页面重建时出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/379887/events/aa3bbc5102ed4a57b66c3c7fed5d7b34/?project=22 2024-11-04 11:26:00 +08:00
4637aa8808 fix: 修复下拉推送偶发的空指针闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/418647/events/1d426e3ceda5477c9afbc6712d335b22/?project=22 2024-11-04 11:24:08 +08:00
81998e3aad Merge branch 'fix/sentry-418235' into 'release'
fix: 畅玩启动提示弹窗游戏列表数组越界问题 https://sentry.shanqu.cc/organizations/lightgame/issues/418304/?project=22

See merge request halo/android/assistant-android!1962
2024-11-01 16:15:14 +08:00
82a8aa03ba fix: 畅玩启动提示弹窗游戏列表数组越界问题 https://sentry.shanqu.cc/organizations/lightgame/issues/418304/?project=22 2024-11-01 16:13:05 +08:00
c876711578 chore: 版本更新至 5.38.3 2024-11-01 09:37:56 +08:00
41fcee7f4d Merge branch 'feat/GHZSCY-6876' into 'release'
Resolve GHZSCY-6876 "Feat/"

See merge request halo/android/assistant-android!1961
2024-11-01 09:37:04 +08:00
0ccbc4d581 feat:一键登录SDK更新—客户端 https://jira.shanqu.cc/browse/GHZSCY-6876 2024-11-01 09:37:04 +08:00
f05fc73e3a Merge branch 'hotfix/v5.38.2-1112/binding_crash' into 'release'
fix: 修复 SearchToolbarTabWrapperFragment 页面 binding bindView 时的闪退问题...

See merge request halo/android/assistant-android!1959
2024-10-31 10:31:26 +08:00
ca3c545f26 Merge branch 'hotfix/v5.38.1-1111/GHZSCY-6855' into 'release'
fix: 神策下载按钮点击事件相关字段上报异常排查 https://jira.shanqu.cc/browse/GHZSCY-6855

See merge request halo/android/assistant-android!1958
2024-10-31 10:28:28 +08:00
226539328e fix: 修复 SearchToolbarTabWrapperFragment 页面 binding bindView 时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/418028/?project=22
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-10-31 10:13:36 +08:00
bb7db78b0c Merge branch 'hotfix/v5.38.2-1112/va_launch_crash' into 'release'
fix: 修复点击畅玩启动插屏广告出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/418073/?project=22

See merge request halo/android/assistant-android!1957
2024-10-31 09:47:03 +08:00
ede62c5363 fix: 修复点击畅玩启动插屏广告出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/418073/?project=22 2024-10-31 09:44:40 +08:00
12bb6824ea Merge branch 'fix/wx_subscribe_msg_response_handle' into 'release'
fix: 修复微信开服提醒消息回调处理异常问题

See merge request halo/android/assistant-android!1955
2024-10-30 14:44:16 +08:00
15c0950754 fix: 修复微信开服提醒消息回调处理异常问题 2024-10-30 14:42:55 +08:00
f86b7fe12a Merge branch 'hotfix/v5.38.2-1112/emulator_auth' into 'release'
fix: 修复雷电模拟器网游插件登录后跳转回游戏出现的闪退问题

See merge request halo/android/assistant-android!1954
2024-10-30 14:31:22 +08:00
d12cdbd34b fix: 修复雷电模拟器网游插件登录后跳转回游戏出现的闪退问题 2024-10-30 14:31:22 +08:00
8436d4eda3 Merge branch 'hotfix/v5.38.2-1112/multi_tab_loading' into 'release'
fix: 修复多tab导航页loading动画没有显示的问题

See merge request halo/android/assistant-android!1952
2024-10-29 13:51:10 +08:00
be832037a7 fix: 修复多tab导航页loading动画没有显示的问题 2024-10-29 13:41:36 +08:00
b620257825 Merge branch 'hotfix/v5.38.2-1112/GHZSCY-6859' into 'release'
fix:【光环助手】深色模式切换显示问题 https://jira.shanqu.cc/browse/GHZSCY-6859

See merge request halo/android/assistant-android!1951
2024-10-28 17:13:30 +08:00
6c88cace99 fix:【光环助手】深色模式切换显示问题 https://jira.shanqu.cc/browse/GHZSCY-6859 2024-10-28 17:11:23 +08:00
f875fa1b14 Merge branch 'feat/GHZSCY-6828' into 'release'
feat: CPM微信小游戏一期优化—客户端 https://jira.shanqu.cc/browse/GHZSCY-6828

See merge request halo/android/assistant-android!1948
2024-10-28 14:54:49 +08:00
8076c3a70a feat: CPM微信小游戏一期优化—客户端 https://jira.shanqu.cc/browse/GHZSCY-6828 2024-10-28 14:54:49 +08:00
bebab317a3 fix: 神策下载按钮点击事件相关字段上报异常排查 https://jira.shanqu.cc/browse/GHZSCY-6855 2024-10-28 14:38:06 +08:00
c450ca570d Merge branch 'hotfix/v5.38.2-1112/GHZSCY-6854' into 'release'
fix:【光环助手】切换深色/普通模式tab字体颜色变化问题 https://jira.shanqu.cc/browse/GHZSCY-6854

See merge request halo/android/assistant-android!1950
2024-10-28 10:23:56 +08:00
d239b0755f fix:【光环助手】切换深色/普通模式tab字体颜色变化问题 https://jira.shanqu.cc/browse/GHZSCY-6854 2024-10-28 10:20:53 +08:00
30 changed files with 318 additions and 150 deletions

View File

@ -663,7 +663,8 @@
android:name=".authorization.AuthorizationActivity"
android:exported="true"
android:launchMode="singleTask"
android:screenOrientation="portrait">
android:screenOrientation="portrait"
android:taskAffinity=".auth">
<intent-filter>
<data android:scheme="ghzhushou_authorization" />
<category android:name="android.intent.category.DEFAULT" />

View File

@ -37,16 +37,16 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
GlobalActivityManager.currentActivity = activity
GlobalActivityManager.activityCount ++
if (GlobalActivityManager.activityCount == 1 && isFromBackgroundToForeground) {
if (AdDelegateHelper.shouldShowStartUpAd(true)
&& !HaloApp.getInstance().isDisableSplashAdTemporarily
&& activity !is SplashScreenActivity
&& activity !is SkipActivity
&& activity !is AuthorizationActivity
&& activity !is SplashAdActivity
&& !isSuggestionActivity(activity)
) {
activity.startActivity(SplashAdActivity.getIntent(activity))
}
// if (AdDelegateHelper.shouldShowStartUpAd(true)
// && !HaloApp.getInstance().isDisableSplashAdTemporarily
// && activity !is SplashScreenActivity
// && activity !is SkipActivity
// && activity !is AuthorizationActivity
// && activity !is SplashAdActivity
// && !isSuggestionActivity(activity)
// ) {
// activity.startActivity(SplashAdActivity.getIntent(activity))
// }
isFromBackgroundToForeground = false
}

View File

@ -0,0 +1,74 @@
package com.gh.common.fragment
import androidx.fragment.app.FragmentManager
import java.lang.reflect.Field
fun FragmentManager.popBackStackAllowStateLoss() {
popBackStackAllowStateLoss(-1, 0)
}
fun FragmentManager.popBackStackAllowStateLoss(id: Int, flags: Int) {
if (!isStateSaved) {
popBackStack(id, flags)
} else {
hook { popBackStack(id, flags) }
}
}
fun FragmentManager.popBackStackAllowStateLoss(name: String?, flags: Int) {
if (!isStateSaved) {
popBackStack(name, flags)
} else {
hook { popBackStack(name, flags) }
}
}
fun FragmentManager.popBackStackImmediateAllowStateLoss() = popBackStackAllowStateLoss(-1, 0)
fun FragmentManager.popBackStackImmediateAllowStateLoss(id: Int, flags: Int) =
if (!isStateSaved) {
popBackStackImmediate(id, flags)
} else {
hook { popBackStackImmediate(id, flags) }
}
fun FragmentManager.popBackStackImmediateAllowStateLoss(name: String?, flags: Int): Boolean =
if (!isStateSaved) {
popBackStackImmediate(name, flags)
} else {
hook { popBackStackImmediate(name, flags) }
}
/**
* 通过反射将FragmentManager的mStateSaved和mStopped设为false否则Activity在回调onSavedInstance以后
* 调用Fragment的popBackStack和popBackStackImmediate方法会触发“java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState”的异常。
* @see <a href="https://sentry.shanqu.cc/organizations/lightgame/issues/418688/?project=22">Sentry-418688</a>
*/
private fun <T> FragmentManager.hook(callback: FragmentManager.() -> T): T {
val mStateSavedField = getField(this::class.java,"mStateSaved")
val stateSaved = mStateSavedField.get(this);
mStateSavedField.set(this, false)
val mStoppedField = getField(this::class.java,"mStopped")
val stopped = mStateSavedField.get(this);
mStoppedField.set(this, false)
val result = callback.invoke(this)
mStateSavedField.set(this, stateSaved)
mStoppedField.set(this, stopped)
return result
}
@Throws(NoSuchFieldException::class)
private fun getField(clazz: Class<*>, name: String): Field {
var cls: Class<*>? = clazz
while (cls != null) {
try {
val declaredField = cls.getDeclaredField(name)
declaredField.isAccessible = true
return declaredField
} catch (e: NoSuchFieldException) {
e.printStackTrace()
}
cls = cls.superclass
}
throw NoSuchFieldException()
}

View File

@ -124,7 +124,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
"game_name", gameName,
"game_type", gameTypeInChinese,
"download_status", downloadStatusInChinese,
"button_name", downloadButton.text,
"button_name", text,
"game_schema_type", gameSchemaType,
"download_type", downloadType,
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,

View File

@ -139,6 +139,7 @@ public class DetailDownloadUtils {
// 游戏包含多 APK 的情况
viewHolder.getMultiVersionDownloadTv().setText("选择下载你的版本" + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord));
viewHolder.getMultiVersionDownloadTv().setVisibility(View.VISIBLE);
viewHolder.getDownloadPb().setTag(com.gh.gamecenter.feature.R.string.download, viewHolder.getMultiVersionDownloadTv().getText());
viewHolder.getDownloadPb().setText("");
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);

View File

@ -7,7 +7,7 @@ import com.gh.gamecenter.common.utils.isVGameDownloadInDualDownloadMode
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.manager.PackagesManager
import com.gh.vspace.VHelper
object PackageLauncher {
@ -91,7 +91,7 @@ object PackageLauncher {
val gameInstall = if (gameEntity != null) {
GameInstall.transformGameInstall(gameEntity, packageName)
} else {
PackageRepository.gameInstalled.find { it.packageName == packageName }
PackagesManager.getInstalledList().find { it.packageName == packageName }
}
if (gameInstall != null) {

View File

@ -1045,6 +1045,7 @@ public class MainActivity extends BaseActivity {
blackList.add(R.id.historyTv);
blackList.add(R.id.myCollectionTv);
blackList.add(R.id.searchTv);
blackList.add(R.id.subject_tab);
updateStaticView(view, blackList);
View communityHomeWrapper = view.findViewById(R.id.communityHomeContainer);

View File

@ -15,6 +15,7 @@ import androidx.core.widget.doAfterTextChanged
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import com.gh.common.fragment.popBackStackAllowStateLoss
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.LogUtils
import com.gh.gamecenter.DisplayType.*
@ -381,7 +382,7 @@ open class SearchActivity : BaseActivity() {
}
protected fun popBackToFragment(tag: String) {
supportFragmentManager.popBackStack(tag, 0)
supportFragmentManager.popBackStackAllowStateLoss(tag, 0)
}
@Subscribe(threadMode = ThreadMode.MAIN)

View File

@ -242,10 +242,10 @@ class AuthorizationActivity : ToolBarActivity() {
VHelper.launch(this, gamePkg, ignoreGApps = true, showLoading = showLoading)
return
}
val remotePkgName = this.mRemotePkgName
if (remotePkgName != null) {// 跳转回其他授权app
startActivity(packageManager.getLaunchIntentForPackage(remotePkgName))
}
// val remotePkgName = this.mRemotePkgName
// if (remotePkgName != null) {// 跳转回其他授权app
// startActivity(packageManager.getLaunchIntentForPackage(remotePkgName))
// }
}
override fun onBackPressed() {

View File

@ -18,7 +18,13 @@ data class SearchSubjectEntity(
@SerializedName("ad_icon_active")
val adIconActive: Boolean = false,
// 本地字段标记是否为微信小游戏CPM专题
var isWGameSubjectCPM: Boolean = false
var isWGameSubjectCPM: Boolean = false,
val type: String = ""
) : Parcelable {
companion object {
const val TYPE_WECHAT_GAME_CPM_COLUMN = "wechat_game_cpm_column"
}
fun getFilterGame() = RegionSettingHelper.filterGame(games)
}

View File

@ -25,10 +25,10 @@ import com.gh.gamecenter.common.utils.toPx
import com.gh.gamecenter.core.iinterface.IScrollable
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.core.utils.SpanBuilder
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.eventbus.EBStar
import com.gh.gamecenter.eventbus.EBTypeChange
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.halo.assistant.HaloApp
import org.greenrobot.eventbus.EventBus
@ -60,7 +60,7 @@ class RatingFragment : LazyListFragment<RatingComment, RatingViewModel>(), IScro
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RATING_EDIT_REQUEST && resultCode == Activity.RESULT_OK) {
mListViewModel.initData()
mListViewModel?.initData()
} else if (
(requestCode == RATING_REPLAY_REQUEST || requestCode == RATING_PATCH_REQUEST)
&& resultCode == Activity.RESULT_OK

View File

@ -806,7 +806,7 @@ class CustomPageRepository private constructor(
fun loadChangeSubjectGame(subjectEntity: SubjectEntity): Observable<List<GameEntity>> =
if (subjectEntity.isWechatColumnCPM) {// 微信小游戏CPM专题的“换一批”接口
wGameSubjectCPMRemoteDataSource.getRecommendCPMList(2, 10).toObservable()
wGameSubjectCPMRemoteDataSource.getEditorRecommendCPMList(2, 10).toObservable()
} else {
remoteDataSource.loadChangeSubjectGame(subjectEntity)
}

View File

@ -40,7 +40,7 @@ class CustomGameGallerySlideViewHolder(
override fun bindView(item: CustomPageItem) {
super.bindView(item)
if (item is CustomSubjectItem) {
binding.cardView.setCardBackgroundColor(com.gh.gamecenter.common.R.color.ui_container_1.toColor(binding.root.context))
if (item.data == cachedSubject) return
cachedSubject = item.data
@ -77,7 +77,6 @@ class CustomGameGallerySlideViewHolder(
val gameList = item.data.data ?: emptyList()
(recyclerView.adapter as? GameGallerySlideAdapter)?.submitList(gameList)
}
binding.cardView.setCardBackgroundColor(com.gh.gamecenter.common.R.color.text_FAFAFA.toColor(binding.root.context))
}

View File

@ -26,6 +26,6 @@ class MiniGameSearchResultRepository(
}
override fun getWGameCPMGameList(): Single<MutableList<GameEntity>> {
return mWGameSubjectCPMDataSource.getRecommendCPMList(1)
return mWGameSubjectCPMDataSource.getUserRecommendCPMList()
}
}

View File

@ -11,7 +11,7 @@ class WGameSubjectCPMListRepository(
) : ISubjectListRepository {
override fun getColumn(column_id: String?, page: Int, sort: String?, order: String?): Single<MutableList<GameEntity>> {
return dataSource.getRecommendCPMList(page)
return dataSource.getEditorRecommendCPMList(page)
}
override fun getColumnSettings(column_id: String?): Observable<SubjectSettingEntity> {

View File

@ -14,7 +14,50 @@ class WGameSubjectCPMRemoteDataSource(
private val api: WGameCPMApiService = RetrofitManager.getInstance().wGameCPMApi
) {
fun getRecommendCPMList(page: Int, pageSize: Int = 10): Single<MutableList<GameEntity>> {
fun getEditorRecommendCPMList(page: Int, pageSize: Int = 10): Single<MutableList<GameEntity>> {
val meta = MetaUtil.getMeta()
val request = mapOf(
"head" to mapOf(
"busiAppid" to Config.WGAME_CPM_BUSIAPPID,
"oaid" to (meta.oaid ?: ""),
"manufacturer" to (meta.manufacturer ?: ""),
"mode" to (meta.model ?: ""),
"androidId" to (MetaUtil.getAndroidId()),
"imei" to (MetaUtil.getIMEI())
),
"body" to mapOf(
"page" to page - 1,
"pageSize" to pageSize,
)
)
return api.getEditorRecommendList(request.toRequestBody())
.map {
if (it.ret == 0) {
it.appInfoList.map { info ->
GameEntity(
mName = info.appName,
mIcon = info.logo,
mBrief = info.briefIntro,
miniGameUid = info.appID,
miniGameAppId = info.userName,
miniGameType = Constants.WECHAT_MINI_GAME_CPM,
miniGameAppStatus = 2,
miniGameAppPath = info.wechatAppPath,
miniGameExtData = info.extData,
miniGameRecommendId = info.recommendID,
mTagStyle = arrayListOf(
TagStyleEntity(name = info.categoryName),
TagStyleEntity(name = info.subcategoryName)
)
)
}.toMutableList()
} else {
mutableListOf()
}
}
}
fun getUserRecommendCPMList(page: Int = 1, pageSize: Int = 10): Single<MutableList<GameEntity>> {
val meta = MetaUtil.getMeta()
val request = mapOf(
"head" to mapOf(

View File

@ -107,6 +107,7 @@ class SearchGameResultAdapter(
return when {
oldItem?.subject != null && newItem?.subject != null -> {
oldItem.subject.columnId == newItem.subject.columnId
&& oldItem.subject.games == newItem.subject.games
}
oldItem?.game != null && newItem?.game != null -> {
@ -121,6 +122,7 @@ class SearchGameResultAdapter(
return when {
oldItem?.subject != null && newItem?.subject != null -> {
oldItem.subject.columnId == newItem.subject.columnId
&& oldItem.subject.games == newItem.subject.games
}
oldItem?.game != null && newItem?.game != null -> {
@ -169,39 +171,50 @@ class SearchGameResultAdapter(
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is SearchSubjectItemViewHolder -> {
holder.binding.run {
when {
position == 0 -> topDivider.visibility = View.GONE
position > 0 -> {
val gameEntity = mEntityList[position - 1].game
if (gameEntity != null) {
val isShowTag = gameEntity.contentTag != null
&& (gameEntity.contentTag!!.custom.isNotEmpty()
|| gameEntity.contentTag!!.zone.link.isNotEmpty()
|| gameEntity.contentTag!!.isLibaoExists
|| gameEntity.contentTag!!.server)
val isShowTagByMirror =
if (gameEntity.shouldUseMirrorInfo()) isShowTag && gameEntity.obtainMirrorData()?.contentTagStatus == "on" else isShowTag
if (isShowTagByMirror) {
topDivider.visibility = View.GONE
val itemData = mEntityList[position]
if (itemData.subject == null || itemData.subject.games.isEmpty()) {
holder.binding.topDivider.visibility = View.GONE
holder.binding.bottomDivider.visibility = View.GONE
holder.binding.headContainer.root.visibility = View.GONE
holder.binding.subjectRv.visibility = View.GONE
} else {
holder.binding.headContainer.root.visibility = View.VISIBLE
holder.binding.subjectRv.visibility = View.VISIBLE
holder.binding.run {
when {
position == 0 -> topDivider.visibility = View.GONE
position > 0 -> {
val gameEntity = mEntityList[position - 1].game
if (gameEntity != null) {
val isShowTag = gameEntity.contentTag != null
&& (gameEntity.contentTag!!.custom.isNotEmpty()
|| gameEntity.contentTag!!.zone.link.isNotEmpty()
|| gameEntity.contentTag!!.isLibaoExists
|| gameEntity.contentTag!!.server)
val isShowTagByMirror =
if (gameEntity.shouldUseMirrorInfo()) isShowTag && gameEntity.obtainMirrorData()?.contentTagStatus == "on" else isShowTag
if (isShowTagByMirror) {
topDivider.visibility = View.GONE
} else {
topDivider.visibility = View.VISIBLE
}
} else {
topDivider.visibility = View.VISIBLE
topDivider.visibility = View.GONE
}
} else {
topDivider.visibility = View.GONE
}
}
bottomDivider.visibility = View.VISIBLE
}
bottomDivider.visibility = View.VISIBLE
holder.bindSubjectItem(
mContext,
itemData,
SearchType.fromString(type).toChinese(),
key,
dao,
sourceEntrance = sourceEntrance
)
}
holder.bindSubjectItem(
mContext,
mEntityList[position],
SearchType.fromString(type).toChinese(),
key,
dao,
sourceEntrance = sourceEntrance
)
}
is SearchGameFirstItemViewHolder -> {

View File

@ -36,6 +36,6 @@ class SearchGameResultRepository(
}
override fun getWGameCPMGameList(): Single<MutableList<GameEntity>> {
return mWGameSubjectCPMDataSource.getRecommendCPMList(1)
return mWGameSubjectCPMDataSource.getUserRecommendCPMList()
}
}

View File

@ -76,40 +76,39 @@ class SearchGameResultViewModel(
refreshWrongInstallStatus()
repository.getSearchSubject(mSearchKey, mPage)
.map { dataList ->
mSearchSubjects.addAll(dataList)
var cpmSearchSubject: SearchSubjectEntity? = null
mSearchSubjects.forEach {
// 微信小游戏CPM专题需要等搜索广告位插入完成后再插入
if (it.location == WGAME_CPM_SUBJECT_POSITION) {
cpmSearchSubject = it.apply { isWGameSubjectCPM = true }
} else {
val item = SearchItemData(subject = it)
if (it.location <= 0 || it.location > itemDataList.size) {
itemDataList.add(item)
} else {
itemDataList.add(it.location - 1, item)
}
}
}
cpmSearchSubject to dataList
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ result ->
.subscribe({ mutableList ->
val cpmSearchSubjects = mutableListOf<SearchSubjectEntity>()
mSearchSubjects.addAll(mutableList)
mSearchSubjects.forEach {
if (it.type == SearchSubjectEntity.TYPE_WECHAT_GAME_CPM_COLUMN) {
cpmSearchSubjects.add(it.apply { isWGameSubjectCPM = true })
}
val item = SearchItemData(subject = it)
if (it.location <= 0 || it.location > itemDataList.size) {
itemDataList.add(item)
} else {
itemDataList.add(it.location - 1, item)
}
}
// 处理初始化列表且游戏列表size为0的情况
handleLoadStatusWhenGameListIsEmpty(list, itemDataList)
if (mIsManuallySearch) {
if (mSearchKey == AdDelegateHelper.gameSearchKeyword) {
updateAdConfigAndDecorateList(itemDataList, list, result.first)
updateAdConfigAndDecorateList(itemDataList, list)
} else {
AdDelegateHelper.requestAdConfig(false, mSearchKey ?: "") {
updateAdConfigAndDecorateList(itemDataList, list, result.first)
updateAdConfigAndDecorateList(itemDataList, list)
}
}
} else {
decorateWithWGameSubjectCPM(itemDataList, list, result.first)
postResultList(itemDataList, list)
}
if (cpmSearchSubjects.isNotEmpty()) {
decorateListWithWGameCPM(cpmSearchSubjects, itemDataList, list)
}
}, {
it.printStackTrace()
@ -118,12 +117,50 @@ class SearchGameResultViewModel(
})
}
/**
* 请求微信小游戏CPM接口获取专题游戏数据并插入对应的专题项中相关需求如下
* @see <a href="https://jira.shanqu.cc/browse/GHZSCY-6710">【光环助手】CPM微信小游戏API接入工作</a>
* @see <a href="https://jira.shanqu.cc/browse/GHZSCY-6827">【光环助手】CPM微信小游戏一期优化</a>
*/
@SuppressLint("CheckResult")
private fun updateAdConfigAndDecorateList(
private fun decorateListWithWGameCPM(
subjects: List<SearchSubjectEntity>,
itemDataList: ArrayList<SearchItemData>,
list: MutableList<GameEntity>,
cpmSubjectEntity: SearchSubjectEntity?
list: MutableList<GameEntity>
) {
val subjectList = subjects.filterNot {
it.games.isNotEmpty()
}
if (subjectList.isEmpty()) return
val subjectSingleList = subjectList.map { subject ->
repository.getWGameCPMGameList()
.onErrorReturnItem(mutableListOf())
.map { subject.columnId to it }
}
Single.zip(subjectSingleList) { it.map { item -> item as Pair<String, MutableList<GameEntity>> } }
.map { dataList ->
for (index in itemDataList.indices) {
val itemData = itemDataList[index]
val subject = itemData.subject ?: continue
if (subject.games.isNotEmpty()) continue
val pair = dataList.firstOrNull { data ->
data.first == subject.columnId
} ?: continue
val newItemData = SearchItemData(
subject = subject.copy(games = pair.second)
)
itemDataList[index] = newItemData
}
itemDataList
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ dataList -> postResultList(dataList, list) }, {})
}
@SuppressLint("CheckResult")
private fun updateAdConfigAndDecorateList(itemDataList: ArrayList<SearchItemData>, list: MutableList<GameEntity>) {
mGameSearchAdList =
AdDelegateHelper.getGameSearchAdList().filter { AdDelegateHelper.shouldShowGameSearchAd(it) }.toArrayList()
.apply { sortBy { it.position } }
@ -137,7 +174,6 @@ class SearchGameResultViewModel(
mAdPositionSet = adPositionSet
if (adPositionSet.isNotEmpty()) {
val decoratedItemDataList = ArrayList(itemDataList)
val ownerAdList = arrayListOf<AdConfig>()
val thirdPartyAdList = arrayListOf<AdConfig>()
@ -175,18 +211,18 @@ class SearchGameResultViewModel(
Single.zip(requestSingleList) {}
.compose(singleToMain())
.subscribe({
decorateListWithAd(itemDataList, decoratedItemDataList, list, cpmSubjectEntity)
decorateListWithAd(itemDataList, list)
}, {
decorateListWithAd(itemDataList, decoratedItemDataList, list, cpmSubjectEntity)
decorateListWithAd(itemDataList, list)
})
} else {
decorateListWithAd(itemDataList, decoratedItemDataList, list, cpmSubjectEntity)
decorateListWithAd(itemDataList, list)
}
} else {
decorateListWithThirdPartyAdOnly(decoratedItemDataList, thirdPartyAdList, list, cpmSubjectEntity)
decorateListWithThirdPartyAdOnly(itemDataList, thirdPartyAdList, list)
}
} else {
decorateWithWGameSubjectCPM(itemDataList, list, cpmSubjectEntity)
postResultList(itemDataList, list)
}
}
@ -197,27 +233,25 @@ class SearchGameResultViewModel(
}
private fun decorateListWithThirdPartyAdOnly(
decoratedItemDataList: ArrayList<SearchItemData>,
itemDataList: ArrayList<SearchItemData>,
thirdPartyAdList: List<AdConfig>,
list: List<GameEntity>,
cpmSubjectEntity: SearchSubjectEntity?
list: List<GameEntity>
) {
thirdPartyAdList.forEach {
decoratedItemDataList.add(it.position - 1, SearchItemData(ad = it.thirdPartyAd, adConfig = it))
itemDataList.add(it.position - 1, SearchItemData(ad = it.thirdPartyAd, adConfig = it))
SPUtils.setLong(Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + it.position, System.currentTimeMillis())
}
decorateWithWGameSubjectCPM(decoratedItemDataList, list, cpmSubjectEntity)
postResultList(itemDataList, list)
}
private fun decorateListWithAd(
itemDataList: ArrayList<SearchItemData>,
decoratedItemDataList: ArrayList<SearchItemData>,
list: List<GameEntity>,
cpmSubjectEntity: SearchSubjectEntity?
list: List<GameEntity>
) {
val adGameOneIdSet = HashSet<String>() // 展示样式为单个游戏时记录游戏ID避免重复
val decoratedItemDataSize = itemDataList.size
for ((index, position) in mAdPositionSet!!.withIndex()) {
if (position < itemDataList.size + index + 1) {
if (position < decoratedItemDataSize + index + 1) {
val adConfig = mGameSearchAdList!!.safelyGetInRelease(index)
val showThirdPartyAd = adConfig?.displayRule?.adSource == AdDelegateHelper.AD_TYPE_SDK
val showOwnerAd = adConfig?.displayRule?.adSource == AdDelegateHelper.AD_TYPE_OWNER
@ -225,7 +259,7 @@ class SearchGameResultViewModel(
if ((showThirdPartyAd && adConfig?.thirdPartyAd != null)
|| (showOwnerAd && adConfig?.ownerAd == null && adConfig?.thirdPartyAd != null && showOnFailed)
) {
decoratedItemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd, adConfig = adConfig))
itemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd, adConfig = adConfig))
SPUtils.setLong(
Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + adConfig.position,
System.currentTimeMillis()
@ -237,7 +271,7 @@ class SearchGameResultViewModel(
if (!gameList.isNullOrEmpty()) {
if (adConfig.ownerAd.adSource?.displayStyle == "game_zone") {
// 游戏专题
decoratedItemDataList.add(
itemDataList.add(
position - 1,
SearchItemData(
subject = SearchSubjectEntity(
@ -259,7 +293,7 @@ class SearchGameResultViewModel(
}
randomGameEntity?.id?.let { adGameOneIdSet.add(it) }
decoratedItemDataList.add(
itemDataList.add(
position - 1,
SearchItemData(game = randomGameEntity, adConfig = adConfig)
)
@ -270,7 +304,7 @@ class SearchGameResultViewModel(
)
} else if (showOnFailed && adConfig.thirdPartyAd != null) {
// 自有广告为空时,显示第三方广告
decoratedItemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd, adConfig = adConfig))
itemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd, adConfig = adConfig))
SPUtils.setLong(
Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + adConfig.position,
System.currentTimeMillis()
@ -281,41 +315,7 @@ class SearchGameResultViewModel(
break
}
}
decorateWithWGameSubjectCPM(decoratedItemDataList, list, cpmSubjectEntity)
}
@SuppressLint("CheckResult")
private fun decorateWithWGameSubjectCPM(
resultList: ArrayList<SearchItemData>,
list: List<GameEntity>,
cpmSubjectEntity: SearchSubjectEntity?
) {
// 微信小游戏CPM专题搜索结果存在则请求CPM接口获取微信小游戏列表数据并将列表数据插入缓存的CPM专题中
// 再根据location的值固定为4将CPM专题插入搜索结果列表中
// 相关需求https://jira.shanqu.cc/browse/GHZSCY-6710
cpmSubjectEntity?.let { subject ->
if (subject.games.isNotEmpty()) {
Single.just(subject.games.toMutableList())
} else {
repository.getWGameCPMGameList()
.onErrorReturnItem(mutableListOf())
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
val cpmSearchItemData = SearchItemData(subject = subject.apply { games = it })
if (subject.location <= 0 || subject.location > resultList.size) {
resultList.add(cpmSearchItemData)
} else {
resultList.add(subject.location - 1, cpmSearchItemData)
}
postResultList(resultList, list)
},
{
postResultList(resultList, list)
})
} ?: postResultList(resultList, list)
postResultList(itemDataList, list)
}
@SuppressLint("CheckResult")
@ -343,7 +343,7 @@ class SearchGameResultViewModel(
}
private fun postResultList(resultList: ArrayList<SearchItemData>, list: List<GameEntity>) {
mResultLiveData.postValue(resultList)
mResultLiveData.postValue(resultList.toMutableList())
if (mPage == 1) {
if (repository is MiniGameSearchResultRepository) {
SensorsBridge.trackMiniGameSearchResultReturn(
@ -362,7 +362,6 @@ class SearchGameResultViewModel(
mSearchKey ?: "",
SearchActivity.toTrackSearchType(mSearchType),
list.isNotEmpty()
)
}
@ -431,7 +430,6 @@ class SearchGameResultViewModel(
companion object {
const val AD_SUBJECT_GAME_MAX_COUNT = 8
const val WGAME_CPM_SUBJECT_POSITION = 4
}
}

View File

@ -102,6 +102,7 @@ abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab {
noDataStub = mCachedView.findViewById(R.id.reuse_no_data_stub)
noConnectionStub = mCachedView.findViewById(R.id.reuse_no_connection_stub)
loadingStub = mCachedView.findViewById(R.id.reuse_loading_stub)
showLoading(true)
backgroundColor = com.gh.gamecenter.common.R.color.ui_background.toColor(requireContext())
backgroundWhiteColor = com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext())

View File

@ -61,6 +61,7 @@ import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.time.TimeUtil
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.feature.utils.SentryHelper
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
import com.gh.gamecenter.home.custom.CustomPageFragment
import com.gh.gamecenter.home.video.AutomaticVideoView
@ -214,7 +215,16 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = FragmentSearchToolbarTabWrapperBinding.inflate(layoutInflater)
binding = try {
FragmentSearchToolbarTabWrapperBinding.inflate(layoutInflater)
} catch (e: Exception) {
SentryHelper.onEvent("VIEW_BINDING_BIND_ERROR",
"digest", e.localizedMessage,
"gid", HaloApp.getInstance().gid
)
// 玄学,重试一次,该闪退闪退
FragmentSearchToolbarTabWrapperBinding.inflate(layoutInflater)
}
mCachedView = binding.root
return mCachedView
}
@ -971,6 +981,8 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
}
override fun setPullDownPush(pullDownPush: PullDownPush?, pullDownPushHandler: PullDownPushHandler?) {
if (!isAdded) return
if (autoVideoView == null) {
binding.autoVideoViewStub.setOnInflateListener { _, inflated ->
autoVideoView = LayoutAutoVideoViewBinding.bind(inflated).root

View File

@ -17,6 +17,7 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.layoutInflater
import com.gh.gamecenter.common.utils.safelyGetInRelease
import com.gh.gamecenter.common.view.PageControllerAdapter
import com.gh.gamecenter.common.view.PageTransformerAdapter
import com.gh.gamecenter.common.view.ScrollEventListener
@ -151,7 +152,8 @@ class VGameInstalledLaunchDialog : DialogFragment() {
launch.setOnClickListener { view ->
val currentItem = pageControllerAdapter.currentItem
val installedGame = installAdapter.currentList[currentItem]
val installedGame =
installAdapter.currentList.safelyGetInRelease(currentItem) ?: return@setOnClickListener
val vDownloadEntity =
VHelper.getVDownloadEntitySnapshot(installedGame.gameId, installedGame.packageName)
?: return@setOnClickListener

View File

@ -7,9 +7,9 @@ ext {
targetSdkVersion = 30
// application info (每个大版本之间的 versionCode 增加 20)
versionCode = 1112
versionName = "5.38.2"
applicationId = "com.gh.gamecenter"
versionCode = 1114
versionName = "5.38.4"
applicationId = "com.gh.gamecenter.a1"
applicationIdGat = "com.gh.gamecenter.intl"
// AndroidX
@ -143,7 +143,7 @@ ext {
acloudPush = "3.8.8.1"
jpushVersion = "5.4.0"
jverifiationVersion = "3.1.7"
jverifiationVersion = "3.2.5"
honorPushVersion = "7.0.61.303"
volcTlsVersion = "1.1.4"

View File

@ -94,6 +94,12 @@ public class OkHttpCacheInterceptor implements Interceptor {
String token = userManagerProvider.getToken();
String deviceId = appProvider.getGid();
String temporaryLocalDeviceId = appProvider.getTemporaryLocalDeviceId();
String packageName = mContext.getPackageName();
request = request.newBuilder()
.addHeader("PACKAGE", packageName)
.build();
if (!TextUtils.isEmpty(token)) {
request = request.newBuilder()
.addHeader("TOKEN", token)

View File

@ -9,6 +9,9 @@ import retrofit2.http.POST
interface WGameCPMApiService {
@POST("geteditorrecommend")
fun getEditorRecommendList(@Body body: RequestBody): Single<WXMiniGameCPMEntity>
@POST("getuserrecommend")
fun getUserRecommendList(@Body body: RequestBody): Single<WXMiniGameCPMEntity>

View File

@ -97,6 +97,8 @@ public class WXEntryActivity extends Activity implements IWXAPIEventHandler, WeC
&& !((SendAuth.Resp) baseResp).state.contains("qqminigame")
) {
WXAPIProxyFactory.getLiveData().postValue(baseResp);
} else if (baseResp.getType() == ConstantsAPI.COMMAND_SUBSCRIBE_MESSAGE) {
WXAPIProxyFactory.getLiveData().postValue(baseResp);
}
String resultString = "";

View File

@ -216,6 +216,7 @@
android:layout_alignParentBottom="true"
android:layout_marginBottom="64dp"
android:gravity="center"
android:visibility="invisible"
android:orientation="horizontal">
<ImageView

View File

@ -5,30 +5,34 @@ import android.content.Context
import android.content.res.Configuration
import com.gh.gamecenter.core.iinterface.IApplication
import com.google.auto.service.AutoService
import com.lg.vspace.common.CommonApp
import com.lg.vspace.App64
@AutoService(IApplication::class)
class HaloApp : IApplication {
private val commonApp = CommonApp()
private val app = App64()
override fun attachBaseContext(base: Context) {
commonApp.attachBaseContext(base)
app.attachBaseContext(base)
}
override fun onCreate(application: Application) {
commonApp.onCreate(application)
app.onCreate(application)
}
override fun onLowMemory() {
app.onLowMemory()
}
override fun onTerminate() {
app.onTerminate()
}
override fun onTrimMemory(level: Int) {
app.onTrimMemory(level)
}
override fun onConfigurationChanged(newConfig: Configuration) {
app.onConfigurationChanged(newConfig)
}
}

View File

@ -77,7 +77,7 @@ done
if [ $BUILD_WITH_INIT_GRADLE == false ]; then
./gradlew assemble${BUILD_VARIANT_ENV}${BUILD_VARIANT_REGION^}Release -PBUILD_PUSH_TYPE=${BUILD_PUSH_TYPE}
else
./gradlew assemble${BUILD_VARIANT_ENV}${BUILD_VARIANT_REGION^}Release -I init.gradle -PBUILD_PUSH_TYPE=${BUILD_PUSH_TYPE}
./gradlew assemble${BUILD_VARIANT_ENV}${BUILD_VARIANT_REGION^}Release -I init.gradle -PEXCLUDE_OPTIONAL_MODULES=true -PENABLE_PUSH=true -PENABLE_FEEDBACK=true -PENABLE_PKG=true -PENABLE_MESSAGE=true -PENABLE_FLOATING_WINDOW=true -PENABLE_SENTRY=true -PENABLE_OAID=true -PENABLE_SENSOR_DATA=true
fi
mkdir -p release-app/${versionName}_${versionCode}

2
vasdk

Submodule vasdk updated: 270ed85b7d...9cc123df25