Compare commits

...

24 Commits

Author SHA1 Message Date
47b0a8d1ac 版本更新至 4.9.6-337 2021-06-17 10:43:33 +08:00
1ae63d3010 Merge branch 'hotfix-v4.9.6-336-recreate' into 'release'
修复首页和游戏详情页页面重建时的 tab 显示问题

See merge request halo/android/assistant-android!116
2021-06-17 10:39:51 +08:00
9b9777ae19 修复首页和游戏详情页页面重建时的 tab 显示问题 2021-06-16 16:18:55 +08:00
814cef6218 Merge branch 'hotfix-v4.9.6-336-crash' into 'release'
1.修复Xapk解压过程中获取解压文件大小时的闪退问题

See merge request halo/android/assistant-android!115
2021-06-15 11:55:02 +08:00
lyr
fd6c4836d4 1.修复Xapk解压过程中获取解压文件大小时的闪退问题
2.修复新分类2.0游戏列表时的空指针问题
3.修复新分类2.0已选分类列表的数组越界问题
2021-06-15 11:51:22 +08:00
9df138ed7c Merge branch 'hotfix-v4.9.6-336-install' into 'release'
特殊处理山寨机在后台开启使用浏览器安装时的安装 intent

See merge request halo/android/assistant-android!114
2021-06-15 11:02:37 +08:00
1f34f95e7c 特殊处理山寨机在后台开启使用浏览器安装时的安装 intent 2021-06-10 09:53:54 +08:00
f826dc07c6 版本更新至 4.9.6 2021-06-08 10:23:08 +08:00
34670d08c0 Merge branch 'hotfix-v4.9.5-335-crash' into 'release'
Hotfix v4.9.5 335 crash

See merge request halo/android/assistant-android!113
2021-06-08 10:22:04 +08:00
5e5646468e 1. 捕抓分类2.0页面延迟操作造成的闪退异常
2. 修复首页滑动 tab 时偶发的闪退
3. 捕抓模拟器游戏延迟操作造成的闪退异常
4. 捕抓礼包详情页延迟操作造成的闪退异常
2021-06-08 10:22:04 +08:00
039203408a 版本更新至 4.9.5 2021-05-31 10:32:07 +08:00
60b325812e Merge branch 'hotfix-v4.9.4-334-crash' into 'release'
Hotfix v4.9.4 334 crash

See merge request halo/android/assistant-android!112
2021-05-31 10:29:00 +08:00
06a43f617b 处理闪退
1. 处理首页 tab 触摸时某些设备可能会闪退的问题
2. 修复游戏库刷新按钮被遮盖的问题
3. 尝试修复游戏库横向列表因恢复滚动状态而出现的闪退
4. 修复偶发的因为获取不到渠道号而触发的闪退
5. 尝试修复启动时偶发的初始化图片加载库触发的闪退
6. 修复 Android 11 首次安装 XAPK 获取权限回到页面时的闪退问题
2021-05-31 10:29:00 +08:00
85d3412fd8 版本更新到 4.9.4 2021-05-28 10:28:06 +08:00
71b8cbbef3 Merge branch 'hotfix-v4.9.3-333-crash' into 'release'
Hotfix v4.9.3 333 crash

See merge request halo/android/assistant-android!111
2021-05-28 10:26:50 +08:00
dfc0183a14 1. 处理包名检测弹窗上报日志的空指针闪退问题
2. 捕抓评论列表一键登录可能触发的闪退问题
3. 修复礼包详情页重建时的闪退问题
4. 修复视频流评论页页面重建时的闪退问题
2021-05-28 10:26:50 +08:00
156e52f619 版本升级到 4.9.3 2021-05-26 14:26:49 +08:00
252cb3825b Merge branch 'hotfix-v4.9.2-332-crash' into 'release'
Hotfix v4.9.2 332 crash

See merge request halo/android/assistant-android!110
2021-05-26 14:26:14 +08:00
075a7e4e77 处理专题详情滚到顶部空指针异常 2021-05-26 09:55:30 +08:00
0c95f911d1 捕抓插件化数据库读写异常 2021-05-26 09:43:40 +08:00
49b74c9a37 修复包名检测弹窗的重建闪退问题 2021-05-25 14:37:31 +08:00
c4240440d1 版本更新到 4.9.2 2021-05-25 10:56:09 +08:00
e0205ec060 Merge branch 'hotfix-v4.9.1-331-crash' into 'release'
修复闪退

