Compare commits

...

51 Commits

Author SHA1 Message Date
5a48293bd8 fix: 修复 build_with_simple_backup.sh 不能在 mac Bash 上编译的问题 2025-01-17 18:45:37 +08:00
d0bf23ae48 Merge remote-tracking branch 'origin/release' into dev 2025-01-17 14:15:55 +08:00
b2fde1e0af Merge branch 'hotfix/v5.38.8-1118/meta_build_script_channel_issue' into 'release'
fix: 修复推广打包渠道不生效的问题

See merge request halo/android/assistant-android!2045
2025-01-16 16:01:39 +08:00
ab1350ff46 fix: 修复推广打包渠道不生效的问题 2025-01-16 16:00:25 +08:00
7f991e29d4 Merge branch 'fix/xiaomi_parallel_game_auth' into 'dev'
fix: 修复小米部分机型双开由于缺少权限无法授权登录的问题

See merge request halo/android/assistant-android!2044
2025-01-16 11:04:40 +08:00
40edf76aed fix: 修复小米部分机型双开由于缺少权限无法授权登录的问题 2025-01-16 11:04:40 +08:00
aaeb83c5df Merge branch 'fix/splash_flicker_on_miui' into 'dev'
fix: 修复部分小米设备修改状态栏颜色导致开屏广告闪烁的问题

See merge request halo/android/assistant-android!2043
2025-01-16 09:29:05 +08:00
5739f0a800 fix: 修复部分小米设备修改状态栏颜色导致开屏广告闪烁的问题 2025-01-15 17:58:16 +08:00
10cc81e7fc Merge branch 'feat/va-relative' into 'dev'
feat: 同步va的release代码

See merge request halo/android/assistant-android!2042
2025-01-15 15:00:42 +08:00
60a50f5722 feat: 同步va的release代码 2025-01-15 14:58:32 +08:00
644881c14f Merge branch 'fix/package_check_stuck_issue' into 'dev'
fix: 修复包名检测弹窗弹出较慢的问题

See merge request halo/android/assistant-android!2041
2025-01-15 14:48:19 +08:00
a0e43930a0 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/ad/AdDelegateHelper.kt
#	dependencies.gradle
#	module_login/src/main/java/com/gh/gamecenter/login/user/UserRepository.java
#	vasdk
2025-01-15 14:27:40 +08:00
aa5f6f4f24 fix: 修复包名检测弹窗弹出较慢的问题 2025-01-15 14:22:22 +08:00
ab7668fd81 chore: 版本更新至 5.38.8 2025-01-15 09:19:40 +08:00
c6f014c984 Merge branch 'hotfix/v5.38.7-1117/pre_download_error' into 'release'
fix: 修复预下载获取资源时,服务端报错未能正确处理的问题

See merge request halo/android/assistant-android!2040
2025-01-14 16:30:31 +08:00
c215bd195e fix: 修复预下载获取资源时,服务端报错未能正确处理的问题 2025-01-14 16:27:43 +08:00
bb73598a87 Merge branch 'hotfix/va-relative' into 'release'
fix: va_core进程没有启动导致aidl的NPE问题。

See merge request halo/android/assistant-android!2039
2025-01-14 16:24:52 +08:00
c6f70d1b4c fix: va_core进程没有启动导致aidl的NPE问题。 2025-01-14 16:23:01 +08:00
ce7f75976c Merge branch 'fix/GHZSCY-7371' into 'dev'
fix: 游戏详情-多版本插件下载问题 https://jira.shanqu.cc/browse/GHZSCY-7371

See merge request halo/android/assistant-android!2038
2025-01-14 13:45:06 +08:00
c8a7999990 fix: 游戏详情-多版本插件下载问题 https://jira.shanqu.cc/browse/GHZSCY-7371 2025-01-14 10:49:52 +08:00
0cd281a53c Merge branch 'hotfix/va-relative' into 'release'
fix: 手机不支持armeabi-v7a架构时,根据游戏来选择架构

See merge request halo/android/assistant-android!2037
2025-01-10 18:01:24 +08:00
e92d89d498 fix: 手机不支持armeabi-v7a架构时,根据游戏来选择架构 2025-01-10 17:44:03 +08:00
a22858389b chore: 版本更新至 5.38.7 2025-01-10 13:55:24 +08:00
e9d091043d Merge branch 'hotfix/va-relative' into 'release'
feat: 同步商业版VA,修复权限问题。

See merge request halo/android/assistant-android!2036
2025-01-10 11:25:46 +08:00
db4ac95094 feat: 同步商业版VA,修复权限问题。
fix: 实名认证超大UI问题
fix: sentry va relative log.
2025-01-10 11:24:45 +08:00
13be47d440 Merge branch 'fix/search-page-crash' into 'release'
fix:https://sentry.shanqu.cc/organizations/lightgame/issues/423398/?project=22

See merge request halo/android/assistant-android!2035
2025-01-10 11:21:43 +08:00
beee098cfe fix:https://sentry.shanqu.cc/organizations/lightgame/issues/423398/?project=22 2025-01-10 11:17:26 +08:00
d67aaf956b Merge branch 'feat/GHZSCY-7046' into 'release'
feat: 补充启动广告图相关广告加载事件埋点—客户端 https://jira.shanqu.cc/browse/GHZSCY-7046

See merge request halo/android/assistant-android!2034
2025-01-09 17:29:21 +08:00
1ed9151b1f feat: 补充启动广告图相关广告加载事件埋点—客户端 https://jira.shanqu.cc/browse/GHZSCY-7046 2025-01-09 16:43:54 +08:00
13f20f6883 Merge branch 'hotfix/v5.38.6-1116/ad_view_background' into 'release'
fix: 还原自有开屏广告的背景颜色 https://jira.shanqu.cc/browse/GHZSCY-7360

See merge request halo/android/assistant-android!2033
2025-01-09 15:28:06 +08:00
78e320a192 fix: 还原自有开屏广告的背景颜色 https://jira.shanqu.cc/browse/GHZSCY-7360 2025-01-09 15:27:34 +08:00
e51db47fad Merge branch 'cherry-pick-f8a26ece' into 'release'
Merge branch 'fix/GHZSCY-7277' into 'dev'

See merge request halo/android/assistant-android!2032
2025-01-09 15:24:18 +08:00
ac02ea88b9 Merge branch 'fix/GHZSCY-7277' into 'dev'
修复错误的下载错误提示 https://jira.shanqu.cc/browse/GHZSCY-7277

