Compare commits
59 Commits
feat/GHZSC
...
refactor/s
| Author | SHA1 | Date | |
|---|---|---|---|
| 5de629cfdd | |||
| f026623600 | |||
| 2f5ee0eb91 | |||
| e7651e8092 | |||
| 82d51d6375 | |||
| 6080edfd8a | |||
| d9713571c9 | |||
| b466525e8b | |||
| 2a25675dce | |||
| 5486ad8818 | |||
| 5552fcf7bc | |||
| 782a0af13c | |||
| c6c2d9cd12 | |||
| f929a08e46 | |||
| e48f96d7d7 | |||
| 3cc95dbc08 | |||
| f75396d7ae | |||
| 72c3df7fa6 | |||
| 2d4920cfb0 | |||
| 2d30b97cca | |||
| 40346e3c9a | |||
| 7f601c856a | |||
| 6e56f2e3a0 | |||
| e2fbda1e4c | |||
| 1e88ba8539 | |||
| 0f43b5610d | |||
| 04dcfbab2e | |||
| 8dd33cb599 | |||
| af5826962b | |||
| 9883f8d5c0 | |||
| 848207784e | |||
| fc294f9e7b | |||
| 96cd53a2c9 | |||
| 5458c93475 | |||
| 675d63c1d6 | |||
| 1040f5ff4d | |||
| 97be320529 | |||
| 0e086c9452 | |||
| dc677d1b9f | |||
| fa50c6e417 | |||
| dc96f2274f | |||
| ad5f5048a6 | |||
| e5491fb297 | |||
| ff96eaafee | |||
| 59cde4e2bf | |||
| cc0c7c7fae | |||
| 9e9ce6a84f | |||
| 7d0b500ff9 | |||
| 425456b263 | |||
| f6abab9a2d | |||
| d194f969e4 | |||
| 95f66344fb | |||
| 570e2fa9bc | |||
| 9e07080043 | |||
| e10a329159 | |||
| b3bc7b43f7 | |||
| 811d42457c | |||
| ac0b819ea9 | |||
| d931fb5940 |
@ -72,7 +72,6 @@ android_build:
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- feat/GHZSCY-6783
|
||||
|
||||
# 代码检查
|
||||
sonarqube_analysis:
|
||||
@ -158,4 +157,3 @@ oss-upload&send-email:
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- feat/GHZSCY-6783
|
||||
|
||||
@ -65,7 +65,7 @@ public class InstallUtils {
|
||||
if (!TextUtils.isEmpty(installVersion) && downloadEntity != null &&
|
||||
installVersion.equals(downloadEntity.getVersionName())) {
|
||||
if (!downloadEntity.isPluggable() || PackageUtils.isSignedByGh(context, packageName)) {
|
||||
EventBus.getDefault().post(new EBPackage(EBPackage.TYPE_INSTALLED, packageName, installVersion));
|
||||
EventBus.getDefault().post(new EBPackage(EBPackage.TYPE_INSTALLED, packageName, installVersion, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,7 +82,7 @@ public class InstallUtils {
|
||||
keys.add(packageName);
|
||||
} else if (!list.contains(packageName)) {
|
||||
keys.add(packageName);
|
||||
EventBus.getDefault().post(new EBPackage("卸载", packageName, ""));
|
||||
EventBus.getDefault().post(new EBPackage("卸载", packageName, "", false));
|
||||
}
|
||||
}
|
||||
for (String key : keys) {
|
||||
|
||||
@ -27,7 +27,9 @@ import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
@ -124,11 +126,12 @@ object UsageStatsHelper {
|
||||
&& curEvent.className == nextEvent.className
|
||||
) {
|
||||
val diff = nextEvent.timeStamp - curEvent.timeStamp
|
||||
val packageName = curEvent.packageName ?: continue
|
||||
|
||||
if (pakAndTime[curEvent.packageName] == null) {
|
||||
pakAndTime[curEvent.packageName] = diff
|
||||
if (pakAndTime[packageName] == null) {
|
||||
pakAndTime[packageName] = diff
|
||||
} else {
|
||||
pakAndTime[curEvent.packageName] = pakAndTime[curEvent.packageName]!! + diff
|
||||
pakAndTime[packageName] = pakAndTime[packageName]!! + diff
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,7 +178,7 @@ object UsageStatsHelper {
|
||||
return
|
||||
}
|
||||
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), postBody.toString())
|
||||
val body = postBody.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
mApi.postUsageStatus(body, UserManager.getInstance().userId)
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
|
||||
@ -34,7 +34,9 @@ import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
@ -216,7 +218,7 @@ object PackageObserver {
|
||||
try {
|
||||
jsonObject.put("game_id", gameId)
|
||||
jsonObject.put("package", packageName)
|
||||
val rBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val rBody = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
RetrofitManager.getInstance().api
|
||||
.postPlayedGame(UserManager.getInstance().userId, rBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
@ -94,8 +94,8 @@ object ExoCacheManager {
|
||||
response =
|
||||
OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).readTimeout(5, TimeUnit.SECONDS).build()
|
||||
.newCall(request).execute()
|
||||
if (response!!.isSuccessful && response.body() != null) {
|
||||
val length = response.body()!!.contentLength()
|
||||
if (response!!.isSuccessful && response.body != null) {
|
||||
val length = response.body!!.contentLength()
|
||||
contentLength = if (length == 0L) -1L else length
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
||||
@ -238,7 +238,7 @@ open class SearchActivity : BaseActivity() {
|
||||
GlobalActivityManager.getCurrentPageEntity().pageId,
|
||||
GlobalActivityManager.getCurrentPageEntity().pageName,
|
||||
key ?: "",
|
||||
TRACK_SEARCH_TYPE_DEFAULT,
|
||||
TRACK_SEARCH_TYPE_RANK,
|
||||
mSourceEntrance
|
||||
)
|
||||
}
|
||||
@ -433,12 +433,14 @@ open class SearchActivity : BaseActivity() {
|
||||
const val TRACK_SEARCH_TYPE_INPUT = "输入搜索"
|
||||
const val TRACK_SEARCH_TYPE_DEFAULT = "默认搜索"
|
||||
const val TRACK_SEARCH_TYPE_HISTORY = "历史搜索"
|
||||
const val TRACK_SEARCH_TYPE_RANK = "榜单搜索"
|
||||
|
||||
@JvmStatic
|
||||
fun toTrackSearchType(type: String) = when (type) {
|
||||
SearchType.AUTO.value -> TRACK_SEARCH_TYPE_AUTO
|
||||
SearchType.MANUAL.value -> TRACK_SEARCH_TYPE_INPUT
|
||||
SearchType.HISTORY.value -> TRACK_SEARCH_TYPE_HISTORY
|
||||
SearchType.RANK.value -> TRACK_SEARCH_TYPE_RANK
|
||||
else -> TRACK_SEARCH_TYPE_DEFAULT
|
||||
}
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ class AmwaySearchDefaultFragment : SearchDefaultFragment() {
|
||||
mViewModel.playedGames.observeNonNull(viewLifecycleOwner) {
|
||||
defaultViewModel?.isExistHotSearch = it.isNotEmpty()
|
||||
updateView()
|
||||
mBinding.searchDiscoveryList.run {
|
||||
mBinding.hotList.run {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = AmwaySearchAdapter(context, mViewModel, "安利墙搜索-最近玩过").apply { setData(it) }
|
||||
}
|
||||
@ -43,7 +43,7 @@ class AmwaySearchDefaultFragment : SearchDefaultFragment() {
|
||||
|
||||
override fun initView() {
|
||||
mBinding = mAmwayBinding.searchContent
|
||||
mBinding.searchDiscoveryHeadContainer.headTitle.text = "最近玩过"
|
||||
mBinding.hotHeadContainer.headTitle.text = "最近玩过"
|
||||
mBinding.historyFlexContainer.setLimitHeight(mFlexMaxHeight)
|
||||
|
||||
updateHistorySearchView(null)
|
||||
|
||||
@ -309,7 +309,8 @@ class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>
|
||||
// 安装/卸载 事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(busFour: EBPackage) {
|
||||
if (busFour.isInstalledOrUninstalled()) {
|
||||
// 忽略首次初始化触发的事件
|
||||
if (!busFour.fromInit && busFour.isInstalledOrUninstalled()) {
|
||||
mAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ open class BaseCloudArchiveViewModel(application: Application, private val mConf
|
||||
)
|
||||
.enqueue(object : Callback {
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
mArchiveConfigStr = response.body()?.string() ?: ""
|
||||
mArchiveConfigStr = response.body?.string() ?: ""
|
||||
callback?.invoke(mArchiveConfigStr)
|
||||
}
|
||||
|
||||
|
||||
@ -161,6 +161,7 @@ class DownloadFragment : BaseFragment_TabLayout() {
|
||||
val showOnFailed = downloadManagerAd?.displayRule?.onFailedAction == "show"
|
||||
if ((showThirdPartyAd && thirdPartyAd != null) || (!showThirdPartyAd && thirdPartyAd != null && ownerAd == null)) {
|
||||
initThirdPartyAd(downloadManagerAd, thirdPartyAd) { isSuccess ->
|
||||
if (!isAdded) return@initThirdPartyAd
|
||||
mBinding.maskView.goneIf(!isSuccess)
|
||||
if (!isSuccess && ownerAd != null && showOnFailed) {
|
||||
mSlideInterval = ownerAd.adSource?.sliderInterval ?: -1
|
||||
@ -215,7 +216,7 @@ class DownloadFragment : BaseFragment_TabLayout() {
|
||||
}
|
||||
|
||||
private fun initOwnerAd(adConfig: AdConfig) {
|
||||
if (adConfig.id.isEmpty()) return
|
||||
if (!isAdded || adConfig.id.isEmpty()) return
|
||||
mAdGameViewModel = viewModelProvider(AdGameViewModel.Factory(adConfig))
|
||||
initAdGameBanner(adConfig)
|
||||
mBinding.closeAdIv.setOnClickListener {
|
||||
@ -249,6 +250,7 @@ class DownloadFragment : BaseFragment_TabLayout() {
|
||||
adConfig.displayRule.onFailedAction == "show" && adConfig.thirdPartyAd != null) {
|
||||
// 自有广告游戏为空时,显示第三方广告
|
||||
initThirdPartyAd(adConfig, adConfig.thirdPartyAd) { isSuccess ->
|
||||
if (!isAdded) return@initThirdPartyAd
|
||||
mBinding.maskView.goneIf(!isSuccess)
|
||||
if (isSuccess) {
|
||||
SPUtils.setLong(Constants.SP_LAST_DOWNLOAD_MANAGER_AD_SHOW_TIME, System.currentTimeMillis())
|
||||
|
||||
@ -220,7 +220,7 @@ class NewInstalledGameFragment : ToolbarFragment() {
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(packageEb: EBPackage) {
|
||||
if (packageEb.isInstalledOrUninstalled()) {
|
||||
if (!packageEb.fromInit && packageEb.isInstalledOrUninstalled()) {
|
||||
mInstallGameViewModel.initData(
|
||||
PackagesManager.filterSameApk(
|
||||
PackagesManager.filterDownloadBlackPackage(mPackageViewModel?.getGameInstalledLiveData()?.value as MutableList<GameInstall>?)
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
package com.gh.gamecenter.eventbus
|
||||
|
||||
class EBPackage(var type: String, var packageName: String, var versionName: String?) {
|
||||
/**
|
||||
* @param fromInit 实体生成是否来自于初始化
|
||||
*/
|
||||
class EBPackage(var type: String,
|
||||
var packageName: String,
|
||||
var versionName: String?,
|
||||
val fromInit: Boolean = false) {
|
||||
var gameId: String? = null
|
||||
var isVGame: Boolean = false // 是否是畅玩游戏
|
||||
|
||||
|
||||
@ -39,14 +39,14 @@ class ForumOrUserSearchDefaultFragment : SearchDefaultFragment() {
|
||||
|
||||
override fun initView() {
|
||||
mBinding = FragmentSearchDefaultBinding.bind(mCachedView)
|
||||
mBinding.searchDiscoveryTagHeadContainer.root.visibility = View.GONE
|
||||
mBinding.searchDiscoveryTagFlexContainer.visibility = View.GONE
|
||||
mBinding.hotTagHeadContainer.root.visibility = View.GONE
|
||||
mBinding.hotTagFlexContainer.visibility = View.GONE
|
||||
if (mEntrance == "论坛首页" || mEntrance == "搜索栏") {
|
||||
mBinding.searchDiscoveryHeadContainer.headTitle.text = "热门论坛"
|
||||
mBinding.hotHeadContainer.headTitle.text = "热门论坛"
|
||||
mViewModel.getForumSearchHotContent()
|
||||
} else {
|
||||
mBinding.searchDiscoveryHeadContainer.root.visibility = View.GONE
|
||||
mBinding.searchDiscoveryList.visibility = View.GONE
|
||||
mBinding.hotHeadContainer.root.visibility = View.GONE
|
||||
mBinding.hotList.visibility = View.GONE
|
||||
}
|
||||
val params = mBinding.historyHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams
|
||||
params.topMargin = 0.5f.dip2px()
|
||||
|
||||
@ -67,6 +67,8 @@ class ColumnCollectionDetailFragment : LazyListFragment<LinkEntity, ColumnCollec
|
||||
}
|
||||
|
||||
private fun showSubjectTab(linkEntityList: MutableList<LinkEntity>) {
|
||||
if (!isVisible) return
|
||||
|
||||
val subjectDataList = arrayListOf<SubjectData>()
|
||||
|
||||
for (link in linkEntityList) {
|
||||
|
||||
@ -45,7 +45,9 @@ import com.zhihu.matisse.Matisse
|
||||
import com.zhihu.matisse.internal.utils.PathUtils
|
||||
import io.reactivex.disposables.Disposable
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import java.io.File
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
@ -420,10 +422,8 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
requestMap["type"] = mGameType
|
||||
}
|
||||
|
||||
val body = RequestBody.create(
|
||||
MediaType.parse("application/json"),
|
||||
GsonUtils.toJson(requestMap)
|
||||
)
|
||||
val body = GsonUtils.toJson(requestMap)
|
||||
.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
mViewModel.uploadGames(body)
|
||||
}
|
||||
|
||||
|
||||
@ -968,7 +968,7 @@ class GameCollectionDetailFragment :
|
||||
// 安装/卸载 事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(busFour: EBPackage) {
|
||||
if (busFour.isInstalledOrUninstalled()) {
|
||||
if (!busFour.fromInit && busFour.isInstalledOrUninstalled()) {
|
||||
if (EBPackage.TYPE_INSTALLED == busFour.type
|
||||
&& UserManager.getInstance().isLoggedIn
|
||||
&& (mEntity?.count?.playedGame ?: 0) < (mEntity?.count?.game ?: 0)
|
||||
|
||||
@ -7,6 +7,9 @@ import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.view.animation.AccelerateDecelerateInterpolator
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.gh.common.util.DirectUtils
|
||||
@ -21,6 +24,17 @@ class GameCollectionAmwayViewHolder(var binding: GameCollectionSquareAmwayItemBi
|
||||
private val mAdapter = GameCollectionAmwayAdapter(binding.root.context)
|
||||
private val mLooperHandle = LooperHandle(this)
|
||||
private val mSlideLooperKey = 333
|
||||
private val mLifecycleObserver = object : DefaultLifecycleObserver {
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
super.onResume(owner)
|
||||
startAutoPlay()
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
super.onPause(owner)
|
||||
stopAutoPlay()
|
||||
}
|
||||
}
|
||||
|
||||
fun bindAmway(amwayList: List<AmwayCommentEntity>, viewModel: GameCollectionSquareViewModel) {
|
||||
mAdapter.setAmwayList(amwayList)
|
||||
@ -54,6 +68,14 @@ class GameCollectionAmwayViewHolder(var binding: GameCollectionSquareAmwayItemBi
|
||||
mLooperHandle.removeMessages(mSlideLooperKey)
|
||||
}
|
||||
|
||||
fun onViewAttach(lifecycle: Lifecycle) {
|
||||
lifecycle.addObserver(mLifecycleObserver)
|
||||
}
|
||||
|
||||
fun onViewDetach(lifecycle: Lifecycle) {
|
||||
lifecycle.removeObserver(mLifecycleObserver)
|
||||
}
|
||||
|
||||
fun ViewPager2.setCurrentItem(
|
||||
item: Int,
|
||||
duration: Long,
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.gamecenter.gamecollection.square
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.util.DirectUtils
|
||||
@ -23,6 +24,7 @@ import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
|
||||
class GameCollectionBannerAdapter(
|
||||
context: Context,
|
||||
private val mLifecycleOwner: LifecycleOwner,
|
||||
private val mViewModel: GameCollectionSquareViewModel,
|
||||
var mBannerList: List<CarouselEntity> = emptyList(),
|
||||
private var mAmwayListItem: List<AmwayCommentEntity>? = null,
|
||||
@ -78,6 +80,20 @@ class GameCollectionBannerAdapter(
|
||||
return index
|
||||
}
|
||||
|
||||
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
|
||||
super.onViewAttachedToWindow(holder)
|
||||
if (holder is GameCollectionAmwayViewHolder) {
|
||||
holder.onViewAttach(mLifecycleOwner.lifecycle)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
|
||||
super.onViewDetachedFromWindow(holder)
|
||||
if (holder is GameCollectionAmwayViewHolder) {
|
||||
holder.onViewDetach(mLifecycleOwner.lifecycle)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ITEM_AMWAY = 100
|
||||
const val ITEM_BANNER = 101
|
||||
|
||||
@ -12,6 +12,9 @@ import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.PagerSnapHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -47,6 +50,7 @@ import java.lang.ref.WeakReference
|
||||
|
||||
class GameCollectionSquareAdapter(
|
||||
context: Context,
|
||||
private val mLifecycleOwner: LifecycleOwner,
|
||||
private val mIsHome: Boolean = false,
|
||||
private val mFragment: GameCollectionSquareFragment,
|
||||
private val mViewModel: GameCollectionSquareViewModel,
|
||||
@ -157,7 +161,7 @@ class GameCollectionSquareAdapter(
|
||||
when (holder) {
|
||||
is GameCollectionHeaderItemViewHolder -> {
|
||||
val itemData = mEntityList[position]
|
||||
holder.bindHeader(itemData, mBasicExposureSource, mViewModel)
|
||||
holder.bindHeader(mLifecycleOwner, itemData, mBasicExposureSource, mViewModel)
|
||||
}
|
||||
|
||||
is GameCollectionFilterItemViewHolder -> holder.bindFilter(mFragment, mViewModel, mRefreshCallback)
|
||||
@ -211,6 +215,20 @@ class GameCollectionSquareAdapter(
|
||||
override fun getItemCount() =
|
||||
if (mEntityList.isNullOrEmpty()) 0 else if (mIsHome && mEntityList.size == 2) mEntityList.size else mEntityList.size + 1
|
||||
|
||||
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
|
||||
super.onViewAttachedToWindow(holder)
|
||||
if (holder is GameCollectionHeaderItemViewHolder) {
|
||||
holder.onViewAttach(mLifecycleOwner.lifecycle)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
|
||||
super.onViewDetachedFromWindow(holder)
|
||||
if (holder is GameCollectionHeaderItemViewHolder) {
|
||||
holder.onViewDetach(mLifecycleOwner.lifecycle)
|
||||
}
|
||||
}
|
||||
|
||||
class GameCollectionHeaderItemViewHolder(val binding: ItemGameCollectionHeaderBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
private lateinit var mBannerAdapter: GameCollectionBannerAdapter
|
||||
@ -218,8 +236,20 @@ class GameCollectionSquareAdapter(
|
||||
private lateinit var mBannerLayoutManager: LinearLayoutManager
|
||||
private val mLooperHandle = LooperHandle(this)
|
||||
private val mSlideLooperKey = 111
|
||||
private val mLifecycleObserver = object : DefaultLifecycleObserver {
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
super.onResume(owner)
|
||||
startAutoPlay()
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
super.onPause(owner)
|
||||
stopAutoPlay()
|
||||
}
|
||||
}
|
||||
|
||||
fun bindHeader(
|
||||
lifecycleOwner: LifecycleOwner,
|
||||
itemData: GameCollectionListItemData,
|
||||
mBasicExposureSource: List<ExposureSource>,
|
||||
viewModel: GameCollectionSquareViewModel
|
||||
@ -249,6 +279,7 @@ class GameCollectionSquareAdapter(
|
||||
mBannerLayoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
|
||||
mBannerAdapter = GameCollectionBannerAdapter(
|
||||
context,
|
||||
lifecycleOwner,
|
||||
viewModel,
|
||||
bannerList,
|
||||
amwayListItem,
|
||||
@ -345,6 +376,14 @@ class GameCollectionSquareAdapter(
|
||||
mLooperHandle.removeMessages(mSlideLooperKey)
|
||||
}
|
||||
|
||||
fun onViewAttach(lifecycle: Lifecycle) {
|
||||
lifecycle.addObserver(mLifecycleObserver)
|
||||
}
|
||||
|
||||
fun onViewDetach(lifecycle: Lifecycle) {
|
||||
lifecycle.removeObserver(mLifecycleObserver)
|
||||
}
|
||||
|
||||
class LooperHandle(viewHolder: GameCollectionHeaderItemViewHolder) : Handler(Looper.getMainLooper()) {
|
||||
private val mWeakReference: WeakReference<GameCollectionHeaderItemViewHolder> = WeakReference(viewHolder)
|
||||
|
||||
|
||||
@ -138,6 +138,7 @@ class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, Gam
|
||||
mGuideContainer?.visibility = View.GONE
|
||||
} else {
|
||||
if (mExposureEventList.isNotEmpty()) ExposureManager.log(mExposureEventList)
|
||||
stopAutoPlay()
|
||||
}
|
||||
val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
|
||||
NewFlatLogUtils.logGameCollectSquareStayTime(stayTime, if (mUseAlternativeLayout) "首页tab栏" else "游戏单广场")
|
||||
@ -175,6 +176,8 @@ class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, Gam
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
startAutoPlay()
|
||||
}
|
||||
mElapsedHelper.resetCounting()
|
||||
mElapsedHelper.resumeCounting()
|
||||
@ -270,6 +273,7 @@ class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, Gam
|
||||
mAdapter =
|
||||
GameCollectionSquareAdapter(
|
||||
requireContext(),
|
||||
viewLifecycleOwner,
|
||||
mUseAlternativeLayout,
|
||||
this,
|
||||
mViewModel,
|
||||
@ -382,6 +386,7 @@ class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, Gam
|
||||
|
||||
val bannerAdapter = GameCollectionBannerAdapter(
|
||||
requireContext(),
|
||||
viewLifecycleOwner,
|
||||
mViewModel,
|
||||
mEntrance = "游戏单广场",
|
||||
mBasicExposureSource = mBasicExposureSourceList
|
||||
@ -515,7 +520,8 @@ class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, Gam
|
||||
}
|
||||
|
||||
private fun startAutoPlay() {
|
||||
if ((mDefaultBinding.headerContainer.bannerRv.adapter as GameCollectionBannerAdapter).getActualSize() <= 1) return
|
||||
val bannerAdapter = mDefaultBinding.headerContainer.bannerRv.adapter as? GameCollectionBannerAdapter
|
||||
if (bannerAdapter == null || bannerAdapter.getActualSize() <= 1) return
|
||||
stopAutoPlay()
|
||||
mLooperHandle.sendEmptyMessageDelayed(mSlideLooperKey, BANNER_LOOP_TIME)
|
||||
}
|
||||
|
||||
@ -394,7 +394,7 @@ class SpecialDownloadDialogFragment : BaseDraggableDialogFragment() {
|
||||
SensorsBridge.trackDownloadComponentsContentClick(
|
||||
gameId = gameEntity.id,
|
||||
gameName = gameEntity.name ?: "unknown",
|
||||
gameSchemeType = gameEntity.gameBitChinese,
|
||||
gameSchemaType = gameEntity.gameBitChinese,
|
||||
downloadStatus = gameEntity.downloadStatusChinese,
|
||||
gameType = gameEntity.categoryChinese,
|
||||
downloadType = if (asVGame) "畅玩下载" else "本地下载",
|
||||
@ -405,7 +405,7 @@ class SpecialDownloadDialogFragment : BaseDraggableDialogFragment() {
|
||||
SensorsBridge.trackDownloadComponentsShow(
|
||||
gameId = gameEntity.id,
|
||||
gameName = gameEntity.name ?: "unknown",
|
||||
gameSchemeType = gameEntity.gameBitChinese,
|
||||
gameSchemaType = gameEntity.gameBitChinese,
|
||||
downloadStatus = gameEntity.downloadStatusChinese,
|
||||
gameType = gameEntity.categoryChinese,
|
||||
downloadType = if (asVGame) "畅玩下载" else "本地下载",
|
||||
|
||||
@ -45,7 +45,9 @@ import com.gh.gamecenter.login.user.UserManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
|
||||
@ -541,7 +543,7 @@ class RatingEditActivity : ToolBarActivity(), KeyboardHeightObserver {
|
||||
jsonObject.put("rom", MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName)
|
||||
jsonObject.put("again", again)
|
||||
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
|
||||
CheckLoginUtils.checkLogin(this, mEntrance) {
|
||||
mViewModel.postGameComment(mComment?.id ?: "", body)
|
||||
|
||||
@ -140,7 +140,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
searchToolbarTabWrapperViewModel =
|
||||
viewModelProviderFromParent(
|
||||
SearchToolbarTabWrapperViewModel.Factory(multiTabNavId, noTabLinkId),
|
||||
multiTabNavId
|
||||
multiTabNavId + noTabLinkId
|
||||
)
|
||||
}
|
||||
if (bottomTabId.isNotEmpty()) {
|
||||
|
||||
@ -806,7 +806,7 @@ class CustomPageRepository private constructor(
|
||||
|
||||
fun loadChangeSubjectGame(subjectEntity: SubjectEntity): Observable<List<GameEntity>> =
|
||||
if (subjectEntity.isWechatColumnCPM) {// 微信小游戏CPM专题的“换一批”接口
|
||||
wGameSubjectCPMRemoteDataSource.getRecommendCPMList(2, 30).toObservable()
|
||||
wGameSubjectCPMRemoteDataSource.getRecommendCPMList(2, 10).toObservable()
|
||||
} else {
|
||||
remoteDataSource.loadChangeSubjectGame(subjectEntity)
|
||||
}
|
||||
|
||||
@ -123,8 +123,12 @@ abstract class BaseCustomViewHolder(
|
||||
_title.name = subject.name
|
||||
tvTitle.text = subject.name ?: ""
|
||||
}
|
||||
if (_title.rightText != subject.home) {
|
||||
_title.rightText = subject.home
|
||||
val home = subject.home ?: ""
|
||||
val homeText = subject.homeText ?: ""
|
||||
if (_title.rightHome != home || _title.rightText != homeText) {
|
||||
_title.rightHome = home
|
||||
_title.rightText = homeText
|
||||
|
||||
fun getHomeText(defaultResId: Int): String =
|
||||
if (subject.homeText.isNullOrBlank()) {
|
||||
defaultResId.toResString()
|
||||
@ -363,6 +367,7 @@ abstract class BaseCustomViewHolder(
|
||||
|
||||
data class TitleData(
|
||||
var name: String? = null,
|
||||
var rightHome: String? = null,
|
||||
var rightText: String? = null,
|
||||
var isRefresh: Boolean = false,
|
||||
var icon: String? = null,
|
||||
|
||||
@ -13,7 +13,7 @@ object HeadUpDisplayLogHelper {
|
||||
source = source,
|
||||
downloadType = if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
|
||||
downloadStatus = downloadEntity.getMetaExtra(Constants.DOWNLOAD_STATUS_IN_CHINESE),
|
||||
gameSchemeType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameSchemaType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameType = downloadEntity.getMetaExtra(Constants.GAME_CATEGORY_IN_CHINESE),
|
||||
gameId = downloadEntity.gameId,
|
||||
gameName = downloadEntity.name
|
||||
@ -25,7 +25,7 @@ object HeadUpDisplayLogHelper {
|
||||
source = source,
|
||||
downloadType = if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
|
||||
downloadStatus = downloadEntity.getMetaExtra(Constants.DOWNLOAD_STATUS_IN_CHINESE),
|
||||
gameSchemeType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameSchemaType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameType = downloadEntity.getMetaExtra(Constants.GAME_CATEGORY_IN_CHINESE),
|
||||
gameId = downloadEntity.gameId,
|
||||
gameName = downloadEntity.name
|
||||
@ -36,7 +36,7 @@ object HeadUpDisplayLogHelper {
|
||||
SensorsBridge.trackAutomaticInstallationPromptBarShow(
|
||||
downloadType = if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
|
||||
downloadStatus = downloadEntity.getMetaExtra(Constants.DOWNLOAD_STATUS_IN_CHINESE),
|
||||
gameSchemeType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameSchemaType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameType = downloadEntity.getMetaExtra(Constants.GAME_CATEGORY_IN_CHINESE),
|
||||
gameId = downloadEntity.gameId,
|
||||
gameName = downloadEntity.name
|
||||
@ -47,7 +47,7 @@ object HeadUpDisplayLogHelper {
|
||||
SensorsBridge.trackAutomaticInstallationPromptBarClick(
|
||||
downloadType = if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
|
||||
downloadStatus = downloadEntity.getMetaExtra(Constants.DOWNLOAD_STATUS_IN_CHINESE),
|
||||
gameSchemeType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameSchemaType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameType = downloadEntity.getMetaExtra(Constants.GAME_CATEGORY_IN_CHINESE),
|
||||
gameId = downloadEntity.gameId,
|
||||
gameName = downloadEntity.name
|
||||
|
||||
@ -6,7 +6,9 @@ import com.gh.gamecenter.retrofit.service.ApiService
|
||||
import com.gh.gamecenter.subject.ISubjectRepository
|
||||
import io.reactivex.Observable
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.ResponseBody
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
|
||||
class QGameSubjectRepository(
|
||||
private val api: ApiService = RetrofitManager.getInstance().newApi
|
||||
@ -17,7 +19,7 @@ class QGameSubjectRepository(
|
||||
}
|
||||
|
||||
override fun getSubjectName(column_id: String?): Observable<ResponseBody> {
|
||||
return Observable.just(ResponseBody.create(MediaType.parse("application/json"), "{\"name\": \"专题\"}"))
|
||||
return Observable.just("{\"name\": \"专题\"}".toResponseBody("application/json".toMediaTypeOrNull()))
|
||||
}
|
||||
|
||||
}
|
||||
@ -14,7 +14,7 @@ class WGameSubjectCPMRemoteDataSource(
|
||||
private val api: WGameCPMApiService = RetrofitManager.getInstance().wGameCPMApi
|
||||
) {
|
||||
|
||||
fun getRecommendCPMList(page: Int, pageSize: Int = 20): Single<MutableList<GameEntity>> {
|
||||
fun getRecommendCPMList(page: Int, pageSize: Int = 10): Single<MutableList<GameEntity>> {
|
||||
val meta = MetaUtil.getMeta()
|
||||
val request = mapOf(
|
||||
"head" to mapOf(
|
||||
|
||||
@ -4,7 +4,9 @@ import com.gh.gamecenter.entity.SubjectSettingEntity
|
||||
import com.gh.gamecenter.subject.ISubjectRepository
|
||||
import io.reactivex.Observable
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.ResponseBody
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
|
||||
class WGameSubjectCPMRepository : ISubjectRepository {
|
||||
override fun getColumnSettings(column_id: String?): Observable<SubjectSettingEntity> {
|
||||
@ -12,6 +14,6 @@ class WGameSubjectCPMRepository : ISubjectRepository {
|
||||
}
|
||||
|
||||
override fun getSubjectName(column_id: String?): Observable<ResponseBody> {
|
||||
return Observable.just(ResponseBody.create(MediaType.parse("application/json"), "{\"name\": \"专题\"}"))
|
||||
return Observable.just("{\"name\": \"专题\"}".toResponseBody("application/json".toMediaTypeOrNull()))
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,9 @@ import com.gh.gamecenter.retrofit.service.ApiService
|
||||
import com.gh.gamecenter.subject.ISubjectRepository
|
||||
import io.reactivex.Observable
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.ResponseBody
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
|
||||
class WGameSubjectRepository(
|
||||
private val api: ApiService = RetrofitManager.getInstance().newApi
|
||||
@ -16,6 +18,6 @@ class WGameSubjectRepository(
|
||||
}
|
||||
|
||||
override fun getSubjectName(column_id: String?): Observable<ResponseBody> {
|
||||
return Observable.just(ResponseBody.create(MediaType.parse("application/json"), "{\"name\": \"专题\"}"))
|
||||
return Observable.just("{\"name\": \"专题\"}".toResponseBody("application/json".toMediaTypeOrNull()))
|
||||
}
|
||||
}
|
||||
@ -119,7 +119,8 @@ object PackageRepository {
|
||||
packageKey = packageFilterManager.packageKey,
|
||||
filteredList = filteredList,
|
||||
isVGame = false,
|
||||
updateInstallStatus = true
|
||||
updateInstallStatus = true,
|
||||
fromInit = true
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -256,13 +257,15 @@ object PackageRepository {
|
||||
* @param onWorkerThreadOnly 是否在工作线程执行
|
||||
* @param isVGame 包名列表是否为畅玩游戏
|
||||
* @param updateInstallStatus 更新安装状态 (通过 EventBus 来进行)
|
||||
* @param fromInit 是否来自数据首次初始化
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
private fun loadInstalledGameDigestAndNotifyData(
|
||||
packageKey: String,
|
||||
filteredList: ArrayList<String>,
|
||||
isVGame: Boolean = false,
|
||||
updateInstallStatus: Boolean = false
|
||||
updateInstallStatus: Boolean = false,
|
||||
fromInit: Boolean = false
|
||||
) {
|
||||
var isNotifyUpdate = false
|
||||
val maxPageCount = (filteredList.size / PAGE_SIZE) + 1
|
||||
@ -291,7 +294,7 @@ object PackageRepository {
|
||||
|
||||
for (game in validGames) {
|
||||
val shouldNotifyChanges =
|
||||
validateGameAndPostChanges(gh_id, game, pkgName, isVGame, updateInstallStatus)
|
||||
validateGameAndPostChanges(gh_id, game, pkgName, isVGame, updateInstallStatus, fromInit)
|
||||
if (!isNotifyUpdate && shouldNotifyChanges) {
|
||||
isNotifyUpdate = true
|
||||
}
|
||||
@ -317,7 +320,8 @@ object PackageRepository {
|
||||
game: GameEntity,
|
||||
pkgName: String,
|
||||
isVGame: Boolean,
|
||||
updateInstallStatus: Boolean
|
||||
updateInstallStatus: Boolean,
|
||||
fromInit: Boolean = false
|
||||
): Boolean {
|
||||
if (ghId == null || ghId == game.id) {
|
||||
gameInstalled.add(GameInstall.transformGameInstall(game, pkgName, isVGame))
|
||||
@ -328,7 +332,7 @@ object PackageRepository {
|
||||
|
||||
if (updateInstallStatus) {
|
||||
EventBus.getDefault()
|
||||
.post(EBPackage(EBPackage.TYPE_INSTALLED, pkgName, game.getApk().firstOrNull()?.version))
|
||||
.post(EBPackage(EBPackage.TYPE_INSTALLED, pkgName, game.getApk().firstOrNull()?.version, fromInit))
|
||||
}
|
||||
|
||||
if (isCanUpdate || isCanPluggable) {
|
||||
|
||||
@ -374,12 +374,14 @@ class HaloPersonalFragment : BaseLazyFragment() {
|
||||
}
|
||||
|
||||
mSuperiorChain?.registerInferiorChain(mPriorityChain)
|
||||
startBannerAutoPlay()
|
||||
}
|
||||
|
||||
override fun onFragmentPause() {
|
||||
super.onFragmentPause()
|
||||
|
||||
mSuperiorChain?.unregisterInferiorChain(mPriorityChain)
|
||||
stopBannerAutoPlay()
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult", "SetTextI18n")
|
||||
@ -1011,7 +1013,7 @@ class HaloPersonalFragment : BaseLazyFragment() {
|
||||
}
|
||||
|
||||
private fun startBannerAutoPlay() {
|
||||
if (mPersonalBannerAdapter.getActualSize() < 2) return
|
||||
if (!::mPersonalBannerAdapter.isInitialized || mPersonalBannerAdapter.getActualSize() < 2) return
|
||||
stopBannerAutoPlay()
|
||||
mLooperHandle.sendEmptyMessageDelayed(mSlideLooperKey, BANNER_LOOP_TIME)
|
||||
}
|
||||
|
||||
@ -20,7 +20,9 @@ import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
@ -75,7 +77,7 @@ class InstalledGameDialog(
|
||||
jsonObject.put("package", game.packageName)
|
||||
objects.put(jsonObject)
|
||||
}
|
||||
val requestBody = RequestBody.create(MediaType.parse("application/json"), objects.toString())
|
||||
val requestBody = objects.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
RetrofitManager.getInstance().api
|
||||
.postPlayedGames(UserManager.getInstance().userId, requestBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
@ -25,7 +25,9 @@ import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.json.JSONObject
|
||||
@ -259,10 +261,8 @@ class AnswerDetailViewModel(application: Application) : AndroidViewModel(applica
|
||||
fun toggleComment(answerId: String, isCommentable: Boolean) {
|
||||
val params = HashMap<String, Boolean>()
|
||||
params["commentable"] = isCommentable
|
||||
val body = RequestBody.create(
|
||||
MediaType.parse("application/json"),
|
||||
JSONObject(params as Map<*, *>).toString()
|
||||
)
|
||||
val body = JSONObject(params as Map<*, *>).toString()
|
||||
.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
|
||||
RetrofitManager.getInstance()
|
||||
.api
|
||||
|
||||
@ -26,7 +26,9 @@ import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.json.JSONArray
|
||||
@ -144,7 +146,7 @@ class ArticleEditViewModel(application: Application) : BaseRichEditorViewModel(a
|
||||
if (draftEntity?.id != null) {
|
||||
articleBody.put("draft_id", draftEntity?.id)
|
||||
}
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), articleBody.toString())
|
||||
val body = articleBody.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
val observable = if (detailEntity == null) {
|
||||
mApi.postCommunityArticle(mSelectCommunityData?.id, body)
|
||||
} else {
|
||||
@ -226,7 +228,7 @@ class ArticleEditViewModel(application: Application) : BaseRichEditorViewModel(a
|
||||
if (mSelectCommunityData != null && mSelectCommunityData!!.id.isNotEmpty()) {
|
||||
articleBody.put("community_id", mSelectCommunityData!!.id)
|
||||
}
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), articleBody.toString())
|
||||
val body = articleBody.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
val observable = if (draftEntity?.id != null) {
|
||||
mApi.patchCommunityArticleDrafts(UserManager.getInstance().userId, draftEntity?.id, body)
|
||||
} else {
|
||||
|
||||
@ -28,7 +28,9 @@ import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.json.JSONArray
|
||||
@ -266,7 +268,7 @@ class QuestionEditViewModel(application: Application) : BaseRichEditorViewModel(
|
||||
}
|
||||
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), bodyJson)
|
||||
val body = bodyJson.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
mApi.moderatorsPatchQuestion(body, UserManager.getInstance().userId, questionEntity?.id)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
||||
@ -15,7 +15,9 @@ import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
@ -59,7 +61,7 @@ class QuestionsInviteViewModel(application: Application, var questionId: String?
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
RetrofitManager.getInstance().api
|
||||
.postInvite(body, questionId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
@ -30,7 +30,9 @@ import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
@ -114,7 +116,7 @@ class VideoPublishViewModel(application: Application) : AndroidViewModel(applica
|
||||
when {
|
||||
isDraft -> {
|
||||
val draftData = JSONObject(videoEntity.toJson()).put("local_path", videoPath).toString()
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), draftData)
|
||||
val body = draftData.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
postDraft(body)
|
||||
}
|
||||
videoPatch != null -> {
|
||||
@ -150,7 +152,7 @@ class VideoPublishViewModel(application: Application) : AndroidViewModel(applica
|
||||
|
||||
private fun patchVideo(jsonObject: JSONObject, videoId: String) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
mApi.patchBbsVideo(videoId, body)
|
||||
.compose(observableToMain())
|
||||
.subscribe(object : Response<ResponseBody>() {
|
||||
@ -208,7 +210,7 @@ class VideoPublishViewModel(application: Application) : AndroidViewModel(applica
|
||||
|
||||
private fun postVideo(jsonObject: JSONObject) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
mApi.postBbsVideo(body)
|
||||
.compose(observableToMain())
|
||||
.subscribe(object : Response<JsonObject>() {
|
||||
|
||||
@ -72,7 +72,7 @@ public class PackageChangeBroadcastReceiver extends BroadcastReceiver {
|
||||
PackageHelper.refreshLocalPackageList();
|
||||
|
||||
String versionName = PackageUtils.getVersionNameByPackageName(packageName);
|
||||
EBPackage installEb = new EBPackage(EBPackage.TYPE_INSTALLED, packageName, versionName);
|
||||
EBPackage installEb = new EBPackage(EBPackage.TYPE_INSTALLED, packageName, versionName, false);
|
||||
if (PackageUtils.isAppOnForeground(context)) {
|
||||
PackageObserver.onPackageChanged(installEb, null);
|
||||
EventBus.getDefault().post(installEb);
|
||||
@ -102,7 +102,7 @@ public class PackageChangeBroadcastReceiver extends BroadcastReceiver {
|
||||
InstallUtils.getInstance().removeUninstall(packageName);
|
||||
PackageHelper.refreshLocalPackageList();
|
||||
|
||||
EBPackage uninstallEb = new EBPackage(EBPackage.TYPE_UNINSTALLED, packageName, "");
|
||||
EBPackage uninstallEb = new EBPackage(EBPackage.TYPE_UNINSTALLED, packageName, "", false);
|
||||
PackageObserver.onPackageChanged(uninstallEb, null);
|
||||
EventBus.getDefault().post(uninstallEb);
|
||||
if (webviewPackageName.equals(packageName)) {
|
||||
@ -118,7 +118,7 @@ public class PackageChangeBroadcastReceiver extends BroadcastReceiver {
|
||||
Utils.log(TAG, "替换了:" + packageName + "包名的程序");
|
||||
String versionName = PackageUtils.getVersionNameByPackageName(packageName);
|
||||
|
||||
EBPackage updateEb = new EBPackage(EBPackage.TYPE_REPLACED, packageName, versionName);
|
||||
EBPackage updateEb = new EBPackage(EBPackage.TYPE_REPLACED, packageName, versionName, false);
|
||||
EventBus.getDefault().post(updateEb);
|
||||
PackageObserver.onPackageChanged(updateEb, null);
|
||||
if (webviewPackageName.equals(packageName)) {
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
package com.gh.gamecenter.search
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.LinearGradient
|
||||
import android.graphics.Shader
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
@ -15,6 +18,7 @@ import androidx.viewpager.widget.PagerAdapter
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.filter.RegionSettingHelper
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.SearchActivity
|
||||
@ -31,7 +35,7 @@ import com.gh.gamecenter.databinding.TabItemSearchDefaultRankBinding
|
||||
import com.gh.gamecenter.db.ISearchHistoryDao
|
||||
import com.gh.gamecenter.db.SearchHistoryDao
|
||||
import com.gh.gamecenter.eventbus.EBSearch
|
||||
import com.gh.gamecenter.feature.entity.DiscoveryTagEntity
|
||||
import com.gh.gamecenter.feature.entity.HotTagEntity
|
||||
import com.gh.gamecenter.feature.entity.SettingsEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.google.android.flexbox.FlexboxLayout
|
||||
@ -43,7 +47,7 @@ import org.json.JSONObject
|
||||
|
||||
open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
|
||||
private var mSearchDiscoveryTagList: List<DiscoveryTagEntity>? = null
|
||||
private var mHotTagList: List<HotTagEntity>? = null
|
||||
protected var mRankList: List<SettingsEntity.Search.RankList>? = null
|
||||
|
||||
protected lateinit var mBinding: FragmentSearchDefaultBinding
|
||||
@ -62,28 +66,28 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
|
||||
private val mDao by lazy { provideDao() }
|
||||
|
||||
private val mSearchDiscoveryTagClickListener: (Int) -> Unit = {
|
||||
val tag = mSearchDiscoveryTagList!![it]
|
||||
val keyword = tag.keyword
|
||||
if (keyword.isNotEmpty()) {
|
||||
PageSwitchDataHelper.pushCurrentPageData(
|
||||
hashMapOf(
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_TYPE, "游戏搜索-搜索发现"),
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_ID, tag.id ?: ""),
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_NAME, tag.text ?: " ")
|
||||
)
|
||||
private val mHotTagClickListener: (Int) -> Unit = {
|
||||
val tag = mHotTagList!![it]
|
||||
NewFlatLogUtils.logSearchHotTagClick(
|
||||
tag.name ?: "",
|
||||
tag.type ?: "",
|
||||
tag.link ?: "",
|
||||
tag.text ?: ""
|
||||
)
|
||||
DataLogUtils.uploadHotTagLog(context, tag.name)
|
||||
PageSwitchDataHelper.pushCurrentPageData(
|
||||
hashMapOf(
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_TYPE, "游戏搜索-热门标签"),
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_ID, tag.id ?: ""),
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_NAME, tag.name ?: " ")
|
||||
)
|
||||
SensorsBridge.trackEvent("SearchLabelClick", "label_name", tag.text ?: "", "label_id", tag.id ?: "")
|
||||
SensorsBridge.trackSearchDiscoveryClick(
|
||||
labelName = tag.text ?: "",
|
||||
labelId = tag.id ?: "",
|
||||
searchContent = keyword,
|
||||
position = it
|
||||
)
|
||||
mViewModel?.add(keyword)
|
||||
EventBus.getDefault().post(EBSearch("history", keyword))
|
||||
Util_System_Keyboard.hideSoftKeyboardByIBinder(context, mBinding.historyFlex.windowToken)
|
||||
}
|
||||
)
|
||||
SensorsBridge.trackEvent("SearchLabelClick", "label_name", tag.name ?: "", "label_id", tag.id ?: "")
|
||||
val exposureEvent = ExposureEvent.createEvent(
|
||||
null,
|
||||
source = listOf(ExposureSource("首页搜索", ""), ExposureSource("热门标签", tag.name ?: ""))
|
||||
)
|
||||
DirectUtils.directToLinkPage(requireContext(), tag, "(搜索-${tag.name})", "", exposureEvent) // 不需要path
|
||||
}
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
@ -136,20 +140,16 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
}
|
||||
mViewModel?.isExistRankList = mRankList?.isNotEmpty() == true
|
||||
|
||||
mSearchDiscoveryTagList = Config.getSettings()?.search?.discoveryTag
|
||||
mViewModel?.isExistSearchDiscoveryTag = mSearchDiscoveryTagList?.isNotEmpty() == true
|
||||
mHotTagList = Config.getSettings()?.search?.hotTag
|
||||
mViewModel?.isExistHotTag = mHotTagList?.isNotEmpty() == true
|
||||
|
||||
updateHistorySearchView(null)
|
||||
mViewModel?.historySearchLiveData?.observe(viewLifecycleOwner) {
|
||||
updateHistorySearchView(it)
|
||||
}
|
||||
|
||||
mBinding.searchDiscoveryTagFlexContainer.setLimitHeight(mFlexMaxHeight)
|
||||
createFlexContent(
|
||||
mBinding.searchDiscoveryTagFlex,
|
||||
getTagListString(),
|
||||
clickListener = mSearchDiscoveryTagClickListener
|
||||
)
|
||||
mBinding.hotTagFlexContainer.setLimitHeight(mFlexMaxHeight)
|
||||
createFlexContent(mBinding.hotTagFlex, getTagListString(), true, clickListener = mHotTagClickListener)
|
||||
initHeadView()
|
||||
initRankViewPager()
|
||||
}
|
||||
@ -178,12 +178,12 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
})
|
||||
}
|
||||
}
|
||||
mBinding.searchDiscoveryHeadContainer.headTitle.text = getString(R.string.search_hot)
|
||||
mBinding.searchDiscoveryHeadContainer.headTitle.textSize = 16F
|
||||
mBinding.searchDiscoveryHeadContainer.headActionTv.visibility = View.GONE
|
||||
mBinding.searchDiscoveryTagHeadContainer.headTitle.text = getString(R.string.search_discovery_tag)
|
||||
mBinding.searchDiscoveryTagHeadContainer.headTitle.textSize = 16F
|
||||
mBinding.searchDiscoveryTagHeadContainer.headActionTv.visibility = View.GONE
|
||||
mBinding.hotHeadContainer.headTitle.text = getString(R.string.search_hot)
|
||||
mBinding.hotHeadContainer.headTitle.textSize = 16F
|
||||
mBinding.hotHeadContainer.headActionTv.visibility = View.GONE
|
||||
mBinding.hotTagHeadContainer.headTitle.text = getString(R.string.search_hot_tag)
|
||||
mBinding.hotTagHeadContainer.headTitle.textSize = 16F
|
||||
mBinding.hotTagHeadContainer.headActionTv.visibility = View.GONE
|
||||
}
|
||||
|
||||
protected open fun initRankViewPager() {
|
||||
@ -318,8 +318,8 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
mBinding.historyHeadContainer.root.visibility =
|
||||
if (mViewModel?.isExistHistory == true) View.VISIBLE else View.GONE
|
||||
mBinding.historyFlex.visibility = if (mViewModel?.isExistHistory == true) View.VISIBLE else View.GONE
|
||||
mBinding.searchDiscoveryTagHeadContainer.root.layoutParams =
|
||||
(mBinding.searchDiscoveryTagHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
mBinding.hotTagHeadContainer.root.layoutParams =
|
||||
(mBinding.hotTagHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
setMargins(
|
||||
0,
|
||||
if (mViewModel?.isExistHistory == true) 16F.dip2px() else 0,
|
||||
@ -327,22 +327,21 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
0
|
||||
)
|
||||
}
|
||||
mBinding.searchDiscoveryHeadContainer.root.layoutParams =
|
||||
(mBinding.searchDiscoveryHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
mBinding.hotHeadContainer.root.layoutParams =
|
||||
(mBinding.hotHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
setMargins(
|
||||
0,
|
||||
if (mViewModel?.isExistHistory == false && mViewModel?.isExistSearchDiscoveryTag == false) 16F.dip2px() else 0,
|
||||
if (mViewModel?.isExistHistory == false && mViewModel?.isExistHotTag == false) 16F.dip2px() else 0,
|
||||
0,
|
||||
0
|
||||
)
|
||||
}
|
||||
mBinding.searchDiscoveryTagHeadContainer.root.visibility =
|
||||
if (mViewModel?.isExistSearchDiscoveryTag == true) View.VISIBLE else View.GONE
|
||||
mBinding.searchDiscoveryTagFlex.visibility =
|
||||
if (mViewModel?.isExistSearchDiscoveryTag == true) View.VISIBLE else View.GONE
|
||||
mBinding.searchDiscoveryHeadContainer.root.visibility =
|
||||
mBinding.hotTagHeadContainer.root.visibility =
|
||||
if (mViewModel?.isExistHotTag == true) View.VISIBLE else View.GONE
|
||||
mBinding.hotTagFlex.visibility = if (mViewModel?.isExistHotTag == true) View.VISIBLE else View.GONE
|
||||
mBinding.hotHeadContainer.root.visibility =
|
||||
if (mViewModel?.isExistHotSearch == true) View.VISIBLE else View.GONE
|
||||
mBinding.searchDiscoveryList.visibility = if (mViewModel?.isExistHotSearch == true) View.VISIBLE else View.GONE
|
||||
mBinding.hotList.visibility = if (mViewModel?.isExistHotSearch == true) View.VISIBLE else View.GONE
|
||||
mBinding.rankTabLayout.visibility = if (mViewModel?.isExistRankList == true) View.VISIBLE else View.GONE
|
||||
mBinding.rankTabIndicator.visibility = if (mViewModel?.isExistRankList == true) View.VISIBLE else View.GONE
|
||||
mBinding.rankViewPager.visibility = if (mViewModel?.isExistRankList == true) View.VISIBLE else View.GONE
|
||||
@ -364,9 +363,9 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
|
||||
private fun getTagListString(): List<String> {
|
||||
val list = ArrayList<String>()
|
||||
if (mSearchDiscoveryTagList != null) {
|
||||
for (entity in mSearchDiscoveryTagList!!) {
|
||||
entity.text?.let { list.add(it) }
|
||||
if (mHotTagList != null) {
|
||||
for (entity in mHotTagList!!) {
|
||||
entity.name?.let { list.add(it) }
|
||||
}
|
||||
}
|
||||
return list
|
||||
@ -375,6 +374,7 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
fun createFlexContent(
|
||||
flexView: FlexboxLayout,
|
||||
contentList: List<String>?,
|
||||
isHotTag: Boolean = false,
|
||||
clickListener: (Int) -> Unit
|
||||
) {
|
||||
|
||||
@ -388,12 +388,16 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
val params = FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 24F.dip2px())
|
||||
flexCell.layoutParams = params
|
||||
|
||||
flexCell.setSingleLine()
|
||||
flexCell.ellipsize = TextUtils.TruncateAt.END
|
||||
flexCell.gravity = Gravity.CENTER
|
||||
flexCell.textSize = 12F
|
||||
flexCell.text = StringUtils.shrinkStringWithDot(contentList[index], 6)
|
||||
flexCell.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
|
||||
if (isHotTag && !mHotTagList.isNullOrEmpty() && mHotTagList!![index].isGuessSearch) {
|
||||
createSmartHotTagStyle(flexCell, contentList[index])
|
||||
} else {
|
||||
flexCell.setSingleLine()
|
||||
flexCell.ellipsize = TextUtils.TruncateAt.END
|
||||
flexCell.gravity = Gravity.CENTER
|
||||
flexCell.textSize = 12F
|
||||
flexCell.text = StringUtils.shrinkStringWithDot(contentList[index], 6)
|
||||
flexCell.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
|
||||
}
|
||||
flexCell.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0)
|
||||
flexCell.background = if (mIsDarkModeOn) GradientDrawable().apply {
|
||||
setStroke(0.5F.dip2px(), Color.parseColor("#21FFFFFF"))
|
||||
@ -405,6 +409,30 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSmartHotTagStyle(flexCell: TextView, name: String) {
|
||||
flexCell.setDrawableStart(R.drawable.ic_smart_search)
|
||||
flexCell.compoundDrawablePadding = 4F.dip2px()
|
||||
flexCell.gravity = Gravity.CENTER_VERTICAL
|
||||
flexCell.typeface = Typeface.DEFAULT_BOLD
|
||||
flexCell.textSize = 12F
|
||||
flexCell.text = StringUtils.shrinkStringWithDot(name, 6)
|
||||
flexCell.setTextColor(Color.WHITE)
|
||||
val colors =
|
||||
intArrayOf(com.gh.gamecenter.common.R.color.text_FFB749.toColor(requireContext()), com.gh.gamecenter.common.R.color.text_FF6D3C.toColor(requireContext()))
|
||||
val position = floatArrayOf(0F, 1F)
|
||||
val linearGradient = LinearGradient(
|
||||
0F,
|
||||
0F,
|
||||
flexCell.paint.textSize * flexCell.text.length,
|
||||
0F,
|
||||
colors,
|
||||
position,
|
||||
Shader.TileMode.CLAMP
|
||||
)
|
||||
flexCell.paint.shader = linearGradient
|
||||
flexCell.invalidate()
|
||||
}
|
||||
|
||||
private fun postExposureEvent(index: Int) {
|
||||
mRankList?.safelyGetInRelease(index)?.content?.forEach {
|
||||
if (it.link.type == "game") {
|
||||
@ -419,15 +447,11 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
super.onDarkModeChanged()
|
||||
initHeadView()
|
||||
mBinding.rootContainer.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
|
||||
mBinding.searchDiscoveryList.adapter?.run {
|
||||
mBinding.hotList.adapter?.run {
|
||||
notifyItemRangeChanged(0, itemCount)
|
||||
}
|
||||
mViewModel?.historySearchLiveData?.value?.let { updateHistorySearchView(it) }
|
||||
createFlexContent(
|
||||
mBinding.searchDiscoveryTagFlex,
|
||||
getTagListString(),
|
||||
clickListener = mSearchDiscoveryTagClickListener
|
||||
)
|
||||
createFlexContent(mBinding.hotTagFlex, getTagListString(), true, clickListener = mHotTagClickListener)
|
||||
}
|
||||
|
||||
protected open fun provideDao(): ISearchHistoryDao =
|
||||
|
||||
@ -11,7 +11,7 @@ class SearchDefaultViewModel(private val dao: ISearchHistoryDao) : ViewModel() {
|
||||
it
|
||||
}
|
||||
var isExistHotSearch: Boolean = false
|
||||
var isExistSearchDiscoveryTag: Boolean = false
|
||||
var isExistHotTag: Boolean = false
|
||||
var isExistHistory: Boolean = false
|
||||
var isExistRankList: Boolean = false
|
||||
|
||||
|
||||
@ -214,7 +214,7 @@ class SearchGameIndexFragment : ListFragment<GameEntity, SearchGameResultViewMod
|
||||
// 安装/卸载 事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(busFour: EBPackage) {
|
||||
if (busFour.isInstalledOrUninstalled()) {
|
||||
if (!busFour.fromInit && busFour.isInstalledOrUninstalled()) {
|
||||
mAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ class SearchGameResultAdapter(
|
||||
private val dao: ISearchHistoryDao,
|
||||
val listViewModel: SearchGameResultViewModel,
|
||||
val entrance: String,
|
||||
val type: String,
|
||||
var type: String,
|
||||
val sourceEntrance: String
|
||||
) : ListAdapter<SearchItemData>(context), IExposable {
|
||||
|
||||
|
||||
@ -376,6 +376,7 @@ open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultV
|
||||
this.mKey = key
|
||||
this.mType = type
|
||||
mAdapter?.key = key
|
||||
mAdapter?.type = type
|
||||
mAdapter?.clearAdIdSet()
|
||||
mListViewModel?.updateSearchKeyWithType(key, type)
|
||||
mListViewModel?.clearSearchSubjects()
|
||||
@ -423,7 +424,7 @@ open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultV
|
||||
// 安装/卸载 事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(busFour: EBPackage) {
|
||||
if (busFour.isInstalledOrUninstalled()) {
|
||||
if (!busFour.fromInit && busFour.isInstalledOrUninstalled()) {
|
||||
mAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,9 +3,9 @@ package com.gh.gamecenter.search.viewmodel
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.gh.gamecenter.SearchActivity
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
||||
class SearchTabViewModel : ViewModel() {
|
||||
|
||||
@ -21,7 +21,8 @@ class SearchTabViewModel : ViewModel() {
|
||||
GlobalActivityManager.getCurrentPageEntity().pageName,
|
||||
location,
|
||||
searchKeyAndType.value?.first ?: "",
|
||||
searchKeyAndType.value?.second ?: "",
|
||||
searchKeyAndType.value?.let {
|
||||
SearchActivity.toTrackSearchType(it.second) } ?: "",
|
||||
text ?: "",
|
||||
position
|
||||
)
|
||||
|
||||
@ -16,7 +16,9 @@ import com.lightgame.utils.Utils.toast
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import retrofit2.HttpException
|
||||
|
||||
class AddKaiFuViewModel(application: Application) : AndroidViewModel(application) {
|
||||
@ -266,7 +268,7 @@ class AddKaiFuViewModel(application: Application) : AndroidViewModel(application
|
||||
|
||||
|
||||
private fun postData(postList: ArrayList<ServerCalendarEntity>) {
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), GsonUtils.toJson(postList))
|
||||
val body = GsonUtils.toJson(postList).toRequestBody("application/json".toMediaTypeOrNull())
|
||||
RetrofitManager.getInstance().api.addKaifu(body, mGameId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
||||
@ -11,7 +11,9 @@ import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
@ -35,7 +37,7 @@ class PatchKaifuViewModel(application: Application) : AndroidViewModel(applicati
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("note", patchName)
|
||||
jsonObject.put("remark", patchRemark)
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
apiService.patchKaifu(body, gameId, serverEntity!!.id)
|
||||
} else {
|
||||
apiService.deleteKaifu(gameId, serverEntity!!.id)
|
||||
|
||||
@ -207,7 +207,7 @@ open class SubjectListFragment : LazyListFragment<GameEntity, SubjectListViewMod
|
||||
// 安装/卸载 事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(busFour: EBPackage) {
|
||||
if (busFour.isInstalledOrUninstalled()) {
|
||||
if (!busFour.fromInit && busFour.isInstalledOrUninstalled()) {
|
||||
mAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ class TagsListFragment : ListFragment<GameEntity, TagsListViewModel>() {
|
||||
// 安装/卸载 事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(busFour: EBPackage) {
|
||||
if (busFour.isInstalledOrUninstalled()) {
|
||||
if (!busFour.fromInit && busFour.isInstalledOrUninstalled()) {
|
||||
mAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,9 @@ import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
@ -57,7 +59,7 @@ class UploadVideoViewModel(application: Application) : AndroidViewModel(applicat
|
||||
|
||||
private fun postVideo(jsonObject: JSONObject) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
mApi.postVideo(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -121,7 +123,7 @@ class UploadVideoViewModel(application: Application) : AndroidViewModel(applicat
|
||||
|
||||
private fun patchVideo(jsonObject: JSONObject, videoId: String) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
mApi.patchVideo(body, videoId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -188,7 +190,7 @@ class UploadVideoViewModel(application: Application) : AndroidViewModel(applicat
|
||||
patchVideo(JSONObject(GsonUtils.toJson(videoEntity)), videoEntity.id)
|
||||
} else if (isDraft) {
|
||||
val draftData = JSONObject(videoEntity.toJson()).put("local_path", videoPath).toString()
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), draftData)
|
||||
val body = draftData.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
postDraft(body)
|
||||
} else {
|
||||
var videoHeight = 0
|
||||
|
||||
@ -19,7 +19,9 @@ import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
@ -66,7 +68,7 @@ class VoteViewModel(application: Application, private val mGameId: String = "")
|
||||
requestMap["version_code"] = installGameEntity.versionCode
|
||||
|
||||
val body = RequestBody.create(
|
||||
MediaType.parse("application/json"),
|
||||
"application/json".toMediaTypeOrNull(),
|
||||
GsonUtils.toJson(requestMap)
|
||||
)
|
||||
RetrofitManager.getInstance().api.postPlatformRequestApk(installGameEntity.platformRequestsId, body)
|
||||
@ -99,7 +101,7 @@ class VoteViewModel(application: Application, private val mGameId: String = "")
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
val responseBodyObservable = if (isNewVote) {
|
||||
RetrofitManager.getInstance().api.addVersionVote(body, mGameId)
|
||||
} else if (isVoted) {
|
||||
|
||||
@ -20,6 +20,9 @@ import com.gh.gamecenter.entity.DiverterEntity
|
||||
import com.gh.gamecenter.entity.MultiTabNav
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@ -59,10 +62,13 @@ class MainWrapperRepository {
|
||||
private val mTabSelectEventFlow = MutableSharedFlow<MainSelectedEvent>()
|
||||
val tabSelectEventFlow = mTabSelectEventFlow as SharedFlow<MainSelectedEvent>
|
||||
|
||||
private var mDisposable: Disposable? = null
|
||||
private var mCheckGidCount = 0
|
||||
|
||||
fun init() {
|
||||
// 若 timeout 后数据未加载完成,则即便还没有回调也使用默认数据生成底部 tab
|
||||
emitDefaultTabDataAfterTimeout()
|
||||
getBypassList()
|
||||
checkGidAndGetBypassList()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,8 +155,33 @@ class MainWrapperRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkGidAndGetBypassList() {
|
||||
if (HaloApp.getInstance().gid.isNullOrEmpty()) {
|
||||
stopCheckGid()
|
||||
mDisposable = Observable.interval(100, TimeUnit.MILLISECONDS)
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.subscribe({
|
||||
mCheckGidCount++
|
||||
if (!HaloApp.getInstance().gid.isNullOrEmpty() || mCheckGidCount >= CHECK_GID_MAX_COUNT) {
|
||||
stopCheckGid()
|
||||
getBypassList()
|
||||
}
|
||||
}, {
|
||||
stopCheckGid()
|
||||
})
|
||||
} else {
|
||||
getBypassList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopCheckGid() {
|
||||
mDisposable?.dispose()
|
||||
mDisposable = null
|
||||
mCheckGidCount = 0
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun getBypassList() {
|
||||
private fun getBypassList() {
|
||||
val isInstallFirstAccess = TimeUtils.isToday(SPUtils.getLong(Constants.SP_BRAND_NEW_FIRST_LAUNCH_TIME) / 1000).toString()
|
||||
mNewApi.getDiverterList(isInstallFirstAccess, BYPASS_TYPE_BOTTOM_TAB)
|
||||
.subscribeOn(Schedulers.computation())
|
||||
@ -294,6 +325,7 @@ class MainWrapperRepository {
|
||||
|
||||
companion object : SingletonHolder<MainWrapperRepository>({ MainWrapperRepository() }) {
|
||||
private const val BYPASS_TIME_OUT = 1000L
|
||||
private const val CHECK_GID_MAX_COUNT = 5
|
||||
const val BYPASS_TYPE_BOTTOM_TAB = "bottom_tab"
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,9 @@ import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.transformWhile
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
@ -93,7 +95,7 @@ class MainWrapperViewModel(application: Application, private val mRepository: Ma
|
||||
fun postMessageRead(messageId: String) {
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("type", "system_message")
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
RetrofitManager.getInstance().api.postMessageRead(UserManager.getInstance().userId, messageId, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
||||
@ -99,7 +99,7 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
private val viewModel: SearchToolbarTabWrapperViewModel by lazy {
|
||||
viewModelProviderFromParent(
|
||||
SearchToolbarTabWrapperViewModel.Factory(multiTabNavId, noTabLinkEntity?.link ?: ""),
|
||||
multiTabNavId
|
||||
multiTabNavId + (noTabLinkEntity?.link ?: "")
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ package com.gh.ndownload.suspendwindow
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.app.Application.ActivityLifecycleCallbacks
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
@ -128,7 +127,7 @@ class NDownloadDrawOverlayPermissionWindowController(val application: Applicatio
|
||||
SensorsBridge.trackDownloadSuspendedWindowGuideShow(
|
||||
gameId = downloadEntity.gameId,
|
||||
gameName = downloadEntity.name,
|
||||
gameSchemeType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameSchemaType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameType = downloadEntity.categoryChinese,
|
||||
downloadStatus = downloadEntity.getMetaExtra(Constants.DOWNLOAD_STATUS_IN_CHINESE),
|
||||
downloadType = if (downloadEntity.asVGame()) "畅玩下载" else "本地下载"
|
||||
|
||||
@ -48,10 +48,17 @@ abstract class NDownloadSuspendWindow<T : View>(
|
||||
|
||||
fun attach() {
|
||||
if (!isAttached) {
|
||||
_isAttached = true
|
||||
windowManager.addView(root, layoutParams)
|
||||
context.registerComponentCallbacks(this)
|
||||
onAttach()
|
||||
try {
|
||||
_isAttached = true
|
||||
windowManager.addView(root, layoutParams)
|
||||
context.registerComponentCallbacks(this)
|
||||
onAttach()
|
||||
} catch (e: Throwable) {
|
||||
// 处理“Unable to add window android.view.ViewRootImpl$W@7bc9502 -- permission denied for window type 2038”的异常
|
||||
// 目前Sentry上仅Z10型号的手机报这个错误(Android 8.1.0),这里明明已经授予了SYSTEM_ALERT_WINDOW权限,但是就是会抛异常= =,只能暴力捕获处理了。。。
|
||||
// 相关异常的链接:https://sentry.shanqu.cc/organizations/lightgame/issues/407275/?project=22
|
||||
_isAttached = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,9 @@ import com.halo.assistant.HaloApp
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
@ -52,9 +54,8 @@ class ManuallyRealNameViewModel(application: Application) : AndroidViewModel(app
|
||||
fun postCertificationReview(idCardEntity: IdCardEntity) {
|
||||
val userInfoEntity = UserInfoEntity()
|
||||
userInfoEntity.idCard = idCardEntity
|
||||
val body = RequestBody.create(
|
||||
MediaType.parse("application/json"), GsonUtils.toJson(userInfoEntity)
|
||||
)
|
||||
val body = GsonUtils.toJson(userInfoEntity)
|
||||
.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
RetrofitManager.getInstance().api.postCertificationReview(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
||||
@ -19,7 +19,9 @@ import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
@ -39,7 +41,7 @@ class VerifyPhoneViewModel(application: Application) : AndroidViewModel(applicat
|
||||
params["mobile"] = phoneNum
|
||||
val jsonObject = JSONObject(params as Map<*, *>)
|
||||
jsonObject.put("device", device)
|
||||
val body: RequestBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body: RequestBody = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
|
||||
api.verifyPhone(1, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
@ -80,7 +82,7 @@ class VerifyPhoneViewModel(application: Application) : AndroidViewModel(applicat
|
||||
params["code"] = code
|
||||
val jsonObject = JSONObject(params as Map<*, *>)
|
||||
jsonObject.put("device", device)
|
||||
val body: RequestBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body: RequestBody = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
|
||||
api.verifyPhone(2, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
BIN
app/src/main/res/drawable-xxxhdpi/ic_smart_search.webp
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_smart_search.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@ -36,7 +36,7 @@
|
||||
</com.gh.gamecenter.common.view.LimitHeightLinearLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/searchDiscoveryTagHeadContainer"
|
||||
android:id="@+id/hotTagHeadContainer"
|
||||
layout="@layout/layout_subject_head"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
@ -45,14 +45,14 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/history_flex_container" />
|
||||
|
||||
<com.gh.gamecenter.common.view.LimitHeightLinearLayout
|
||||
android:id="@+id/search_discovery_tag_flex_container"
|
||||
android:id="@+id/hot_tag_flex_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/ui_surface"
|
||||
app:layout_constraintTop_toBottomOf="@id/searchDiscoveryTagHeadContainer">
|
||||
app:layout_constraintTop_toBottomOf="@id/hotTagHeadContainer">
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:id="@+id/search_discovery_tag_flex"
|
||||
android:id="@+id/hot_tag_flex"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="16dp"
|
||||
@ -62,21 +62,21 @@
|
||||
</com.gh.gamecenter.common.view.LimitHeightLinearLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/searchDiscoveryHeadContainer"
|
||||
android:id="@+id/hotHeadContainer"
|
||||
layout="@layout/layout_subject_head"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/search_discovery_tag_flex_container" />
|
||||
app:layout_constraintTop_toBottomOf="@id/hot_tag_flex_container" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/search_discovery_list"
|
||||
android:id="@+id/hot_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:overScrollMode="never"
|
||||
app:layout_constrainedHeight="true"
|
||||
app:layout_constraintTop_toBottomOf="@+id/searchDiscoveryHeadContainer" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/hotHeadContainer" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/rankTabLayout"
|
||||
@ -91,7 +91,7 @@
|
||||
app:tabMode="scrollable"
|
||||
app:tabIndicator="@null"
|
||||
app:tabRippleColor="@color/transparent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/search_discovery_list"
|
||||
app:layout_constraintTop_toBottomOf="@+id/hot_list"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
<string name="download_startall">全部開始</string>
|
||||
<string name="search_searching">搜索中...</string>
|
||||
<string name="search_hot">熱門搜索</string>
|
||||
<string name="search_discovery_tag">搜索發現</string>
|
||||
<string name="search_hot_tag">熱門標簽</string>
|
||||
<string name="search_history">歷史搜索</string>
|
||||
<string name="news_concenrn_game_mine">我關註的遊戲</string>
|
||||
<string name="news_search_input">請輸入搜索關鍵字</string>
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
<string name="download_startall">全部开始</string>
|
||||
<string name="search_searching">搜索中...</string>
|
||||
<string name="search_hot">热门搜索</string>
|
||||
<string name="search_discovery_tag">搜索发现</string>
|
||||
<string name="search_hot_tag">热门标签</string>
|
||||
<string name="search_history">历史搜索</string>
|
||||
<string name="news_concenrn_game_mine">我关注的游戏</string>
|
||||
<string name="news_search_input">请输入搜索关键字</string>
|
||||
|
||||
@ -17,8 +17,8 @@ buildscript {
|
||||
password("u9gZYH4MQEwLLQZK")
|
||||
}
|
||||
}
|
||||
maven { url 'https://jitpack.io' }
|
||||
maven { url "https://maven.google.com" }
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -41,7 +41,6 @@ allprojects {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url 'https://jitpack.io' }
|
||||
maven { url 'https://maven.aliyun.com/repository/public' }
|
||||
maven { url 'https://maven.aliyun.com/repository/central'}
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases/' }
|
||||
@ -55,6 +54,7 @@ allprojects {
|
||||
// 配置HMS Core SDK的Maven仓地址。
|
||||
maven { url 'https://developer.huawei.com/repo/' }
|
||||
maven { url 'https://developer.hihonor.com/repo' }
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
task clean(type: Delete) {
|
||||
|
||||
@ -49,6 +49,7 @@ class GhTransform(var project: Project) : Transform() {
|
||||
mTransformHelper.addTransformer(RoomTransformer())
|
||||
mTransformHelper.addTransformer(ActivityTransformer())
|
||||
mTransformHelper.addTransformer(AppCompatEditTextTransformer())
|
||||
mTransformHelper.addTransformer(MiniGameWebViewTransformer())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
package com.gh.gamecenter.plugin.transform
|
||||
|
||||
import javassist.ClassPool
|
||||
import javassist.CtClass
|
||||
import javassist.NotFoundException
|
||||
import javassist.bytecode.ClassFile
|
||||
import java.io.BufferedInputStream
|
||||
import java.io.DataInputStream
|
||||
import java.io.InputStream
|
||||
|
||||
class MiniGameWebViewTransformer : Transformer {
|
||||
|
||||
private val classPool = ClassPool.getDefault()
|
||||
|
||||
override fun getModifyClassName(): String {
|
||||
return "QUAUtil"
|
||||
}
|
||||
|
||||
override fun modifyClass(filePath: String, inputStream: InputStream): CtClass? {
|
||||
if (filePath.contains(getModifyClassName())) {
|
||||
|
||||
println("发现 QUAUtil")
|
||||
|
||||
val classFile = ClassFile(DataInputStream(BufferedInputStream(inputStream)))
|
||||
val ctClass = classPool.get(classFile.name)
|
||||
|
||||
if (ctClass.isFrozen) {
|
||||
ctClass.defrost()
|
||||
}
|
||||
|
||||
// 使用 try catch 包裹找到的第一个 getSystemUA 方法 (若能找到的话)
|
||||
try {
|
||||
val ctMethod = ctClass.getDeclaredMethod("getSystemUA")
|
||||
val body = "{ if (systemUA != null) { return systemUA; } systemUA = java.net.URLEncoder.encode(System.getProperty(\"http.agent\"), \"UTF-8\"); return systemUA; }"
|
||||
ctMethod.setBody(body)
|
||||
|
||||
println("修改 getSystemUA 方法")
|
||||
} catch (e: NotFoundException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return ctClass
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
@ -49,7 +49,7 @@ ext {
|
||||
rxAndroid2 = "2.1.1"
|
||||
rxBinding2 = "2.1.1"
|
||||
retrofit = "2.3.0"
|
||||
okHttp = "3.12.13"
|
||||
okHttp = "4.11.0"
|
||||
gson = "2.8.2"
|
||||
zxing = "3.2.1"
|
||||
fresco = "2.6.0"
|
||||
|
||||
@ -18,6 +18,7 @@ object NewLogUtils {
|
||||
private const val KEY_CONTENT_ID = "content_id"
|
||||
private const val KEY_CONTENT_TITLE = "content_title"
|
||||
private const val KEY_HELP_ID = "help_id"
|
||||
private const val KEY_QA_COLLECTION = "qa_collection"
|
||||
private const val KEY_SEARCH_KEY = "search_key"
|
||||
|
||||
private fun log(jsonObject: JSONObject, logStore: String = "event", uploadImmediately: Boolean = false) {
|
||||
@ -53,10 +54,11 @@ object NewLogUtils {
|
||||
}
|
||||
|
||||
//点击QA更多
|
||||
fun logClickQaMoreBtn(helpId: String) {
|
||||
fun logClickQaMoreBtn(helpId: String, qaCollection: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "qa_click_title_more"
|
||||
KEY_HELP_ID to helpId
|
||||
KEY_QA_COLLECTION to qaCollection
|
||||
KEY_META to LogUtils.getMetaObject()
|
||||
KEY_LAUNCH_ID to Tracker.launchId
|
||||
KEY_SESSION_ID to Tracker.sessionId
|
||||
|
||||
@ -150,7 +150,7 @@ class HelpAndFeedbackFragment : BaseLazyFragment() {
|
||||
|
||||
val layoutManager = FixLinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
|
||||
mSnapHelper = LeftPagerSnapHelper()
|
||||
mHelpVideoAdapter = HelpVideoAdapter(requireContext(), mSnapHelper!!, layoutManager, helpVideoRv)
|
||||
mHelpVideoAdapter = HelpVideoAdapter(requireContext(), viewLifecycleOwner, mSnapHelper!!, layoutManager, helpVideoRv)
|
||||
(helpVideoRv.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
|
||||
helpVideoRv.layoutManager = layoutManager
|
||||
helpVideoRv.adapter = mHelpVideoAdapter
|
||||
@ -209,9 +209,7 @@ class HelpAndFeedbackFragment : BaseLazyFragment() {
|
||||
mViewModel.selectedCategory.name == HelpAndFeedbackViewModel.MY_RELATED_QA_NAME
|
||||
)
|
||||
)
|
||||
if (mViewModel.selectedCategory.id.isNotEmpty()) {
|
||||
NewLogUtils.logClickQaMoreBtn(mViewModel.selectedCategory.id)
|
||||
}
|
||||
NewLogUtils.logClickQaMoreBtn(mViewModel.selectedCategory.id, mViewModel.selectedCategory.name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,8 @@ import android.os.Handler
|
||||
import android.os.Message
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.MarginLayoutParams
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
@ -20,6 +22,7 @@ import java.lang.ref.WeakReference
|
||||
|
||||
class HelpVideoAdapter(
|
||||
context: Context,
|
||||
private val mLifecycleOwner: LifecycleOwner,
|
||||
private val mSnapHelper: LeftPagerSnapHelper,
|
||||
private val mLayoutManager: LinearLayoutManager,
|
||||
private val mRecyclerView: RecyclerView
|
||||
@ -27,6 +30,17 @@ class HelpVideoAdapter(
|
||||
private var mHelpVideoList = arrayListOf<HelpVideo>()
|
||||
private val mLooperHandle = LooperHandle(this)
|
||||
private val mSlideLooperKey = 102
|
||||
private val mLifecycleObserver = object : DefaultLifecycleObserver {
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
super.onResume(owner)
|
||||
startScroll()
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
super.onPause(owner)
|
||||
stopScroll()
|
||||
}
|
||||
}
|
||||
|
||||
fun submitList(helpVideoList: List<HelpVideo>) {
|
||||
mHelpVideoList = ArrayList(helpVideoList)
|
||||
@ -122,6 +136,16 @@ class HelpVideoAdapter(
|
||||
mLooperHandle.removeMessages(mSlideLooperKey)
|
||||
}
|
||||
|
||||
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
|
||||
super.onViewAttachedToWindow(holder)
|
||||
mLifecycleOwner.lifecycle.addObserver(mLifecycleObserver)
|
||||
}
|
||||
|
||||
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
|
||||
super.onViewDetachedFromWindow(holder)
|
||||
mLifecycleOwner.lifecycle.removeObserver(mLifecycleObserver)
|
||||
}
|
||||
|
||||
class LooperHandle(adapter: HelpVideoAdapter) : Handler() {
|
||||
private val mWeakReference: WeakReference<HelpVideoAdapter> = WeakReference(adapter)
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ class HelpContentAdapter(
|
||||
context: Context,
|
||||
private val mFragment: HelpContentFragment,
|
||||
private val mViewModel: NormalListViewModel<HelpEntity>,
|
||||
private val mQaId: String?,
|
||||
private val mIsFromHelpAndFeedback: Boolean,
|
||||
private val mQaCollectionId: String?,
|
||||
private val mNavigationTitle: String,
|
||||
private val searchType: String,
|
||||
@ -103,7 +103,7 @@ class HelpContentAdapter(
|
||||
)
|
||||
} else {
|
||||
NewLogUtils.logEnterQaContent(
|
||||
"其他位置",
|
||||
if (mIsFromHelpAndFeedback) "帮助与反馈" else "其他位置",
|
||||
entity.id,
|
||||
HtmlUtils.filterHtmlLabel(entity.title),
|
||||
entity.helpId,
|
||||
|
||||
@ -60,7 +60,7 @@ class HelpContentFragment : ListFragment<HelpEntity, NormalListViewModel<HelpEnt
|
||||
requireContext(),
|
||||
this,
|
||||
mListViewModel,
|
||||
mQaId,
|
||||
!mCategoryId.isNullOrEmpty() || mIsMyRelatedQA,
|
||||
mQaCollectionId,
|
||||
mNavigationTitle,
|
||||
mSearchType,
|
||||
|
||||
@ -61,7 +61,7 @@ class HelpQaCategoryAdapter(val context: Context, private val mQaCollectionId: S
|
||||
} else {
|
||||
MtaHelper.onEvent("意见反馈", "使用帮助点击", "点击更多+${helpCategoryEntity.name}")
|
||||
}
|
||||
NewLogUtils.logClickQaMoreBtn(helpCategoryEntity.id)
|
||||
NewLogUtils.logClickQaMoreBtn(helpCategoryEntity.id, helpCategoryEntity.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@ import cn.com.chinatelecom.account.api.CtAuth
|
||||
import cn.jiguang.verifysdk.api.*
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.databinding.SetWaitDialogBinding
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
@ -50,7 +49,6 @@ object LoginHelper {
|
||||
//请注意,这里有可能会出现内存泄漏,需要及时清理
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private var backgroundView: View? = null
|
||||
private var loggingDialog: Dialog? = null
|
||||
private var cbPrivacy: CheckBox? = null
|
||||
|
||||
private var loginProvider: ILoginProvider? = null
|
||||
@ -85,20 +83,26 @@ object LoginHelper {
|
||||
fun loginAuth(context: Context, entrance: String, callback: (() -> Unit)?) {
|
||||
runOnUiThread {
|
||||
val dialogContext = DialogHelper.checkDialogContext(context)
|
||||
if (dialogContext is Activity && dialogContext.isFinishing) return@runOnUiThread
|
||||
preDialog = dialogContext?.let {
|
||||
Dialog(it, com.gh.gamecenter.common.R.style.DialogWindowTransparent).apply {
|
||||
val binding = SetWaitDialogBinding.inflate(LayoutInflater.from(dialogContext)).apply {
|
||||
setWaitMessage.text = "请求登录中"
|
||||
if (dialogContext is Activity && (dialogContext.isFinishing || dialogContext.isDestroyed)) return@runOnUiThread
|
||||
preDialog = try {
|
||||
dialogContext?.let {
|
||||
Dialog(it, com.gh.gamecenter.common.R.style.DialogWindowTransparent).apply {
|
||||
val binding = SetWaitDialogBinding.inflate(LayoutInflater.from(dialogContext)).apply {
|
||||
setWaitMessage.text = "请求登录中"
|
||||
}
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
setContentView(binding.root)
|
||||
setCanceledOnTouchOutside(false)
|
||||
show()
|
||||
}
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
setContentView(binding.root)
|
||||
setCanceledOnTouchOutside(false)
|
||||
show()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// no implement
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
isDarkMode = DarkModeUtils.isDarkModeOn(context)
|
||||
setUiConfig(context, callback)
|
||||
val settings = LoginSettings()
|
||||
@ -136,7 +140,6 @@ object LoginHelper {
|
||||
}
|
||||
|
||||
8 -> { // 点击了一键登录按钮
|
||||
showLoggingDialog()
|
||||
SensorsBridge.trackEvent("Login", "login_type", "一键登录")
|
||||
}
|
||||
}
|
||||
@ -156,7 +159,6 @@ object LoginHelper {
|
||||
}
|
||||
|
||||
LOGIN_AUTH_CODE_FAILURE -> {
|
||||
dismissDialog()
|
||||
getLoginProvider()?.startCodeLoginPageFromQuickLogin(openAuthPageSuccess, context, callback)
|
||||
}
|
||||
}
|
||||
@ -167,9 +169,6 @@ object LoginHelper {
|
||||
if (preDialog?.isShowing == true) {
|
||||
preDialog?.dismiss()
|
||||
}
|
||||
if (loggingDialog?.isShowing == true) {
|
||||
loggingDialog?.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUiConfig(context: Context, callback: (() -> Unit)?) {
|
||||
@ -259,15 +258,6 @@ object LoginHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private fun showLoggingDialog() {
|
||||
AppManager.getInstance().recentActiveActivity?.run {
|
||||
val dialogContext = com.gh.gamecenter.common.utils.DialogHelper.checkDialogContext(this)
|
||||
if (dialogContext == null || (dialogContext is Activity && dialogContext.isFinishing)) return
|
||||
loggingDialog = getLoginProvider()?.createLoggingDialog(dialogContext)
|
||||
loggingDialog?.show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showPrivacyCheckDialog(
|
||||
authContext: Context,
|
||||
context: Context,
|
||||
@ -332,7 +322,6 @@ object LoginHelper {
|
||||
|
||||
fun release() {
|
||||
backgroundView = null
|
||||
loggingDialog = null
|
||||
preDialog = null
|
||||
isPolicyCheck = false
|
||||
loginToken = ""
|
||||
|
||||
@ -63,6 +63,11 @@ class CustomLayoutInflaterFactory(
|
||||
view.dimOnDarkMode()
|
||||
}
|
||||
|
||||
// 为每个Fragment的子view添加对应Fragment的Tag
|
||||
parent?.getTag(androidx.fragment.R.id.fragment_container_view_tag)?.let {
|
||||
view?.setTag(androidx.fragment.R.id.fragment_container_view_tag, it)
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.brotli.BrotliInterceptor;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
@ -38,6 +39,7 @@ public abstract class BaseRetrofitManager {
|
||||
final Cache cache = new Cache(new File(OkHttpCache.getCachePath(context)), 10 * 1024 * 1024); // 10Mb
|
||||
|
||||
return Injection.provideRetrofitBuilder()
|
||||
.addInterceptor(BrotliInterceptor.INSTANCE)
|
||||
.addInterceptor(new OkHttpCacheInterceptor(context))
|
||||
.addInterceptor(new OkHttpRetryInterceptor(context, maxRetryCount))
|
||||
.addInterceptor(new ChuckerInterceptor(context, new ChuckerCollector(context, true, RetentionManager.Period.ONE_DAY)))
|
||||
|
||||
@ -13,7 +13,9 @@ import com.gh.gamecenter.core.provider.IUserManagerProvider
|
||||
import com.gh.gamecenter.core.utils.MtaHelper
|
||||
import com.lightgame.config.CommonDebug
|
||||
import okhttp3.*
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.Response
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
@ -43,12 +45,12 @@ class OkHttpRetryInterceptor constructor(context: Context, val maxRetryCount: In
|
||||
|
||||
var tryCount = 0
|
||||
val token = chain.request().header("token")
|
||||
val url = request.url().toString()
|
||||
while ((response == null || (token != null && response.code() == 401 && (!url.contains("refresh")))) // 排除刷新token接口,避免进入死循环
|
||||
val url = request.url.toString()
|
||||
while ((response == null || (token != null && response.code == 401 && (!url.contains("refresh")))) // 排除刷新token接口,避免进入死循环
|
||||
&& ++tryCount <= maxRetryCount
|
||||
) {
|
||||
if (CommonDebug.IS_DEBUG) {
|
||||
CommonDebug.logMethodWithParams(this, "Retrying ${request.url()} for $tryCount")
|
||||
CommonDebug.logMethodWithParams(this, "Retrying ${request.url} for $tryCount")
|
||||
}
|
||||
|
||||
if (url.contains("users:validate") && !TextUtils.isEmpty(request.header("retry"))
|
||||
@ -70,7 +72,7 @@ class OkHttpRetryInterceptor constructor(context: Context, val maxRetryCount: In
|
||||
tryCount = maxRetryCount + 1 // 只要token刷新异常直接主动退出登录
|
||||
if (e != null && e.isNotEmpty()) {
|
||||
response =
|
||||
response?.newBuilder()?.body(ResponseBody.create(MediaType.parse("application/json"), e))
|
||||
response?.newBuilder()?.body(e.toResponseBody("application/json".toMediaTypeOrNull()))
|
||||
?.build()
|
||||
}
|
||||
})
|
||||
@ -81,9 +83,9 @@ class OkHttpRetryInterceptor constructor(context: Context, val maxRetryCount: In
|
||||
val buildConfig =
|
||||
ARouter.getInstance().build(RouteConsts.provider.buildConfig).navigation() as IBuildConfigProvider
|
||||
// 上报网络错误,过滤 404 以及非用户可感知的请求
|
||||
val api = pathSegmentsToString(request.url().pathSegments())
|
||||
val api = pathSegmentsToString(request.url.pathSegments)
|
||||
if (tryCount == maxRetryCount + 1
|
||||
&& (response == null || response?.code() != 404)
|
||||
&& (response == null || response?.code != 404)
|
||||
&& isUserAwareApi(api)
|
||||
) {
|
||||
MtaHelper.onEvent(
|
||||
|
||||
@ -68,7 +68,9 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.io.*
|
||||
@ -652,25 +654,25 @@ fun String.copyTextAndToast(toastText: String = "复制成功") {
|
||||
|
||||
fun Map<String, String>.createRequestBody(): RequestBody {
|
||||
val json = GsonUtils.toJson(this)
|
||||
return RequestBody.create(MediaType.parse("application/json"), json)
|
||||
return json.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
}
|
||||
|
||||
fun Map<String, Any>.createRequestBodyAny(): RequestBody {
|
||||
val json = GsonUtils.toJson(this)
|
||||
return RequestBody.create(MediaType.parse("application/json"), json)
|
||||
return json.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
}
|
||||
|
||||
fun Any.toRequestBody(): RequestBody {
|
||||
val json = GsonUtils.toJson(this)
|
||||
return RequestBody.create(MediaType.parse("application/json"), json)
|
||||
return json.toRequestBody("application/json".toMediaTypeOrNull())
|
||||
}
|
||||
|
||||
fun JSONObject.toRequestBody(): RequestBody {
|
||||
return RequestBody.create(MediaType.parse("application/json"), this.toString())
|
||||
return this.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
}
|
||||
|
||||
fun JSONArray.toRequestBody(): RequestBody {
|
||||
return RequestBody.create(MediaType.parse("application/json"), this.toString())
|
||||
return this.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
}
|
||||
|
||||
// 对在浏览器(WebView)显示的路径进行转码
|
||||
|
||||
@ -8,8 +8,14 @@ import android.graphics.drawable.ColorDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.facebook.common.executors.CallerThreadExecutor
|
||||
import com.facebook.common.references.CloseableReference
|
||||
@ -406,6 +412,23 @@ object ImageUtils {
|
||||
return modifiedUrl
|
||||
}
|
||||
|
||||
private fun View.findFragment(): Fragment? {
|
||||
var view: View? = this
|
||||
val addTagViewList = ArrayList<View>()
|
||||
while (view != null) {
|
||||
val tag = view.getTag(androidx.fragment.R.id.fragment_container_view_tag)
|
||||
if (tag is Fragment) {
|
||||
addTagViewList.forEach {
|
||||
it.setTag(androidx.fragment.R.id.fragment_container_view_tag, tag)
|
||||
}
|
||||
return tag
|
||||
}
|
||||
addTagViewList.add(view)
|
||||
view = view.parent as? View
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun loadImage(
|
||||
view: SimpleDraweeView?,
|
||||
highResUrl: String,
|
||||
@ -414,6 +437,14 @@ object ImageUtils {
|
||||
shouldNotSaveMemoryCache: Boolean,
|
||||
controllerListener: BaseControllerListener<ImageInfo>? = null,
|
||||
) {
|
||||
val lifecycleObserver = view?.getTag(R.id.lifecycle_observer) as? LifecycleObserver
|
||||
val lifecycle = if (lifecycleObserver != null) view.findFragment()?.viewLifecycleOwner?.lifecycle else null
|
||||
lifecycleObserver?.let {
|
||||
lifecycle?.removeObserver(it)
|
||||
view.setTag(R.id.lifecycle_observer, null)
|
||||
}
|
||||
|
||||
val listener = getFinalControllerListener(view, controllerListener, lifecycle)
|
||||
val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(highResUrl))
|
||||
.apply {
|
||||
if (shouldNotSaveMemoryCache) {
|
||||
@ -424,7 +455,7 @@ object ImageUtils {
|
||||
.build()
|
||||
val controller = Fresco.newDraweeControllerBuilder()
|
||||
.setImageRequest(imageRequest)
|
||||
.setControllerListener(controllerListener)
|
||||
.setControllerListener(listener)
|
||||
.apply {
|
||||
if (lowResUrl.isNotEmpty()
|
||||
&& lowResUrl != highResUrl
|
||||
@ -443,6 +474,59 @@ object ImageUtils {
|
||||
view?.setTag(R.string.highResImageTag, highResUrl)
|
||||
}
|
||||
|
||||
private fun getFinalControllerListener(
|
||||
view: SimpleDraweeView?,
|
||||
controllerListener: BaseControllerListener<ImageInfo>?,
|
||||
lifecycle: Lifecycle?
|
||||
) = object : BaseControllerListener<ImageInfo>() {
|
||||
override fun onSubmit(id: String?, callerContext: Any?) {
|
||||
super.onSubmit(id, callerContext)
|
||||
controllerListener?.onSubmit(id, callerContext)
|
||||
}
|
||||
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
|
||||
super.onFinalImageSet(id, imageInfo, animatable)
|
||||
controllerListener?.onFinalImageSet(id, imageInfo, animatable)
|
||||
animatable?.let {
|
||||
(lifecycle ?: view?.findFragment()?.viewLifecycleOwner?.lifecycle)?.run {
|
||||
val observer = object : DefaultLifecycleObserver {
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
super.onPause(owner)
|
||||
it.stop()
|
||||
}
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
super.onResume(owner)
|
||||
it.start()
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
super.onDestroy(owner)
|
||||
removeObserver(this)
|
||||
}
|
||||
}
|
||||
view?.setTag(R.id.lifecycle_observer, observer)
|
||||
addObserver(observer)
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun onIntermediateImageSet(id: String?, imageInfo: ImageInfo?) {
|
||||
super.onIntermediateImageSet(id, imageInfo)
|
||||
controllerListener?.onIntermediateImageSet(id, imageInfo)
|
||||
}
|
||||
override fun onIntermediateImageFailed(id: String?, throwable: Throwable?) {
|
||||
super.onIntermediateImageFailed(id, throwable)
|
||||
controllerListener?.onIntermediateImageFailed(id, throwable)
|
||||
}
|
||||
override fun onFailure(id: String?, throwable: Throwable?) {
|
||||
super.onFailure(id, throwable)
|
||||
controllerListener?.onFailure(id, throwable)
|
||||
}
|
||||
override fun onRelease(id: String?) {
|
||||
super.onRelease(id)
|
||||
controllerListener?.onRelease(id)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addCachedUrl(url: String) {
|
||||
imageDecorationThread.execute {
|
||||
if (url.startsWith("http")) {
|
||||
|
||||
@ -26,7 +26,7 @@ object SensorsBridge {
|
||||
private const val KEY_LAST_PAGE_BUSINESS_ID = "last_page_business_id"
|
||||
private const val KEY_DOWNLOAD_STATUS = "download_status"
|
||||
private const val KEY_DOWNLOAD_TYPE = "download_type"
|
||||
private const val KEY_GAME_SCHEME_TYPE = "game_scheme_type"
|
||||
private const val KEY_GAME_SCHEMA_TYPE = "game_schema_type"
|
||||
private const val KEY_GAME_TYPE = "game_type"
|
||||
const val KEY_POSITION = "position"
|
||||
const val KEY_TAB_CONTENT = "tab_content"
|
||||
@ -88,8 +88,6 @@ object SensorsBridge {
|
||||
private const val KEY_VERIFICATION_TYPE = "verification_type"
|
||||
private const val KEY_VIDEO_ID = "video_id"
|
||||
private const val KEY_PLAY_TYPE = "play_type"
|
||||
private const val KEY_LABEL_NAME = "label_name"
|
||||
private const val KEY_LABEL_ID = "label_id"
|
||||
const val KEY_BOTTOM_TAB = "bottom_tab"
|
||||
const val KEY_MULTI_TAB_NAME = "several_tab_page_name"
|
||||
const val KEY_MULTI_TAB_ID = "several_tab_page_id"
|
||||
@ -293,8 +291,6 @@ object SensorsBridge {
|
||||
|
||||
private const val EVENT_COLUMN_TEST_CLICK = "ColumnTestClick"
|
||||
|
||||
private const val EVENT_SEARCH_DISCOVERY_CLICK = "SearchDiscoveryClick"
|
||||
|
||||
private const val EVENT_BYPASS_BROWSING = "BypassBrowsing"
|
||||
private const val EVENT_FAIL_BYPASS = "FailBypass"
|
||||
|
||||
@ -4013,7 +4009,7 @@ object SensorsBridge {
|
||||
* 触发时机:当下载悬浮窗引导图展示时触发上报
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @param gameSchemeType 游戏架构类型:64位/32位
|
||||
* @param gameSchemaType 游戏架构类型:64位/32位
|
||||
* @param downloadStatus 游戏下载状态
|
||||
* @param gameType 游戏的类型:单机、网游等
|
||||
* @param downloadType 实际下载方式:本地下载/畅玩下载
|
||||
@ -4022,7 +4018,7 @@ object SensorsBridge {
|
||||
fun trackDownloadSuspendedWindowGuideShow(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
gameSchemeType: String,
|
||||
gameSchemaType: String,
|
||||
downloadStatus: String,
|
||||
gameType: String,
|
||||
downloadType: String
|
||||
@ -4030,7 +4026,7 @@ object SensorsBridge {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_GAME_SCHEME_TYPE to gameSchemeType
|
||||
KEY_GAME_SCHEMA_TYPE to gameSchemaType
|
||||
KEY_DOWNLOAD_STATUS to downloadStatus
|
||||
KEY_GAME_TYPE to gameType
|
||||
KEY_DOWNLOAD_TYPE to downloadType
|
||||
@ -4070,7 +4066,7 @@ object SensorsBridge {
|
||||
* @param source 来源:游戏下载\重启APP
|
||||
* @param downloadType 所上报游戏的实际下载方式:本地下载/畅玩下载
|
||||
* @param downloadStatus 所上报游戏下载状态
|
||||
* @param gameSchemeType 所上报游戏架构类型:64位/32位
|
||||
* @param gameSchemaType 所上报游戏架构类型:64位/32位
|
||||
* @param gameType 游戏的类型:单机、网游等
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
@ -4079,7 +4075,7 @@ object SensorsBridge {
|
||||
source: String,
|
||||
downloadType: String,
|
||||
downloadStatus: String,
|
||||
gameSchemeType: String,
|
||||
gameSchemaType: String,
|
||||
gameType: String,
|
||||
gameId: String,
|
||||
gameName: String
|
||||
@ -4088,7 +4084,7 @@ object SensorsBridge {
|
||||
KEY_SOURCE to source
|
||||
KEY_DOWNLOAD_TYPE to downloadType
|
||||
KEY_DOWNLOAD_STATUS to downloadStatus
|
||||
KEY_GAME_SCHEME_TYPE to gameSchemeType
|
||||
KEY_GAME_SCHEMA_TYPE to gameSchemaType
|
||||
KEY_GAME_TYPE to gameType
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
@ -4103,7 +4099,7 @@ object SensorsBridge {
|
||||
* @param source 来源:游戏下载\重启APP
|
||||
* @param downloadType 所上报游戏的实际下载方式:本地下载/畅玩下载
|
||||
* @param downloadStatus 所上报游戏下载状态
|
||||
* @param gameSchemeType 所上报游戏架构类型:64位/32位
|
||||
* @param gameSchemaType 所上报游戏架构类型:64位/32位
|
||||
* @param gameType 游戏的类型:单机、网游等
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
@ -4112,7 +4108,7 @@ object SensorsBridge {
|
||||
source: String,
|
||||
downloadType: String,
|
||||
downloadStatus: String,
|
||||
gameSchemeType: String,
|
||||
gameSchemaType: String,
|
||||
gameType: String,
|
||||
gameId: String,
|
||||
gameName: String
|
||||
@ -4121,7 +4117,7 @@ object SensorsBridge {
|
||||
KEY_SOURCE to source
|
||||
KEY_DOWNLOAD_TYPE to downloadType
|
||||
KEY_DOWNLOAD_STATUS to downloadStatus
|
||||
KEY_GAME_SCHEME_TYPE to gameSchemeType
|
||||
KEY_GAME_SCHEMA_TYPE to gameSchemaType
|
||||
KEY_GAME_TYPE to gameType
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
@ -4135,7 +4131,7 @@ object SensorsBridge {
|
||||
* 触发时机:触发自动下载提示条展示时上报
|
||||
* @param downloadType 所上报游戏的实际下载方式:本地下载/畅玩下载
|
||||
* @param downloadStatus 所上报游戏下载状态
|
||||
* @param gameSchemeType 所上报游戏架构类型:64位/32位
|
||||
* @param gameSchemaType 所上报游戏架构类型:64位/32位
|
||||
* @param gameType 游戏的类型:单机、网游等
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
@ -4143,7 +4139,7 @@ object SensorsBridge {
|
||||
fun trackAutomaticInstallationPromptBarShow(
|
||||
downloadType: String,
|
||||
downloadStatus: String,
|
||||
gameSchemeType: String,
|
||||
gameSchemaType: String,
|
||||
gameType: String,
|
||||
gameId: String,
|
||||
gameName: String
|
||||
@ -4151,7 +4147,7 @@ object SensorsBridge {
|
||||
val json = json {
|
||||
KEY_DOWNLOAD_TYPE to downloadType
|
||||
KEY_DOWNLOAD_STATUS to downloadStatus
|
||||
KEY_GAME_SCHEME_TYPE to gameSchemeType
|
||||
KEY_GAME_SCHEMA_TYPE to gameSchemaType
|
||||
KEY_GAME_TYPE to gameType
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
@ -4165,7 +4161,7 @@ object SensorsBridge {
|
||||
* 触发时机:触发自动下载提示条点击时上报
|
||||
* @param downloadType 所上报游戏的实际下载方式:本地下载/畅玩下载
|
||||
* @param downloadStatus 所上报游戏下载状态
|
||||
* @param gameSchemeType 所上报游戏架构类型:64位/32位
|
||||
* @param gameSchemaType 所上报游戏架构类型:64位/32位
|
||||
* @param gameType 游戏的类型:单机、网游等
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
@ -4173,7 +4169,7 @@ object SensorsBridge {
|
||||
fun trackAutomaticInstallationPromptBarClick(
|
||||
downloadType: String,
|
||||
downloadStatus: String,
|
||||
gameSchemeType: String,
|
||||
gameSchemaType: String,
|
||||
gameType: String,
|
||||
gameId: String,
|
||||
gameName: String
|
||||
@ -4181,7 +4177,7 @@ object SensorsBridge {
|
||||
val json = json {
|
||||
KEY_DOWNLOAD_TYPE to downloadType
|
||||
KEY_DOWNLOAD_STATUS to downloadStatus
|
||||
KEY_GAME_SCHEME_TYPE to gameSchemeType
|
||||
KEY_GAME_SCHEMA_TYPE to gameSchemaType
|
||||
KEY_GAME_TYPE to gameType
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
@ -4195,7 +4191,7 @@ object SensorsBridge {
|
||||
* 触发时机:下载组件展示时上报
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @param gameSchemeType 游戏架构类型:64位/32位
|
||||
* @param gameSchemaType 游戏架构类型:64位/32位
|
||||
* @param downloadStatus 所上报游戏下载状态
|
||||
* @param gameType 游戏的类型:单机、网游等
|
||||
* @param downloadType 所上报游戏的实际下载方式:本地下载/畅玩下载
|
||||
@ -4203,7 +4199,7 @@ object SensorsBridge {
|
||||
fun trackDownloadComponentsShow(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
gameSchemeType: String,
|
||||
gameSchemaType: String,
|
||||
downloadStatus: String,
|
||||
gameType: String,
|
||||
downloadType: String,
|
||||
@ -4211,7 +4207,7 @@ object SensorsBridge {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_GAME_SCHEME_TYPE to gameSchemeType
|
||||
KEY_GAME_SCHEMA_TYPE to gameSchemaType
|
||||
KEY_DOWNLOAD_STATUS to downloadStatus
|
||||
KEY_GAME_TYPE to gameType
|
||||
KEY_DOWNLOAD_TYPE to downloadType
|
||||
@ -4225,7 +4221,7 @@ object SensorsBridge {
|
||||
* 触发时机:下载组件点击时上报
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @param gameSchemeType 游戏架构类型:64位/32位
|
||||
* @param gameSchemaType 游戏架构类型:64位/32位
|
||||
* @param downloadStatus 所上报游戏下载状态
|
||||
* @param gameType 游戏的类型:单机、网游等
|
||||
* @param downloadType 所上报游戏的实际下载方式:本地下载/畅玩下载
|
||||
@ -4235,7 +4231,7 @@ object SensorsBridge {
|
||||
fun trackDownloadComponentsContentClick(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
gameSchemeType: String,
|
||||
gameSchemaType: String,
|
||||
downloadStatus: String,
|
||||
gameType: String,
|
||||
downloadType: String,
|
||||
@ -4245,7 +4241,7 @@ object SensorsBridge {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_GAME_SCHEME_TYPE to gameSchemeType
|
||||
KEY_GAME_SCHEMA_TYPE to gameSchemaType
|
||||
KEY_DOWNLOAD_STATUS to downloadStatus
|
||||
KEY_GAME_TYPE to gameType
|
||||
KEY_DOWNLOAD_TYPE to downloadType
|
||||
@ -4339,31 +4335,6 @@ object SensorsBridge {
|
||||
trackEvent(EVENT_HALO_SELF_CLICK, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:SearchDiscoveryClick
|
||||
* 事件名称:搜索发现点击事件
|
||||
* 触发时机:点击搜索发现时触发
|
||||
* @param labelName 标签名称
|
||||
* @param labelId 标签ID
|
||||
* @param searchContent 搜索内容
|
||||
* @param position 序号
|
||||
* @see EVENT_SEARCH_DISCOVERY_CLICK
|
||||
*/
|
||||
fun trackSearchDiscoveryClick(
|
||||
labelName: String,
|
||||
labelId: String,
|
||||
searchContent: String,
|
||||
position: Int
|
||||
) {
|
||||
val json = json {
|
||||
KEY_LABEL_NAME to labelName
|
||||
KEY_LABEL_ID to labelId
|
||||
KEY_SEARCH_CONTENT to searchContent
|
||||
KEY_POSITION to position
|
||||
}
|
||||
trackEvent(EVENT_SEARCH_DISCOVERY_CLICK, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:BypassBrowsing
|
||||
* 事件名称:分流器访问事件
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<item name="root_container" type="id" />
|
||||
<item name="lifecycle_observer" type="id" />
|
||||
</resources>
|
||||
@ -58,6 +58,7 @@ dependencies {
|
||||
api "com.jakewharton.rxbinding2:rxbinding:${rxBinding2}"
|
||||
api "com.github.tbruyelle:rxpermissions:${rxPermissions}"
|
||||
api "com.squareup.okhttp3:okhttp:${okHttp}"
|
||||
api "com.squareup.okhttp3:okhttp-brotli:${okHttp}"
|
||||
api "com.squareup.retrofit2:retrofit:${retrofit}"
|
||||
api "com.squareup.retrofit2:converter-gson:${retrofit}" // include gson 2.7
|
||||
api "com.squareup.retrofit2:adapter-rxjava2:${retrofit}"
|
||||
|
||||
@ -15,8 +15,6 @@ interface ILoginProvider : IProvider {
|
||||
callback: () -> Unit
|
||||
)
|
||||
|
||||
fun createLoggingDialog(context: Context): Dialog
|
||||
|
||||
fun createQuickLoginBackgroundView(context: Context): View
|
||||
|
||||
fun startQuickLoginHelperPageFromQuickLogin(loginToken: String, context: Context, callback: (() -> Unit)?)
|
||||
|
||||
@ -6,6 +6,8 @@ import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class ProcessUtil {
|
||||
@ -20,13 +22,25 @@ public class ProcessUtil {
|
||||
return currentProcessName;
|
||||
}
|
||||
|
||||
//1)通过Application的API获取当前进程名
|
||||
//0)通过反射 ActivityThread 获取实例再获取当前进程名
|
||||
currentProcessName = getCurrentProcessNameByActivityThreadInstance();
|
||||
if (!TextUtils.isEmpty(currentProcessName)) {
|
||||
return currentProcessName;
|
||||
}
|
||||
|
||||
//1)通过 CMD 获取当前进程名
|
||||
currentProcessName = getCurrentProcessNameByCMD(android.os.Process.myPid());
|
||||
if (!TextUtils.isEmpty(currentProcessName)) {
|
||||
return currentProcessName;
|
||||
}
|
||||
|
||||
//2)通过 Application 的 API 获取当前进程名
|
||||
currentProcessName = getCurrentProcessNameByApplication();
|
||||
if (!TextUtils.isEmpty(currentProcessName)) {
|
||||
return currentProcessName;
|
||||
}
|
||||
|
||||
//2)通过反射ActivityThread获取当前进程名
|
||||
//3)通过反射 ActivityThread 获取当前进程名
|
||||
currentProcessName = getCurrentProcessNameByActivityThread();
|
||||
if (!TextUtils.isEmpty(currentProcessName)) {
|
||||
return currentProcessName;
|
||||
@ -38,7 +52,7 @@ public class ProcessUtil {
|
||||
/**
|
||||
* 通过Application新的API获取进程名,无需反射,无需IPC,效率最高。
|
||||
*/
|
||||
public static String getCurrentProcessNameByApplication() {
|
||||
private static String getCurrentProcessNameByApplication() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
return Application.getProcessName();
|
||||
}
|
||||
@ -48,7 +62,7 @@ public class ProcessUtil {
|
||||
/**
|
||||
* 通过反射ActivityThread获取进程名,避免了ipc
|
||||
*/
|
||||
public static String getCurrentProcessNameByActivityThread() {
|
||||
private static String getCurrentProcessNameByActivityThread() {
|
||||
String processName = null;
|
||||
try {
|
||||
final Method declaredMethod = Class.forName("android.app.ActivityThread", false, Application.class.getClassLoader())
|
||||
@ -64,4 +78,52 @@ public class ProcessUtil {
|
||||
return processName;
|
||||
}
|
||||
|
||||
private static String getCurrentProcessNameByActivityThreadInstance() {
|
||||
try {
|
||||
// Get ActivityThread class
|
||||
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread",false, Application.class.getClassLoader());
|
||||
|
||||
// Get the current ActivityThread instance
|
||||
Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread");
|
||||
currentActivityThreadMethod.setAccessible(true);
|
||||
Object activityThread = currentActivityThreadMethod.invoke(null);
|
||||
|
||||
// Get the getProcessName method
|
||||
Method getProcessNameMethod = activityThreadClass.getDeclaredMethod("getProcessName");
|
||||
getProcessNameMethod.setAccessible(true);
|
||||
|
||||
// Call the getProcessName method
|
||||
return (String) getProcessNameMethod.invoke(activityThread);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getCurrentProcessNameByCMD(int pid) {
|
||||
//get from /proc/PID/cmdline
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader("/proc/" + pid + "/cmdline"));
|
||||
String processName = br.readLine();
|
||||
if (!TextUtils.isEmpty(processName)) {
|
||||
processName = processName.trim();
|
||||
if (!TextUtils.isEmpty(processName)) {
|
||||
return processName; //OK
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
|
||||
} finally {
|
||||
try {
|
||||
if (br != null) {
|
||||
br.close();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
//failed
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
package com.gh.gamecenter.feature.entity
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
class DiscoveryTagEntity(
|
||||
@SerializedName("_id")
|
||||
var id: String? = "",
|
||||
var text: String? = "",
|
||||
@SerializedName("keyword")
|
||||
var _keyword: String? = ""
|
||||
) : Parcelable {
|
||||
val keyword get(): String {
|
||||
val keyword = this._keyword
|
||||
if (keyword.isNullOrEmpty()) {
|
||||
return text ?: ""
|
||||
}
|
||||
return keyword
|
||||
}
|
||||
}
|
||||
@ -70,8 +70,6 @@ class SettingsEntity(
|
||||
var hotSearch: List<HotSearch>? = listOf(),
|
||||
@SerializedName("tag")
|
||||
var hotTag: List<HotTagEntity>? = listOf(),
|
||||
@SerializedName("discover_tag")
|
||||
var discoveryTag: List<DiscoveryTagEntity>? = listOf(),
|
||||
@SerializedName("hot_list")
|
||||
var rankList: List<RankList>? = listOf(),
|
||||
@SerializedName("wechat_game_search_list")
|
||||
|
||||
@ -33,18 +33,6 @@ class LoginProviderImpl : ILoginProvider {
|
||||
}
|
||||
}
|
||||
|
||||
override fun createLoggingDialog(context: Context) =
|
||||
Dialog(context, com.gh.gamecenter.common.R.style.DialogWindowTransparent).apply {
|
||||
val binding = SetWaitDialogBinding.inflate(LayoutInflater.from(context)).apply {
|
||||
root.background = com.gh.gamecenter.common.R.drawable.background_shape_white_radius_8.toDrawable(context)
|
||||
setWaitMessage.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))
|
||||
setWaitMessage.text = R.string.logging.toResString()
|
||||
}
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
setContentView(binding.root)
|
||||
setCanceledOnTouchOutside(false)
|
||||
}
|
||||
|
||||
override fun createQuickLoginBackgroundView(context: Context): View =
|
||||
LayoutQuickLoginBackgroundBinding.inflate(LayoutInflater.from(context)).root
|
||||
|
||||
|
||||
@ -75,10 +75,10 @@ class QuickLoginHelperActivity : BaseActivity(), LoginHelper.LoginCallback, Obse
|
||||
private fun login(content: JSONObject, loginTag: LoginTag) {
|
||||
val logUtils = ARouter.getInstance().build(RouteConsts.provider.logUtils).navigation() as? ILogUtilsProvider
|
||||
logUtils?.login("logging", loginTag.name, mEntrance)
|
||||
if (loginTag != LoginTag.oauth) {
|
||||
mLoginDialog = WaitingDialogFragment.newInstance(getString(R.string.logging))
|
||||
mLoginDialog?.show(supportFragmentManager, null)
|
||||
}
|
||||
|
||||
mLoginDialog = WaitingDialogFragment.newInstance(getString(R.string.logging))
|
||||
mLoginDialog?.show(supportFragmentManager, null)
|
||||
|
||||
mUserViewModel.login(content, loginTag)
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,9 @@ import io.reactivex.ObservableEmitter
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
@ -142,7 +144,7 @@ class MessageListViewModel(application: Application, private val mType: String,
|
||||
// 后端同步
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("type", "system_message")
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
mApi.postMessageRead(UserManager.getInstance().userId, messageId, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
||||
@ -158,7 +158,7 @@ class NetworkDiagnosisActivity : ToolBarActivity() {
|
||||
builder.append(response.toString())
|
||||
builder.append("\n")
|
||||
builder.append("Response Header:\n")
|
||||
builder.append(response.headers().toString())
|
||||
builder.append(response.headers.toString())
|
||||
builder.append("\n")
|
||||
} catch (e: IOException) {
|
||||
builder.append("Error:\n")
|
||||
|
||||
@ -16,7 +16,9 @@ import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
@ -37,7 +39,7 @@ class BindPhoneViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
params["mobile"] = phoneNum
|
||||
val jsonObject = JSONObject(params as Map<*, *>)
|
||||
jsonObject.put("device", device)
|
||||
val body: RequestBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body: RequestBody = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
|
||||
api.bindPhone(1, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
@ -88,7 +90,7 @@ class BindPhoneViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
}
|
||||
val jsonObject = JSONObject(params as Map<*, *>)
|
||||
jsonObject.put("device", device)
|
||||
val body: RequestBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body: RequestBody = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
|
||||
api.bindPhone(2, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
@ -132,7 +134,7 @@ class BindPhoneViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
params["mobile"] = phoneNum
|
||||
val jsonObject = JSONObject(params as Map<*, *>)
|
||||
jsonObject.put("device", device)
|
||||
val body: RequestBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body: RequestBody = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
|
||||
api.reBindPhone(1, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
@ -184,7 +186,7 @@ class BindPhoneViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
}
|
||||
val jsonObject = JSONObject(params as Map<*, *>)
|
||||
jsonObject.put("device", device)
|
||||
val body: RequestBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
val body: RequestBody = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
|
||||
|
||||
api.reBindPhone(2, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
@ -7,7 +7,7 @@ plugins {
|
||||
|
||||
android {
|
||||
// 在 DEFAULT_PLUGIN_URL 中提取插件版本号
|
||||
def defaultPluginUrl = "https://dev-app-static.796697.com/va/plugin/2024/09/02/1.0.3_64_1725265812586.zip"
|
||||
def defaultPluginUrl = "https://app-static.796697.com/va/plugin/2024/10/17/1.0.3_64_1729148903919.zip"
|
||||
def versionText = defaultPluginUrl.substring(defaultPluginUrl.lastIndexOf("/") + 1)
|
||||
def pluginVersionPattern = ~/^\d+.\d+.\d+/
|
||||
def matcher = versionText =~ pluginVersionPattern
|
||||
|
||||
2
vasdk
2
vasdk
Submodule vasdk updated: a13dc8061e...473be43ac0
Reference in New Issue
Block a user