See merge request halo/android/assistant-android!109
2021-05-25 10:55:35 +08:00
895024aa09 1. 修复启动时初始化图片加载库可能的闪退问题
2. 修复游戏详情最新开服可能的闪退问题
3. 修复在越南/法语设备上启动会闪退的问题
2021-05-25 10:53:47 +08:00
29 changed files with 190 additions and 266 deletions

View File

@ -158,9 +158,11 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
}
if (this.getClass().getName().equals(xapkUnzipActivity) && !TextUtils.isEmpty(xapkUrl)) {
DownloadEntity downloadEntity = DownloadManager.getInstance(this).getDownloadEntityByUrl(xapkUrl);
PackageInstaller.install(this, downloadEntity, false);
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "");
SPUtils.setString(Constants.SP_XAPK_URL, "");
if (downloadEntity != null) {
PackageInstaller.install(this, downloadEntity, false);
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "");
SPUtils.setString(Constants.SP_XAPK_URL, "");
}
}
}

View File

@ -42,6 +42,7 @@ import org.greenrobot.eventbus.ThreadMode
/**
* 包名检测弹窗
*/
// TODO 将 gameEntity 放到 argument 里再取出,避免重建时为空
class PackageCheckDialogFragment : BaseDialogFragment() {
private lateinit var binding: FragmentPackageCheckBinding
@ -73,7 +74,9 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
EventBus.getDefault().register(this)
LogUtils.uploadPackageCheck("pkg_check_pop_click", "出现弹窗", gameEntity, "", "", "", "")
gameEntity?.let {
LogUtils.uploadPackageCheck("pkg_check_pop_click", "出现弹窗", it, "", "", "", "")
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

View File

@ -489,8 +489,8 @@ fun Float.sp2px(): Int {
return (this * scale + 0.5f).toInt()
}
fun Float.roundTo(n : Int) : Float {
return "%.${n}f".format(this).toFloat()
fun Float.roundTo(n: Int): Float {
return "%.${n}f".format(Locale.CHINA, this).toFloat()
}
/**

View File

@ -24,17 +24,24 @@ object HomePluggableHelper {
val apkList = gameEntity.getApk()
if (apkList.isNotEmpty()) {
val apk = apkList.first()
val filterData = mHomePluggableFilterDao.getDataByPkgName(apk.packageName)
if (filterData?.active == true) {
val filterTag = filterData.tag
return filterTag != "never" && apk.version != filterTag
tryCatchInRelease {
val filterData = mHomePluggableFilterDao.getDataByPkgName(apk.packageName)
if (filterData?.active == true) {
val filterTag = filterData.tag
return filterTag != "never" && apk.version != filterTag
}
}
}
return true
}
@JvmStatic
fun getPermanentInactivePluggablePackage() = mHomePluggableFilterDao.getDataByTag("never")
fun getPermanentInactivePluggablePackage(): List<HomePluggableFilterEntity>? {
tryCatchInRelease {
return mHomePluggableFilterDao.getDataByTag("never")
}
return emptyList()
}
@JvmStatic
fun activationFilterData() {

View File

@ -484,4 +484,22 @@ object ImageUtils {
fun getVideoSnapshot(videoUrl: String, progress: Long): String {
return "$videoUrl?x-oss-process=video/snapshot,t_$progress,f_jpg,w_0,h_0"
}
/**
* 虽然在 Application 里有使用子线程初始化但有可能出现初始化超时(卡住?)的情况,
* 这里反射获取 sDraweecontrollerbuildersupplier 根据是否有值确定是否被初始化了
*/
@JvmStatic
fun isFrescoInitialized(): Boolean {
val clazz = SimpleDraweeView::class.java
return try {
val field =
clazz.getDeclaredField("sDraweecontrollerbuildersupplier")
field.isAccessible = true
val obj = field[SimpleDraweeView::class.java]
obj != null
} catch (ignore: java.lang.Exception) {
false
}
}
}

View File

@ -956,6 +956,8 @@ public class LogUtils {
}
public static void uploadPackageCheck(String event, String action, GameEntity gameEntity, String linkTitle, String linkDesc, String downloadGameId, String downloadGameName) {
if (gameEntity == null) return;
PackageDialogEntity packageDialog = gameEntity.getPackageDialog();
if (packageDialog == null) return;
JSONObject object = new JSONObject();

View File

@ -108,7 +108,11 @@ object PackageInstaller {
@JvmStatic
fun getInstallIntent(context: Context, path: String): Intent {
var uri = Uri.fromFile(File(path))
val installIntent = Intent(Intent.ACTION_VIEW)
val installIntent = if (BrowserInstallHelper.isUseBrowserToInstallEnabledWithPackageMatched()) {
Intent(Intent.ACTION_INSTALL_PACKAGE)
} else {
Intent(Intent.ACTION_VIEW)
}
if ("smartisan" == Build.MANUFACTURER) {
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

View File

@ -274,7 +274,9 @@ object QuickLoginHelper {
private fun startCodeLoginPage(context: Context, entrance: String, isFinishAuth: Boolean, isFromPermission: Boolean) {
if (mPreDialog != null && mPreDialog!!.isShowing) {
mPreDialog?.dismiss()
tryWithDefaultCatch {
mPreDialog?.dismiss()
}
}
if (isFinishAuth) {

View File

@ -121,9 +121,14 @@ object XapkInstaller : IXapkUnzipListener {
DownloadManager.getInstance(mContext).updateDownloadEntity(downloadEntity)
}
SentryHelper.onEvent("XAPK_UNZIP_ERROR",
// 仅官网渠道上报 XAPK 异常信息
if (HaloApp.getInstance().channel == "GH_206") {
SentryHelper.onEvent(
"XAPK_UNZIP_ERROR",
"gameName", downloadEntity.name,
"errorDigest", exception.localizedMessage)
"errorDigest", exception.localizedMessage
)
}
debugOnly {
Utils.log("unzip", "onFailure->$exception")

View File

@ -1,5 +1,6 @@
package com.gh.common.xapk
import android.os.Build
import android.os.Environment
import com.gh.common.util.debounceActionWithInterval
import com.gh.common.util.getExtension
@ -207,8 +208,15 @@ class XapkUnzipThread(private var mDownloadEntity: DownloadEntity,
private fun getUnzipSize(path: String): Long {
var totalSize = 0L
ZipFile(File(path)).use {
for (entry in it.entries()) {
// 这里安卓5.0以下使用use会报错闪退
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ZipFile(File(path)).use {
for (entry in it.entries()) {
totalSize += entry.size
}
}
} else {
for (entry in ZipFile(File(path)).entries()) {
totalSize += entry.size
}
}

View File

@ -166,6 +166,28 @@ object BrowserInstallHelper {
}
}
/**
* 浏览器安装的后台开关 (返回仅包名匹配时的状态)
*/
@JvmStatic
fun isUseBrowserToInstallEnabledWithPackageMatched(): Boolean {
val settingsEntity = Config.getNewSettingsEntity()
if (settingsEntity == null) {
return false
} else {
settingsEntity.installModel.packages?.let {
for (packageName in it) {
if (mAllInstalledPackageList.contains(packageName)) {
return true
}
}
}
return false
}
}
fun onApkInstalled(path: String?) {
path?.let {
val fileName = path.substringAfterLast(File.separator).removeSuffix(DownloadServer.APK_SUFFIX)

View File

@ -196,7 +196,9 @@ public class LibaoDetailActivity extends ToolBarActivity implements LibaoDetailA
setNavigationTitle(mName);
mLibaoEntity = (LibaoEntity) HaloApp.get(LibaoEntity.TAG, false);
isClickReceiveBtnIn = getIntent().getBooleanExtra(EntranceUtils.KEY_IS_CLICK_RECEIVE_BTN, false);
mLibaoEntity.setClickReceiveBtnIn(isClickReceiveBtnIn);
if (mLibaoEntity != null) {
mLibaoEntity.setClickReceiveBtnIn(isClickReceiveBtnIn);
}
mIsScroll = true;
@ -319,7 +321,11 @@ public class LibaoDetailActivity extends ToolBarActivity implements LibaoDetailA
CheckLoginUtils.checkLogin(this, mEntrance, () ->
mLibaoDetailRv.postDelayed(() -> {
if (mAdapter.libaoDetailTopViewHolder != null) {
mAdapter.libaoDetailTopViewHolder.libaoCopyBtn.performClick();
try {
mAdapter.libaoDetailTopViewHolder.libaoCopyBtn.performClick();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 200)
);

View File

@ -24,7 +24,6 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.base.AppUncaughtHandler;
import com.gh.base.BaseActivity;
import com.gh.base.fragment.BaseFragment_ViewPager;
@ -52,6 +51,7 @@ import com.gh.common.util.ErrorHelper;
import com.gh.common.util.ExtensionsKt;
import com.gh.common.util.GsonUtils;
import com.gh.common.util.HomePluggableHelper;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.LogUtils;
import com.gh.common.util.LunchType;
import com.gh.common.util.MtaHelper;
@ -176,8 +176,12 @@ public class MainActivity extends BaseActivity {
super.onCreate(savedInstanceState);
setStatusBarColor(Color.TRANSPARENT);
if (!isFrescoInitialized()) {
BigImageViewer.initialize(FrescoImageLoader.with(this));
if (!ImageUtils.isFrescoInitialized()) {
try {
BigImageViewer.initialize(FrescoImageLoader.with(this));
} catch (Throwable e) {
e.printStackTrace();
}
}
Fragment fragmentFromFM = getSupportFragmentManager().findFragmentById(R.id.layout_activity_content);
@ -966,19 +970,4 @@ public class MainActivity extends BaseActivity {
context.startActivity(intent);
}
/**
* 虽然在 Application 里有使用子线程初始化但有可能出现初始化超时(卡住?)的情况,
* 这里反射获取 sDraweecontrollerbuildersupplier 根据是否有值确定是否被初始化了
*/
public boolean isFrescoInitialized() {
Class<SimpleDraweeView> clazz = SimpleDraweeView.class;
try {
Field field = clazz.getDeclaredField("sDraweecontrollerbuildersupplier");
field.setAccessible(true);
Object object = field.get(SimpleDraweeView.class);
return object != null;
} catch (Exception ignore) {
return false;
}
}
}

View File

@ -276,7 +276,7 @@ class CategoryV2Fragment : LazyFragment() {
if (position == 1 && SPUtils.getBoolean(Constants.SP_FIRST_ENTER_CATEGORY_V2, true)) {
SPUtils.setBoolean(Constants.SP_FIRST_ENTER_CATEGORY_V2, false)
mBinding?.drawerLayout?.postDelayed({
openDrawer()
tryCatchInRelease { openDrawer() }
}, 200L)
}
} else {

View File

@ -58,7 +58,7 @@ class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>
override fun provideListAdapter() = mAdapter
?: CategoryV2ListAdapter(
requireContext(),
mListViewModel,
mListViewModel ?: provideListViewModel(),
mCategoryViewModel ?: viewModelProviderFromParent(CategoryV2ViewModel.Factory(mCategoryId, mCategoryTitle), mCategoryId),
mEntrance).apply { mAdapter = this }
@ -80,7 +80,7 @@ class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>
initFilterView()
mListViewModel.refresh.observeNonNull(viewLifecycleOwner) { onRefresh() }
mListViewModel?.refresh?.observeNonNull(viewLifecycleOwner) { onRefresh() }
mCategoryViewModel?.run {
categoryPositionLiveData.observeNonNull(viewLifecycleOwner) {
directories[it.first].data?.get(it.second)?.run {
@ -114,11 +114,11 @@ class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>
visibility = View.VISIBLE
setOnConfigSetupListener(object : CategoryFilterView.OnCategoryFilterSetupListener {
override fun onSetupSortSize(sortSize: SubjectSettingEntity.Size) {
mListViewModel.updateSortConfig(sortSize = sortSize)
mListViewModel?.updateSortConfig(sortSize = sortSize)
}
override fun onSetupSortType(sortType: CategoryFilterView.SortType) {
mListViewModel.updateSortConfig(sortType = sortType)
mListViewModel?.updateSortConfig(sortType = sortType)
}
override fun onSetupSortCategory() {
@ -139,7 +139,7 @@ class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>
visibility = View.GONE
}
if (categoryId != null) mSubCategoryId = categoryId
mListViewModel.updateSortConfig(categoryIds = mSubCategoryId)
mListViewModel?.updateSortConfig(categoryIds = mSubCategoryId)
}
private fun addCategory(entity: CategoryEntity) {
@ -156,7 +156,7 @@ class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>
remove(entity)
if (size == 0) {
mBinding?.selectedCategoryContainer?.visibility = View.GONE
mListViewModel.updateSortConfig(categoryIds = mSubCategoryId)
mListViewModel?.updateSortConfig(categoryIds = mSubCategoryId)
} else {
updateCategoryGame()
}
@ -188,8 +188,11 @@ class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>
i = index
}
}
mBinding?.selectedCategoryContainer?.removeView(mSelectedViewList[i])
mSelectedViewList.removeAt(i)
if (i < mSelectedViewList.size) {
mBinding?.selectedCategoryContainer?.removeView(mSelectedViewList[i])
mSelectedViewList.removeAt(i)
}
}
}
@ -215,7 +218,7 @@ class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>
categoryIds.append("-")
}
}
mListViewModel.updateSortConfig(categoryIds = categoryIds.toString())
mListViewModel?.updateSortConfig(categoryIds = categoryIds.toString())
}
}

View File

@ -63,11 +63,12 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mViewModel = viewModelProviderFromParent()
savedInstanceState?.let { mDefaultSelectedTab = it.getInt(LAST_SELECTED_POSITION) }
}
override fun onFragmentFirstVisible() {
mViewModel = viewModelProviderFromParent()
mSearchToolbarFragment = childFragmentManager.findFragmentById(R.id.wrapper_toolbar) as SearchToolbarFragment?
?: SearchToolbarFragment()
setSearchHints()
@ -84,7 +85,6 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
updateAppBarStyle(Color.WHITE, false)
mViewModel?.getTabs()
mViewModel?.tabs?.observe(viewLifecycleOwner, Observer {
if (mDefaultSelectedTab == -1) {
mDefaultSelectedTab = mViewModel?.defaultTabPosition ?: 0
@ -174,8 +174,8 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
},
onPageScrolled = { position, positionOffset, _ ->
if (position + 1 != mTabTitleList.size) {
val currentAppBarColor = tabList[position].primaryColor
val incomingAppBarColor = tabList[position + 1].primaryColor
val currentAppBarColor = tabList.safelyGetInRelease(position)?.primaryColor ?: Color.WHITE
val incomingAppBarColor = tabList.safelyGetInRelease(position + 1)?.primaryColor ?: Color.WHITE
val proximatelySelectedPosition = if (positionOffset < 0.5) position else position + 1
@ -186,8 +186,8 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
}
// 颜色显示是否变更
val isContentStyleChanged = tabList[proximatelySelectedPosition].useLightStyle != mIsDisplayingLightContent
mIsDisplayingLightContent = tabList[proximatelySelectedPosition].useLightStyle
val isContentStyleChanged = tabList.safelyGetInRelease(proximatelySelectedPosition)?.useLightStyle != mIsDisplayingLightContent
mIsDisplayingLightContent = tabList.safelyGetInRelease(proximatelySelectedPosition)?.useLightStyle ?: false
mTabSelectedColor = if (mIsDisplayingLightContent) TAB_DEFAULT_COLOR_LIGHT else TAB_SELECTED_COLOR
mTabDefaultColor = if (mIsDisplayingLightContent) TAB_DEFAULT_COLOR_LIGHT else TAB_DEFAULT_COLOR

View File

@ -24,6 +24,10 @@ class HomeSearchToolWrapperViewModel(application: Application) : AndroidViewMode
var appBarOffset = 0
init {
getTabs()
}
@SuppressLint("CheckResult")
fun getTabs() {
RetrofitManager.getInstance(getApplication()).api

View File

@ -61,6 +61,13 @@ public class SearchToolWrapperFragment extends LazyFragment {
.replace(R.id.wrapper_toolbar, mSearchToolbarFragment)
.replace(R.id.wrapper_main_content, Objects.requireNonNull(mContentFragment)).commitAllowingStateLoss();
// 补上底部 tab 的高度
inflatedView.findViewById(R.id.wrapperLl).setPadding(
0,
0,
0,
(int) requireContext().getResources().getDimension(R.dimen.main_bottom_tab_height));
mCachedView.post(() -> mSearchToolbarFragment.updateSearchToolbarColor(Color.WHITE));
}

View File

@ -10,6 +10,7 @@ import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.iinterface.IOffsetable
import com.gh.common.util.TimeUtils
import com.gh.common.util.dip2px
import com.gh.common.util.tryCatchInRelease
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.GameHorizontalListBinding
import com.gh.gamecenter.entity.GameEntity
@ -51,7 +52,10 @@ class GameHorizontalSlideListViewHolder(val binding: GameHorizontalListBinding)
binding.horizontalRv.scrollToPosition(0)
}
} else {
binding.horizontalRv.scrollBy(offset, offset)
// 可能会因为上下复用数据变化而出现 IndexOutOfBoundsException 异常,毕竟有局部更新功能...
tryCatchInRelease {
binding.horizontalRv.scrollBy(offset, offset)
}
}
}
}

View File

@ -369,7 +369,6 @@ class GameDetailFragment : NormalFragment() {
args.getString(EntranceUtils.KEY_GAMEID),
args.getParcelable(GameEntity.TAG))
mViewModel = viewModelProviderFromParent(factory)
mViewModel.loadData()
mPackageViewModel = viewModelProvider(PackageViewModel.Factory())
mUserViewModel = viewModelProvider(UserViewModel.Factory(HaloApp.getInstance().application))

View File

@ -12,6 +12,7 @@ import androidx.lifecycle.ViewModelProvider
import com.gh.common.constant.Constants
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.history.HistoryHelper
import com.gh.common.runOnUiThread
import com.gh.common.util.*
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.gamedetail.entity.BigEvent
@ -30,12 +31,17 @@ import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException
import tv.danmaku.ijk.media.exo2.ExoSourceManager
import java.util.*
import kotlin.collections.ArrayList
class GameDetailViewModel(application: Application,
var gameId: String?,
var game: GameEntity?) : AndroidViewModel(application) {
init {
runOnUiThread {
loadData()
}
}
private val mApi = RetrofitManager.getInstance(getApplication()).api
private val mSensitiveApi = RetrofitManager.getInstance(application).sensitiveApi

View File

@ -1,11 +1,15 @@
package com.gh.gamecenter.gamedetail.desc
import android.content.Context
import android.view.*
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View.MeasureSpec
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.TimeUtils
import com.gh.common.util.safelyGetInRelease
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.ItemGameDetailLatestServiceBinding
import com.gh.gamecenter.databinding.ItemGameDetailMoreBinding
@ -79,7 +83,10 @@ class GameLatestServiceAdapter(val context: Context, val datas: ArrayList<Server
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is GameLatestServiceViewHolder) {
val entity = if (mIsExpand) mExpandEntities[position] else mShrinkEntities[position]
// TODO 这里会数组越界,需要检查原因
val entity = (if (mIsExpand) mExpandEntities.safelyGetInRelease(position) else mShrinkEntities.safelyGetInRelease(position))
?: return
holder.binding.timeTv.text = TimeUtils.getFormatDate(entity.getTime())
holder.binding.serviceNameTv.text = "${entity.getNote()} ${entity.remark}"

View File

@ -1,17 +1,15 @@
package com.gh.gamecenter.simulatorgame
import android.app.Dialog
import android.graphics.Color
import android.graphics.Paint
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.widget.*
import androidx.core.content.ContextCompat
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentStatePagerAdapter
@ -122,7 +120,7 @@ class SimulatorGameFragment : NormalFragment() {
})
mViewModel.simulatorGameLoadSuccess.observe(viewLifecycleOwner, Observer {
AppExecutor.uiExecutor.executeWithDelay(Runnable {
showSimulatorGuide(it)
tryCatchInRelease { showSimulatorGuide(it) }
},500)
})
}

View File

@ -125,7 +125,9 @@ class SubjectListFragment : LazyListFragment<GameEntity, SubjectListViewModel>()
// 与外部Appbar交互
override fun onTitleClick() {
if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0 || provideListAdapter().itemCount == 0) {
if (mLayoutManager == null
|| mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0
|| provideListAdapter().itemCount == 0) {
// do nothing
} else {
mLayoutManager.scrollToPosition(0)

View File

@ -16,7 +16,6 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.OrientationHelper
import androidx.recyclerview.widget.RecyclerView
import com.gh.base.fragment.BaseLazyFragment
import com.gh.common.constant.Constants
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.*
import com.gh.common.videolog.VideoRecordUtils
@ -558,10 +557,14 @@ class VideoDetailContainerFragment : BaseLazyFragment(), OnBackPressedListener {
}
fun findVisibleVideoViewByPosition(): DetailPlayerView? {
val pos = findVisibleItemPosition()
val holder = mBinding.recyclerview?.findViewHolderForAdapterPosition(pos)
return holder?.itemView as? DetailPlayerView
// 页面被销毁重建时,旧 fragment 可能会收到 onActivityResult 的 callback ,这时 mBinding 为未初始化状态
return if (::mBinding.isInitialized) {
val pos = findVisibleItemPosition()
val holder = mBinding.recyclerview?.findViewHolderForAdapterPosition(pos)
holder?.itemView as? DetailPlayerView
} else {
null
}
}
private fun findVisibleItemPosition(): Int {

View File

@ -27,6 +27,7 @@ import com.gh.common.util.DeviceUtils;
import com.gh.common.util.DownloadNotificationHelper;
import com.gh.common.util.DownloadObserver;
import com.gh.common.util.HomeBottomBarHelper;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.SPUtils;
@ -104,7 +105,12 @@ public class HaloApp extends MultiDexApplication {
}
public String getChannel() {
return mChannel;
// 存在 IO 初始化线程阻塞(万物皆可阻塞)导致 mChannel 为空的情况,这里特殊处理下
if (TextUtils.isEmpty(mChannel)) {
return "";
} else {
return mChannel;
}
}
public void setOAID(String oaid) {
@ -141,8 +147,14 @@ public class HaloApp extends MultiDexApplication {
initDataHelper();
Tracker.init(this);
//初始化Fresco(BigImageViewer 已包含Fresco)
BigImageViewer.initialize(FrescoImageLoader.with(this));
// 初始化 Fresco(BigImageViewer 已包含Fresco)
if (!ImageUtils.isFrescoInitialized()) {
try {
BigImageViewer.initialize(FrescoImageLoader.with(this));
} catch (Throwable e) {
e.printStackTrace();
}
}
deviceRamSize = DeviceUtils.getTotalRamSizeOfDevice(this);

View File

@ -71,7 +71,7 @@
</RelativeLayout>
<androidx.viewpager.widget.ViewPager
<com.gh.common.view.Gh_ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

View File

@ -1,191 +1,2 @@
GH_TEST
GH_TEST2
GH_REFRESH
GH_100
GH_101
GH_102
GH_103
GH_104
GH_106
GH_107
GH_108
GH_109
GH_110
GH_111
GH_113
GH_114
GH_115
GH_116
GH_117
GH_118
GH_119
GH_120
GH_121
GH_123
GH_127
GH_200
GH_201
GH_202
GH_203
GH_204
GH_205
GH_206
GH_222
GH_307
GH_333
GH_600
GH_601
GH_602
GH_603
GH_604
GH_605
GH_606
GH_607
GH_608
GH_609
GH_610
GH_611
GH_612
GH_613
GH_614
GH_615
GH_616
GH_617
GH_618
GH_619
GH_620
GH_621
GH_622
GH_623
GH_624
GH_625
GH_626
GH_627
GH_628
GH_629
GH_630
GH_631
GH_632
GH_633
GH_634
GH_635
GH_636
GH_637
GH_638
GH_639
GH_640
GH_641
GH_642
GH_643
GH_644
GH_645
GH_646
GH_647
GH_648
GH_649
GH_650
GH_651
GH_652
GH_653
GH_654
GH_655
GH_656
GH_657
GH_658
GH_659
GH_660
GH_661
GH_662
GH_663
GH_664
GH_665
GH_666
GH_667
GH_667
GH_668
GH_669
GH_670
GH_671
GH_672
GH_673
GH_674
GH_675
GH_676
GH_677
GH_678
GH_679
GH_680
GH_681
GH_682
GH_683
GH_684
GH_685
GH_686
GH_687
GH_688
GH_689
GH_690
GH_691
GH_692
GH_693
GH_694
GH_695
GH_696
GH_697
GH_698
GH_699
GH_700
GH_701
GH_702
GH_703
GH_704
GH_705
GH_706
GH_707
GH_708
GH_709
GH_710
GH_711
GH_712
GH_713
GH_714
GH_715
GH_716
GH_717
GH_718
GH_719
GH_720
GH_721
GH_722
GH_723
GH_724
GH_725
GH_726
GH_727
GH_728
GH_729
GH_730
GH_731
GH_732
GH_733
GH_734
GH_735
GH_736
GH_737
GH_738
GH_739
GH_740
GH_741
GH_742
GH_743
GH_744
GH_745
GH_746
GH_747
GH_748
GH_749
GH_750
GH_777
GH_787
GH_888
GH_999
GH_TEST2

View File

@ -7,8 +7,8 @@ ext {
targetSdkVersion = 26
// application info (每个大版本之间的 versionCode 增加 20)
versionCode = 331
versionName = "4.9.1"
versionCode = 337
versionName = "4.9.6"
applicationId = "com.gh.gamecenter"
// AndroidX