See merge request halo/android/assistant-android!2025

(cherry picked from commit f8a26ece01)

54ee3ea3 fix: 游戏下载异常提示 https://jira.shanqu.cc/browse/GHZSCY-7277

Co-authored-by: 陈君陶 <chenjuntao@ghzhushou.com>
2025-01-09 15:23:53 +08:00
f60004fc81 Merge branch 'feat/GHZSCY-7359' into 'release'
需求合并

See merge request halo/android/assistant-android!2031
2025-01-09 15:05:29 +08:00
0cf39a82e2 Merge branch 'fix/viewstub_crashes' into 'release'
fix: 修复ViewStub偶发闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/422108/events/?project=22 https://sentry.shanqu.cc/organizations/lightgame/issues/425087/?project=22

See merge request halo/android/assistant-android!2030
2025-01-09 15:03:51 +08:00
315f244153 fix:【光环助手】包名检测及搜索页面在深色模式下的显示问题 https://jira.shanqu.cc/browse/GHZSCY-6985 2025-01-09 14:54:37 +08:00
f4bdc02d70 fix: 【光环助手】深色模式显示问题 https://jira.shanqu.cc/browse/GHZSCY-7121 2025-01-09 14:54:17 +08:00
aef39eb481 feat: 样式组件优化汇总—客户端 https://jira.shanqu.cc/browse/GHZSCY-6866 2025-01-09 14:53:37 +08:00
dc2e7147d9 fix: 修复ViewStub偶发闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/422108/events/?project=22 https://sentry.shanqu.cc/organizations/lightgame/issues/425087/?project=22 2025-01-09 14:49:58 +08:00
fdcb6342bf Merge branch 'hotfix/v5.38.6-1116/crashes' into 'release'
修复部分 5.38.6 线上闪退

See merge request halo/android/assistant-android!2029
2025-01-09 14:37:49 +08:00
b0da4f8986 Merge branch 'hotfix/v5.38.6-1116/blank_ad_view' into 'release'
fix: 优化开屏广告的显示,提高线程池的 core 线程数,限制视频开屏广告的触摸控制

See merge request halo/android/assistant-android!2028
2025-01-09 14:37:40 +08:00
f7cc906cc5 fix: 优化开屏广告的显示,提高线程池的 core 线程数,限制视频开屏广告的触摸控制 2025-01-09 14:37:40 +08:00
795fbabd90 Merge branch 'hotfix/v5.38.6-1116/login_culprit' into 'release'
修复`我的光环`页面在用户信息接口异常时的显示问题 https://jira.shanqu.cc/browse/GHZSCY-7340

See merge request halo/android/assistant-android!2027
2025-01-09 14:34:25 +08:00
e770f8a359 fix: 修复安装完成后更新安装信息时的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/395511 2025-01-09 11:49:38 +08:00
dd12b103be fix: 捕抓上报游戏启动日志的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/406179 2025-01-09 09:59:32 +08:00
21f4a398d5 fix: 处理数组越界闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/408904 2025-01-09 09:45:22 +08:00
8dfb1644a8 fix: 登录状态显示问题 https://jira.shanqu.cc/browse/GHZSCY-7340 2025-01-07 17:48:53 +08:00
9744b95126 Merge branch 'fix/viewstub_crash' into 'release'
fix: 修复ViewStub偶发闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/423818/?project=22

See merge request halo/android/assistant-android!2019
2024-12-27 15:14:25 +08:00
009608165c Merge branch 'fix-issues-421826' into 'release'
fix:https://sentry.shanqu.cc/organizations/lightgame/issues/421826/?project=22

See merge request halo/android/assistant-android!2018
2024-12-27 14:02:39 +08:00
98356a7dd7 fix: 修复ViewStub偶发闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/423818/?project=22 2024-12-27 13:56:10 +08:00
8389041379 fix:https://sentry.shanqu.cc/organizations/lightgame/issues/421826/?project=22 2024-12-27 13:49:29 +08:00
37 changed files with 306 additions and 187 deletions

View File

@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.graphics.drawable.Animatable
import android.os.Message
import android.text.TextUtils
import android.view.View
@ -13,11 +14,13 @@ import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.fragment.app.Fragment
import com.therouter.TheRouter
import com.facebook.drawee.controller.BaseControllerListener
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.image.ImageInfo
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.common.util.LogUtils
import com.gh.common.util.NewFlatLogUtils.logOpenScreenAdSkip
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.MainActivity
@ -59,6 +62,8 @@ object AdDelegateHelper {
private val mGameSearchAdList: ArrayList<AdConfig> by lazy { arrayListOf() }
private var mVGameLaunchAd: AdConfig? = null
private var ownerSplashAdLoadTime = 0L
val vGameLaunchAd: AdConfig?
get() = mVGameLaunchAd
@ -76,6 +81,7 @@ object AdDelegateHelper {
}
var isShowingSplashAd = false // 是否正在显示开屏广告
var isOwnerSplashAdShown = false // 自有开屏广告是否展示
var gameSearchKeyword = ""
fun initAdSdk(context: Context) {
@ -302,6 +308,7 @@ object AdDelegateHelper {
) {
val hideCallback = {
isShowingSplashAd = false
isOwnerSplashAdShown = false
hideAction.invoke()
}
if (mSplashAd != null) {
@ -574,6 +581,8 @@ object AdDelegateHelper {
handler: BaseActivity.BaseHandler,
hideCallback: () -> Unit
) {
isOwnerSplashAdShown = false
val jumpBtn = startAdContainer.findViewById<TextView>(R.id.jumpBtn)
val jumpDetailBtn: TextView = startAdContainer.findViewById(R.id.jumpDetailBtn)
val adImage: SimpleDraweeView = startAdContainer.findViewById(R.id.adImage)
@ -592,38 +601,62 @@ object AdDelegateHelper {
)
adImage.visibleIf(true)
ImageUtils.display(adImage, ad.img)
ImageUtils.displayWithCallback(adImage, ad.img, true, object : BaseControllerListener<ImageInfo>() {
override fun onSubmit(id: String?, callerContext: Any?) {
super.onSubmit(id, callerContext)
adImage.post {
ownerSplashAdLoadTime = System.currentTimeMillis()
NewFlatLogUtils.logSplashAdLoad(ad.id)
}
}
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
isOwnerSplashAdShown = true
adImage.post {
NewFlatLogUtils.logSplashAdShow(ad.id, System.currentTimeMillis() - ownerSplashAdLoadTime)
}
}
override fun onFailure(id: String?, throwable: Throwable?) {
super.onFailure(id, throwable)
NewFlatLogUtils.logSplashAdFail(ad.id, "启动广告图加载失败")
}
})
if (ad.isImageType) {
adVideo.visibleIf(false)
} else {
adVideo.visibleIf(true)
adVideo.startPlay(ad.video.url)
}
startAdContainer.setOnClickListener {
// 拦截点击事件传递
}
jumpBtn.setOnClickListener {
handler.removeMessages(MainActivity.COUNTDOWN_AD)
hideCallback.invoke()
val linkEntity = ad.jump
logOpenScreenAdSkip(
ad.id,
(if (linkEntity.text != null) linkEntity.text else "")!!,
(if (linkEntity.type != null) linkEntity.type else "")!!,
(if (linkEntity.link != null) linkEntity.link else "")!!
)
SensorsBridge.trackEvent(
"SplashAdOwnSkip",
"splash_ad_id",
ad.id,
"link_type",
linkEntity.type ?: "",
"link_id",
linkEntity.link ?: "",
"link_text",
linkEntity.text ?: ""
)
it.debounceActionWithInterval(1000L) {
if (!isOwnerSplashAdShown) {
NewFlatLogUtils.logSplashAdFail(ad.id, "加载过程中点击跳过广告")
}
handler.removeMessages(MainActivity.COUNTDOWN_AD)
hideCallback.invoke()
val linkEntity = ad.jump
NewFlatLogUtils.logOpenScreenAdSkip(
ad.id,
(if (linkEntity.text != null) linkEntity.text else "")!!,
(if (linkEntity.type != null) linkEntity.type else "")!!,
(if (linkEntity.link != null) linkEntity.link else "")!!
)
SensorsBridge.trackEvent(
"SplashAdOwnSkip",
"splash_ad_id",
ad.id,
"link_type",
linkEntity.type ?: "",
"link_id",
linkEntity.link ?: "",
"link_text",
linkEntity.text ?: ""
)
}
}
val sources: MutableList<ExposureSource> = ArrayList()
sources.add(ExposureSource("开屏广告", ad.id))

View File

@ -44,6 +44,16 @@ class SplashAdVideoView @JvmOverloads constructor(
return R.layout.layout_splash_ad_video
}
override fun touchSurfaceMoveFullLogic(absDeltaX: Float, absDeltaY: Float) {
// no nothing
}
override fun onPrepared() {
super.onPrepared()
visibility = VISIBLE
}
override fun onAutoCompletion() {
setStateAndUi(CURRENT_STATE_AUTO_COMPLETE);

View File

@ -4,6 +4,7 @@ import android.app.Activity
import android.content.Context
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.PackageChangeHelper
import com.gh.common.util.TempCertificationUtils
import com.gh.gamecenter.feature.entity.GameEntity
@ -25,6 +26,10 @@ class LandPageAddressHandler : DownloadChainHandler() {
processEndCallback?.invoke(asVGame, null)
}
} else {
val packageName = gameEntity.getApk().firstOrNull()?.packageName
if (packageName?.isNotEmpty() == true) {
PackageChangeHelper.addInstallPendingPackage(packageName)
}
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
}
}

View File

@ -3,7 +3,6 @@ package com.gh.common.dialog
import android.animation.ValueAnimator
import android.content.Context
import android.content.DialogInterface
import android.content.pm.PackageInfo
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -19,7 +18,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
@ -59,7 +57,6 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
private val mDuration = 3000
private var mDisposable: Disposable? = null
private var mAdapter: PackageCheckAdapter? = null
private var mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
var gameEntity: GameEntity? = null
var callBack: ConfirmListener? = null
@ -195,7 +192,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
if (binding.noRemindAgainCb.isChecked) {
saveRecord(entity)
}
val isAllPackageInstalled = isAllPackageInstalled(mAllInstalledPackages, entity)
val isAllPackageInstalled = isAllPackageInstalled(entity)
if (isAllPackageInstalled) {
mDismissByTouchInside = true
callBack?.onConfirm()
@ -299,7 +296,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
private fun getNotInstalledLink(packageDialogEntity: PackageDialogEntity): LinkEntity? {
val links = LinkedHashSet<LinkEntity>()
packageDialogEntity.detectionObjects.forEach { obj ->
if (!checkDetectionsInstalled(mAllInstalledPackages, obj.packages)) {
if (!checkDetectionsInstalled(obj.packages)) {
obj.assignDownload.forEach {
links.add(packageDialogEntity.links[it])
}
@ -325,9 +322,8 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
override fun onResume() {
super.onResume()
mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
gameEntity?.packageDialog?.let {
if (isAllPackageInstalled(mAllInstalledPackages, it)) {
if (isAllPackageInstalled(it)) {
callBack?.onConfirm()
dismissAllowingStateLoss()
}
@ -363,7 +359,6 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {
if (busFour.isInstalledOrUninstalled()) {
mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
mAdapter?.notifyDataSetChanged()
}
}
@ -388,7 +383,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
val entity = entities[position]
holder.binding.gameNameTv.text = entity.text
if (position <= index) {
val isAllInstalled = checkDetectionsInstalled(mAllInstalledPackages, entity.packages)
val isAllInstalled = checkDetectionsInstalled(entity.packages)
if (isAllInstalled) {
holder.binding.statusTv.text = "已安装"
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_theme))
@ -416,8 +411,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
return
}
val allInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
if (isAllPackageInstalled(allInstalledPackages, packageDialogEntity)) {
if (isAllPackageInstalled(packageDialogEntity)) {
callBack.onConfirm()
return
}
@ -453,13 +447,11 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
}
private fun checkDetectionsInstalled(
allInstalledPackages: List<String>,
packages: ArrayList<String>
): Boolean {
var isPackagesInstalled = false
packages.forEach { packageName ->
val isInstalled = allInstalledPackages.find { it == packageName } != null
if (isInstalled) {
if (PackageUtils.isInstalledFromAllPackage(HaloApp.getInstance(), packageName)) {
isPackagesInstalled = true
return@forEach
}
@ -469,17 +461,14 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
fun isAllPackageInstalled(
allInstalledPackages: List<String>,
packageDialogEntity: PackageDialogEntity
): Boolean {
var isAllInstalled = true
packageDialogEntity.detectionObjects.forEach loop@{ obj ->
if (!checkDetectionsInstalled(allInstalledPackages, obj.packages)) {
isAllInstalled = false
return isAllInstalled
if (!checkDetectionsInstalled(obj.packages)) {
return false
}
}
return isAllInstalled
return true
}
}
}

View File

@ -17,7 +17,7 @@ import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.DialogWechatBindingFailedBinding
import com.gh.gamecenter.login.user.UserRepository
import com.gh.gamecenter.login.user.UserManager
import com.lightgame.utils.Utils
class WechatBindingFailedDialogFragment : BaseDialogFragment() {
@ -48,10 +48,10 @@ class WechatBindingFailedDialogFragment : BaseDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
UserRepository.getInstance().loginUserInfo.observe(viewLifecycleOwner) {
currentUserId = it.data.getShortUserId()
binding.tvCurrentName.text = it.data.name
binding.ivCurrentAvatar.displayAvatar(it.data.icon)
UserManager.getInstance().userInfoEntity?.let {
currentUserId = it.getShortUserId()
binding.tvCurrentName.text = it.name ?: ""
binding.ivCurrentAvatar.displayAvatar(it.icon)
binding.tvUserId.text = getString(R.string.user_id, currentUserId)
}

View File

@ -10,16 +10,12 @@ fun FragmentManager.popBackStackAllowStateLoss() {
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) }
}
}
@ -29,34 +25,9 @@ fun FragmentManager.popBackStackImmediateAllowStateLoss(id: Int, flags: Int) =
if (!isStateSaved) {
popBackStackImmediate(id, flags)
} else {
hook { popBackStackImmediate(id, flags) }
false
}
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

View File

@ -2778,4 +2778,34 @@ object NewFlatLogUtils {
parseAndPutMeta()(this)
}.let(::log)
}
// 自有开屏广告加载
fun logSplashAdLoad(id: String) {
json {
KEY_EVENT to "splash_ad_load"
"ad_id" to id
parseAndPutMeta()(this)
}.let(::log)
}
// 自有开屏广告展示
fun logSplashAdShow(id: String, duration: Long) {
json {
KEY_EVENT to "splash_ad_show"
"ad_id" to id
"duration" to duration
parseAndPutMeta()(this)
}.let(::log)
}
// 自有开屏广告加载/展示失败
@JvmStatic
fun logSplashAdFail(id: String, error: String) {
json {
KEY_EVENT to "splash_ad_fail"
"ad_id" to id
"error" to error
parseAndPutMeta()(this)
}.let(::log)
}
}

View File

@ -578,7 +578,6 @@ object PackageHelper {
Utils.log(TAG, "refreshWrongInstallStatus 检查安装状态异常的应用")
val uninstalledButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
val updatedButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
for (packageName in packageNameSet) {
val installedVersionName = PackageUtils.getVersionNameByPackageName(packageName)
@ -587,18 +586,9 @@ object PackageHelper {
&& installedVersionName == null
) {
uninstalledButKeepingWrongStatusPackageNameSet.add(packageName)
} else if (PackagesManager.isInstalled(packageName)
&& installedVersionName != null
&& !PackagesManager.isInstalledWithSpecificVersion(packageName, installedVersionName)
) {
updatedButKeepingWrongStatusPackageNameSet.add(packageName)
}
}
Utils.log(
TAG,
"refreshWrongInstallStatus 需要更新已更新状态的包数量为 ${updatedButKeepingWrongStatusPackageNameSet.size}"
)
Utils.log(
TAG,
"refreshWrongInstallStatus 需要移除已安装的包数量为 ${uninstalledButKeepingWrongStatusPackageNameSet.size}"
@ -616,12 +606,6 @@ object PackageHelper {
additionalWhiteListPackageNameSet.toString()
)
}
if (updatedButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
for (packageName in updatedButKeepingWrongStatusPackageNameSet) {
PackageChangeHelper.addUpdate(packageName)
}
}
}
}
}
@ -635,7 +619,6 @@ object PackageHelper {
val installedButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
val uninstalledButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
val updatedButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
for (game in gameEntityList) {
for (apk in game.getApk()) {
@ -651,13 +634,6 @@ object PackageHelper {
&& installedVersionName == null
) {
uninstalledButKeepingWrongStatusPackageNameSet.add(packageName)
} else if (PackagesManager.isInstalled(packageName)
&& installedVersionName != null
&& !PackagesManager.isInstalledWithSpecificVersion(packageName, installedVersionName)
&& !PackagesManager.isCanUpdate(game.id, packageName, false)
) {
cachedPkgNameAndGameEntityMap.put(packageName, game)
updatedButKeepingWrongStatusPackageNameSet.add(packageName)
}
}
}
@ -666,10 +642,6 @@ object PackageHelper {
TAG,
"refreshWrongInstallStatus 需要更新已安装状态的包数量为 ${installedButKeepingWrongStatusPackageNameSet.size}"
)
Utils.log(
TAG,
"refreshWrongInstallStatus 需要更新已更新状态的包数量为 ${updatedButKeepingWrongStatusPackageNameSet.size}"
)
Utils.log(
TAG,
"refreshWrongInstallStatus 需要移除已安装的包数量为 ${uninstalledButKeepingWrongStatusPackageNameSet.size}"
@ -699,12 +671,6 @@ object PackageHelper {
additionalWhiteListPackageNameSet.toString()
)
}
if (updatedButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
for (packageName in updatedButKeepingWrongStatusPackageNameSet) {
PackageChangeHelper.addUpdate(packageName, cachedPkgNameAndGameEntityMap.remove(packageName))
}
}
}
}
}

View File

@ -81,28 +81,11 @@ object PackageLauncher {
gameEntity: GameEntity? = null,
packageName: String?
) {
if (packageName.isNullOrEmpty()) {
ToastUtils.toast("启动失败")
return
}
// 获取 GameInstall 实体,用于记录启动日志用
val gameInstall = if (gameEntity != null) {
GameInstall.transformGameInstall(gameEntity, packageName)
} else {
PackagesManager.getInstalledList().find { it.packageName == packageName }
}
if (gameInstall != null) {
NewFlatLogUtils.logGameLaunch(
gameId = gameInstall.id ?: "unknown",
gameName = gameInstall.name ?: "unknown",
gameCategory = gameInstall.category ?: "unknown",
downloadStatus = if (gameInstall.downloadStatus == "demo") "试玩" else "下载"
)
}
try {
val intent = context.applicationContext.packageManager.getLaunchIntentForPackage(packageName)
if (intent != null) {
@ -113,6 +96,26 @@ object PackageLauncher {
} catch (e: Exception) {
ToastUtils.toast( "启动失败")
}
try {
// 获取 GameInstall 实体,用于记录启动日志用
val gameInstall = if (gameEntity != null) {
GameInstall.transformGameInstall(gameEntity, packageName)
} else {
PackagesManager.getInstalledList().find { it.packageName == packageName }
}
if (gameInstall != null) {
NewFlatLogUtils.logGameLaunch(
gameId = gameInstall.id ?: "unknown",
gameName = gameInstall.name ?: "unknown",
gameCategory = gameInstall.category ?: "unknown",
downloadStatus = if (gameInstall.downloadStatus == "demo") "试玩" else "下载"
)
}
} catch (e: RuntimeException) {
// 都 DeadSystemException 了,还想啥日志上报
}
}
}

View File

@ -301,7 +301,7 @@ public class PackageUtils {
Signature[] signatures = packageInfo.signatures;
// 使用幸运破解器破解安卓签名认证可能会出现不用签名也能装的情况,这里有可能是空的
if (signatures[0] != null) {
if (signatures.length > 0 && signatures[0] != null) {
return parseSignature(signatures[0].toByteArray());
} else {
return new String[]{null, null};

View File

@ -166,8 +166,13 @@ public class MainActivity extends BaseActivity {
private final Handler handler = new Handler();
private boolean mShouldShowAd = false; // 是否显示广告
private Bundle mTempSavedInstanceState;
private boolean mFragmentIsCreated = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
mTempSavedInstanceState = savedInstanceState;
mShouldShowAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null
&& !HaloApp.getInstance().isAlreadyUpAndRunning;
HaloApp.getInstance().isAlreadyUpAndRunning = true;
@ -175,21 +180,12 @@ public class MainActivity extends BaseActivity {
mMainWrapperViewModel = new ViewModelProvider(this, new MainWrapperViewModel.Factory(HaloApp.getInstance()))
.get(MainWrapperViewModel.class);
DisplayUtils.transparentStatusBar(this);
DisplayUtils.updateGlobalScreen(this);
super.onCreate(savedInstanceState);
setStatusBarColor(Color.TRANSPARENT);
Fragment fragmentFromFM = getSupportFragmentManager().findFragmentById(com.gh.gamecenter.selector.R.id.layout_activity_content);
mMainWrapperFragment = fragmentFromFM != null ? (MainWrapperFragment) fragmentFromFM : new MainWrapperFragment();
if (savedInstanceState != null) {
mMainWrapperFragment.setArguments(savedInstanceState);
} else if (getIntent() != null) {
mMainWrapperFragment.setArguments(getIntent().getExtras());
}
replaceFragment(mMainWrapperFragment);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
if (HaloApp.getInstance().isNewForThisVersion) {
LunchType lunchType = HaloApp.getInstance().getLaunchType();
@ -215,7 +211,6 @@ public class MainActivity extends BaseActivity {
DataUtils.getGid();
}
mPackageViewModel = ViewModelProviders.of(this, new PackageViewModel.Factory()).get(PackageViewModel.class);
final boolean containsErrorMsg = com.gh.gamecenter.common.constant.Config.isContainsErrorMsg();
@ -273,6 +268,7 @@ public class MainActivity extends BaseActivity {
if (mShouldShowAd) {
showAd();
} else {
doInitMainFragment(mTempSavedInstanceState);
hideTextAd();
hideSplashAd();
}
@ -328,6 +324,23 @@ public class MainActivity extends BaseActivity {
CertificationSwitchHelper.getCertificationSwitch();
}
private void doInitMainFragment(Bundle savedInstanceState) {
if (mFragmentIsCreated) return;
mTempSavedInstanceState = null;
Fragment fragmentFromFM = getSupportFragmentManager().findFragmentById(com.gh.gamecenter.selector.R.id.layout_activity_content);
mMainWrapperFragment = fragmentFromFM != null ? (MainWrapperFragment) fragmentFromFM : new MainWrapperFragment();
if (savedInstanceState != null) {
mMainWrapperFragment.setArguments(savedInstanceState);
} else if (getIntent() != null) {
mMainWrapperFragment.setArguments(getIntent().getExtras());
}
replaceFragment(mMainWrapperFragment);
mFragmentIsCreated = true;
}
@SuppressLint("CheckResult")
private void getTeenagerMode() {
RetrofitManager.getInstance()
@ -541,19 +554,31 @@ public class MainActivity extends BaseActivity {
protected void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == COUNTDOWN_AD || msg.what == COUNTDOWN_SDK_AD) {
mCountdownCount++;
int maxCount;
if (msg.what == COUNTDOWN_AD) {
maxCount = mCountdownMaxCount;
} else {
maxCount = COUNTDOWN_SDK_MAX_COUNT;
}
// 读秒到一半的时候初始化 MainWrapperFragment
if (mCountdownCount == maxCount / 2) {
doInitMainFragment(mTempSavedInstanceState);
}
mCountdownCount++;
if (maxCount < mCountdownCount) {
AdDelegateHelper.INSTANCE.setShowingSplashAd(false);
hideSplashAd();
if (msg.what == COUNTDOWN_AD && msg.obj instanceof StartupAdEntity) {
StartupAdEntity ad = (StartupAdEntity) msg.obj;
if (!AdDelegateHelper.INSTANCE.isOwnerSplashAdShown()) {
com.gh.common.util.NewFlatLogUtils.logSplashAdFail(ad.getId(), "广告加载超时");
}
AdDelegateHelper.INSTANCE.setOwnerSplashAdShown(false);
LinkEntity linkEntity = ad.getJump();
SensorsBridge.trackEvent(
"SplashAdOwnSkip",
@ -633,10 +658,11 @@ public class MainActivity extends BaseActivity {
ExtensionsKt.removeFromParent(startSdkAdIcpContainer, true);
}
onSplashHidden();
onAdHidden();
}
private void onSplashHidden() {
private void onAdHidden() {
doInitMainFragment(mTempSavedInstanceState);
// 通知全局弹窗可以进行显示
AppExecutor.getUiExecutor().execute(GlobalPriorityChainHelper.INSTANCE::start);
}
@ -854,7 +880,9 @@ public class MainActivity extends BaseActivity {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && !mMainWrapperFragment.onHandleBackPressed()) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0
&& mMainWrapperFragment != null
&& !mMainWrapperFragment.onHandleBackPressed()) {
DownloadEntity downloadEntity = null;
for (DownloadEntity entity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentTask()) {
if (entity.getStatus().equals(DownloadStatus.done)) {

View File

@ -329,6 +329,19 @@ open class SearchActivity : BaseActivity() {
// MtaHelper.onEvent("游戏搜索", "主动搜索", newSearchKey)
}
override fun onResume() {
super.onResume()
val newSearchKey = searchEt.text.toString().trim { it <= ' ' }
if (newSearchKey.isBlank()) {
try {
popBackToFragment(SearchDefaultFragment::class.java.name)
} catch (e: Exception) {
// no implement
}
}
}
protected open fun provideDao(): ISearchHistoryDao = SearchHistoryDao(this)
open fun updateDisplayType(type: DisplayType) {

View File

@ -194,6 +194,10 @@ class DetailViewHolder(
if (mGameEntity.isLandPageAddressDialog() && !mGameEntity.isLandPageAddressDialogShowOnly()) {
// 第三方落地页为开启状态并且展示状态不为“仅显示弹窗”,需要在点击确认后显示弹窗
DialogUtils.showLandPageAddressDialog(mViewHolder.context, mGameEntity) {
val packageName = mGameEntity.getApk().firstOrNull()?.packageName
if (packageName?.isNotEmpty() == true) {
PackageChangeHelper.addInstallPendingPackage(packageName)
}
DirectUtils.directToExternalBrowser(mViewHolder.context, mGameEntity.landPageAddressDialog!!.link!!)
}
}

View File

@ -1,5 +1,7 @@
package com.gh.gamecenter.authorization
import android.app.Activity
import android.app.Application.ActivityLifecycleCallbacks
import android.app.Dialog
import android.content.Intent
import android.os.Build
@ -22,6 +24,7 @@ import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserRepository
import com.gh.gamecenter.login.view.LoginActivity
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
/**
@ -139,7 +142,7 @@ class AuthorizationActivity : ToolBarActivity() {
override fun onRestart() {
super.onRestart()
if (!CheckLoginUtils.isLogin()) {
finish()
finishAndRemoveTask()
} else {
initUserInfo()
initData()
@ -150,12 +153,12 @@ class AuthorizationActivity : ToolBarActivity() {
private fun checkParam() {
val uri = intent.data
if (uri == null) {
finish()
finishAndRemoveTask()
return
}
val host = uri.host
if (host != "authorize") {
finish()
finishAndRemoveTask()
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
@ -168,7 +171,7 @@ class AuthorizationActivity : ToolBarActivity() {
gameName = uri.getQueryParameter(EntranceConsts.KEY_GAME_NAME) ?: ""
gameUid = uri.getQueryParameter(EntranceConsts.KEY_UID)?.toIntOrNull() ?: -1
if (mRemotePkgName == null) {
finish()
finishAndRemoveTask()
return
}
}
@ -221,7 +224,7 @@ class AuthorizationActivity : ToolBarActivity() {
val remotePkgName = mRemotePkgName
if (remotePkgName == null) {
logAuthResult(false)
finish()
finishAndRemoveTask()
return
}
if (mToken.isEmpty()) {
@ -242,13 +245,44 @@ class AuthorizationActivity : ToolBarActivity() {
intent.putExtra(EntranceConsts.KEY_USER_NAME, username)
intent.putExtra(EntranceConsts.KEY_USER_AVATAR, userAvatar)
if (gameUid != -1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(gameUid))
try {
sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(gameUid))
} catch (e: Exception) {
// 双开/分身游戏进行授权时,如果无 INTERACT_ACROSS_USERS 权限则使用Activity传递授权结果
authByActivity(intent)
return
}
} else {
sendBroadcast(intent)
}
logAuthResult(true)
backToLaunchApp()
finish()
finishAndRemoveTask()
}
private fun authByActivity(intent: Intent) {
intent.setClassName(mRemotePkgName!!, AUTHORIZATION_RESULT_ACTIVITY)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
HaloApp.getInstance().registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {
if (activity == this@AuthorizationActivity) {
HaloApp.getInstance().unregisterActivityLifecycleCallbacks(this)
finishAndRemoveTask()
}
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {
if (activity == this@AuthorizationActivity) {
HaloApp.getInstance().unregisterActivityLifecycleCallbacks(this)
}
}
})
startActivity(intent)
logAuthResult(true)
}
private fun logAuthResult(isSuccess: Boolean) {
@ -277,7 +311,7 @@ class AuthorizationActivity : ToolBarActivity() {
}
override fun onBackPressed() {
super.onBackPressed()
finishAndRemoveTask()
backToLaunchApp(false)
@ -292,6 +326,7 @@ class AuthorizationActivity : ToolBarActivity() {
private const val BUTTON_TYPE_CONFIRM = "确定"
private const val BUTTON_TYPE_BACK = "返回"
private const val TYPE_PLUGIN = "plugin"
private const val AUTHORIZATION_RESULT_ACTIVITY = "com.gh.plugin.AuthorizationResultActivity"
}
}

View File

@ -12,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.gh.common.exposure.IExposable
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.PackageChangeHelper
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageLauncher
import com.gh.download.DownloadManager
@ -398,6 +399,10 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
if (update.isLandPageAddressDialogShowOnly()) {
updateOrPluggable(updateBtn, update, downloadEntity, pluginDesc)
} else {
val packageName = update.packageName
if (packageName.isNotEmpty() == true) {
PackageChangeHelper.addInstallPendingPackage(packageName)
}
DirectUtils.directToExternalBrowser(it.context, update.landPageAddressDialog!!.link!!)
}
}

View File

@ -239,7 +239,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
viewModel.loadFirst(false)
}
}
binding.reuseNoConnectionStub.inflate()
binding.reuseNoConnectionStub.inflateOrShow()
} else {
noConnectionBinding?.root?.visibility = View.VISIBLE
}
@ -249,7 +249,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
noDataBinding = ReuseNoneDataBinding.bind(inflated)
noDataBinding?.root?.visibility = View.VISIBLE
}
binding.reuseNoDataStub.inflate()
binding.reuseNoDataStub.inflateOrShow()
} else {
noDataBinding?.root?.visibility = View.VISIBLE
}
@ -304,7 +304,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
}
initSearchBar(it)
}
binding.reuseSearchBarStub.inflate()
binding.reuseSearchBarStub.inflateOrShow()
} else {
initSearchBar(it)
}

View File

@ -53,6 +53,7 @@ class CustomHomeSlideListItemViewHolder(val binding: HomeSlideListItemCustomBind
ImageUtils.displayWithCallback(
binding.slideBackground,
homeSlide.image,
false,
object : BaseControllerListener<ImageInfo>() {
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
binding.bottomGradient.visibility = View.VISIBLE

View File

@ -67,6 +67,7 @@ class CustomHomeSubSlideListItemViewHolder(val binding: HomeSubSlideListItemCust
ImageUtils.displayWithCallback(
binding.slideBackground,
homeSlide.image,
false,
object : BaseControllerListener<ImageInfo>() {
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
if (homeSlide.placeholderColor.isNotEmpty() && homeSlide.linkGame != null) {

View File

@ -35,17 +35,21 @@ class PackageFilterManager {
if (appendOnly) {
// 添加因为异常而没能正常更新的包名列表
finalPackageList.addAll(PackageRepository.mPendingPackageNameSet)
synchronized(PackageRepository.mPendingPackageNameSet) {
finalPackageList.addAll(PackageRepository.mPendingPackageNameSet)
}
}
RetrofitManager.getInstance()
.newApi
.postInstalledAppList(packageList.toRequestBody())
.postInstalledAppList(finalPackageList.toRequestBody())
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<PackageFilter>() {
override fun onSuccess(data: PackageFilter) {
mPackageKey = data.key
PackageRepository.mPendingPackageNameSet.clear()
synchronized(PackageRepository.mPendingPackageNameSet) {
PackageRepository.mPendingPackageNameSet.removeAll(finalPackageList)
}
val partialPackageList = arrayListOf<String>()
@ -78,7 +82,9 @@ class PackageFilterManager {
super.onFailure(exception)
if (appendOnly) {
PackageRepository.mPendingPackageNameSet.addAll(packageList)
synchronized(PackageRepository.mPendingPackageNameSet) {
PackageRepository.mPendingPackageNameSet.addAll(finalPackageList)
}
} else {
if (exception is retrofit2.HttpException && exception.code() == 403) {
// 403 代表 key 过期,需要重新获取

View File

@ -85,7 +85,7 @@ object PackageRepository {
_recentVaPlayedChanged.postValue(Unit)
}
val packageFilterManager = PackageFilterManager()
var mPendingPackageNameSet = hashSetOf<String>() // 因遇到异常而等待下次操作更新的包名列表
var mPendingPackageNameSet = Collections.synchronizedSet<String>(hashSetOf<String>()) // 因遇到异常而等待下次操作更新的包名列表
var mValidPackageNameSet = hashSetOf<String>() // 已被收录的游戏包名列表

View File

@ -701,7 +701,7 @@ class HaloPersonalFragment : BaseLazyFragment() {
}
private fun inflateRealView() {
mBinding.stub.inflate()
mBinding.stub.inflateOrShow()
mStubBinding.statusBar.goneIf(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
mStubBinding.darkModeIv.goneIf(!(Config.getNightModeSetting()?.icon ?: false))

View File

@ -162,7 +162,7 @@ abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab {
showLoading(true)
}
}
noConnectionStub?.inflate()
noConnectionStub?.inflateOrShow()
} else {
noConnectionBinding?.root?.visibility = View.VISIBLE
}
@ -178,7 +178,7 @@ abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab {
noDataBinding = ReuseNoneDataBinding.bind(inflated)
noDataBinding?.root?.visibility = View.VISIBLE
}
noDataStub?.inflate()
noDataStub?.inflateOrShow()
} else {
noDataBinding?.root?.visibility = View.VISIBLE
}
@ -194,7 +194,7 @@ abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab {
loadingBinding = ReuseLoadingBinding.bind(inflated)
loadingBinding?.root?.visibility = View.VISIBLE
}
loadingStub?.inflate()
loadingStub?.inflateOrShow()
} else {
loadingBinding?.root?.visibility = View.VISIBLE
}

View File

@ -65,7 +65,6 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
override fun onCreate(savedInstanceState: Bundle?) {
mViewModel = viewModelProviderFromParent(MainWrapperViewModel.Factory(HaloApp.getInstance()))
super.onCreate(savedInstanceState)
DisplayUtils.transparentStatusBar(requireActivity())
initSkeleton()

View File

@ -968,7 +968,7 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
setPullDownPushInternal(pullDownPush, pullDownPushHandler)
}
try {
binding.autoVideoViewStub.inflate()
binding.autoVideoViewStub.inflateOrShow()
} catch (e: Exception) {
SentryHelper.onEvent("VIEW_STUB_INFLATE_ERROR", "digest", e.localizedMessage)
}

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.gh.gamecenter.common.view.MaterializedRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
<com.gh.gamecenter.common.view.MaterializedFrameLayout
android:id="@id/layout_activity_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
@ -97,4 +97,4 @@
</RelativeLayout>
</RelativeLayout>
</com.gh.gamecenter.common.view.MaterializedRelativeLayout>

View File

@ -13,7 +13,6 @@
android:id="@+id/adImage"
android:layout_width="0dp"
android:layout_height="0dp"
android:tint="#01000000"
android:visibility="gone"
app:actualImageScaleType="centerCrop"
app:fadeDuration="0"
@ -26,6 +25,7 @@
android:id="@+id/ad_video"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/startAdIcpContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.View
import android.view.ViewStub
import com.gh.gamecenter.common.R
import com.gh.gamecenter.common.utils.inflateOrShow
/**
* 这是在 BaseLazyFragment 之上添加了一些通用功能的抽象类
@ -66,7 +67,7 @@ abstract class LazyFragment : BaseLazyFragment() {
} else {
mViewStub?.layoutResource = getRealLayoutId()
mViewStub?.setOnInflateListener { _, inflatedView -> onRealLayoutInflated(inflatedView) }
mViewStub?.inflate()?.let { mCachedView = it }
mViewStub?.inflateOrShow()?.let { mCachedView = it }
}
}

View File

@ -1,13 +1,15 @@
package com.gh.gamecenter.common.utils
import androidx.core.util.Pools
import com.facebook.drawee.controller.BaseControllerListener
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.image.ImageInfo
import com.facebook.imagepipeline.request.Postprocessor
import com.gh.gamecenter.core.utils.SingletonHolder
class AsyncImageLoader private constructor() {
fun addAsyncImage(view: SimpleDraweeView?, url: String, loadAsAnimatedImage: Boolean, processor: Postprocessor?) {
fun addAsyncImage(view: SimpleDraweeView?, url: String, loadAsAnimatedImage: Boolean, processor: Postprocessor?, controllerListener: BaseControllerListener<ImageInfo>?) {
try {
val loopThread = LoopThread.getInstance()
val params = loopThread.obtainImageParams()
@ -15,6 +17,7 @@ class AsyncImageLoader private constructor() {
params.url = url
params.loadAsAnimatedImage = loadAsAnimatedImage
params.processor = processor
params.controllerListener = controllerListener
loopThread.addAsyncImage(params)
} catch (e: InterruptedException) {
e.printStackTrace()
@ -86,7 +89,7 @@ class AsyncImageLoader private constructor() {
private fun loadImage(params: ImageLoadParams, isIgnoreWidth: Boolean = false) {
ImageUtils.display(params.view, params.url, params.loadAsAnimatedImage, params.processor, isIgnoreWidth)
ImageUtils.display(params.view, params.url, params.loadAsAnimatedImage, params.processor, isIgnoreWidth, params.controllerListener)
releaseImageParams(params)
}
@ -105,6 +108,7 @@ class AsyncImageLoader private constructor() {
loadAsAnimatedImage = false
processor = null
retryCount = 0
controllerListener = null
mImagePool.release(this)
}
}
@ -120,5 +124,6 @@ class ImageLoadParams(
var url: String = "",
var loadAsAnimatedImage: Boolean = true,
var processor: Postprocessor? = null,
var retryCount: Int = 0
var retryCount: Int = 0,
var controllerListener: BaseControllerListener<ImageInfo>? = null,
)

View File

@ -1698,4 +1698,12 @@ fun RecyclerView.tryToClearRecycler() {
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
}
fun ViewStub.inflateOrShow(): View? =
if (parent != null) {
inflate()
} else {
visibility = View.VISIBLE
null
}

View File

@ -162,8 +162,10 @@ object ImageUtils {
fun displayWithCallback(
draweeView: SimpleDraweeView?,
imageUrl: String?,
noMemoryCache: Boolean = false,
controllerListener: BaseControllerListener<ImageInfo>?
) {
if (noMemoryCache) draweeView?.setTag(TAG_NO_MEMORY_CACHE, true)
displayInternal(
view = draweeView,
url = imageUrl,
@ -319,7 +321,7 @@ object ImageUtils {
val disableMemoryCache = view?.getTag(TAG_NO_MEMORY_CACHE) == true
if (view != null && width == 0 && !isIgnoreWidth) {
AsyncImageLoader.getInstance().addAsyncImage(view, url, loadAsAnimatedImage, processor)
AsyncImageLoader.getInstance().addAsyncImage(view, url, loadAsAnimatedImage, processor, controllerListener)
return@execute
}
var lowResUrl = ""
@ -367,9 +369,10 @@ object ImageUtils {
url: String?,
loadAsAnimatedImage: Boolean = true,
processor: Postprocessor? = null,
isIgnoreWidth: Boolean = false
isIgnoreWidth: Boolean = false,
controllerListener: BaseControllerListener<ImageInfo>? = null
) {
displayInternal(view, url, loadAsAnimatedImage, processor, isIgnoreWidth)
displayInternal(view, url, loadAsAnimatedImage, processor, isIgnoreWidth, controllerListener)
}
/**

View File

@ -21,7 +21,7 @@ import java.util.concurrent.*
*/
object AppExecutor {
private const val CORE_POOL_SIZE = 3
private const val CORE_POOL_SIZE = 6
private const val MAX_POOL_SIZE = 32
@JvmStatic

View File

@ -185,7 +185,9 @@ public class DisplayUtils {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
if (isKeepLowVersionMiui) {
if (isKeepLowVersionMiui
&& "miui".equals(Build.MANUFACTURER)
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
Class clazz = window.getClass();
try {
int darkModeFlag = 0;

View File

@ -575,8 +575,9 @@ public class UserRepository {
@Override
public void onApiFailure(ApiResponse<UserInfoEntity> e) {
super.onApiFailure(e);
mLoginObsResponseUserInfo.postValue(e);
if (loginTag != null) {
mLoginObsResponseUserInfo.postValue(e);
IErrorHelperProvider errorHelper = TheRouter.get(IErrorHelperProvider.class);
if (errorHelper != null) {
errorHelper.handleLoginError(mContext, e.getHttpException(), loginTag.toChinese(), false);

View File

@ -16,7 +16,7 @@ git checkout module_sensors_data/build.gradle
# 开启 mapping 上传
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' '1 a plugins { id "io.sentry.android.gradle" version "3.7.0" } ' app/build.gradle
sed -i '' "1s|^|plugins { id \"io.sentry.android.gradle\" version \"3.7.0\" }\n|" app/build.gradle
else
sed -i '1 a plugins { id "io.sentry.android.gradle" version "3.7.0" }' app/build.gradle
fi
@ -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 -PBUILD_PUSH_TYPE=${BUILD_PUSH_TYPE} --no-daemon
fi
mkdir -p release-app/${versionName}_${versionCode}

View File

@ -165,7 +165,7 @@ if [ "${sdk_platform}" != "" ]; then
echo "光环助手_${versionName}_${versionCode}_神马推广包_${git_sha}_${build_time}"
cp -R app/build/outputs/apk/smCn/release/app-sm-cn-release.apk "${apk_release_path}"
fi
updateChannelIfNeeded "${output}/${apk_release_path}"
updateChannelIfNeeded "${apk_release_path}"
else
apk_release_path="${output}/${PACKAGE_NAME}_${versionName}_${versionCode}_${MODULE_VERSION}_${va_version}_${unix_timestamp}_${buildType}.apk"

2
vasdk

Submodule vasdk updated: 267757b094...af3c440926