fix: 简单优化启动耗时问题

This commit is contained in:
chenjuntao
2024-08-05 11:43:00 +08:00
parent 9b57d10e2d
commit eb08575f3e
21 changed files with 136 additions and 90 deletions

View File

@ -20,11 +20,11 @@ class SplashAdVideoView @JvmOverloads constructor(
fun startPlay(cover: String, url: String) {
Debuger.enable()
GSYVideoType.setShowType(SCREEN_TYPE_FULL)
GSYVideoType.setRenderType(GSYVideoType.SUFRACE)
CustomManager.getCustomManager(getKey()).isNeedMute = true
setUp(url, false, "")
setUp(url, true, "")
val ivCover = findViewById<SimpleDraweeView>(R.id.thumbImage)
ImageUtils.display(ivCover, cover)
@ -51,6 +51,7 @@ class SplashAdVideoView @JvmOverloads constructor(
fun clearAll() {
GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_DEFAULT)
GSYVideoType.setRenderType(GSYVideoType.TEXTURE)
release()
CustomManager.removeManager(getKey())
}

View File

@ -20,6 +20,7 @@ import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.EnvHelper;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
@ -47,7 +48,6 @@ import java.util.Locale;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.BehaviorSubject;
@ -225,7 +225,6 @@ public class Config {
RetrofitManager.getInstance()
.getVApi().getSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<VSetting>() {
@Override
public void onSuccess(VSetting data) {
@ -258,7 +257,6 @@ public class Config {
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<AppEntity>() {
@Override
public void onSuccess(AppEntity data) {
@ -290,7 +288,6 @@ public class Config {
RetrofitManager.getInstance()
.getApi().getSettings(PackageUtils.getGhVersionName(), channel)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<SettingsEntity>() {
@Override
public void onResponse(SettingsEntity response) {
@ -303,7 +300,7 @@ public class Config {
edit.apply();
if (!SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
EventBus.getDefault().post(new EBReuse("Refresh"));
AppExecutor.getUiExecutor().execute(() -> EventBus.getDefault().post(new EBReuse("Refresh")));
}
}
});
@ -311,7 +308,6 @@ public class Config {
RetrofitManager.getInstance()
.getApi().getNewSettings(Build.MANUFACTURER, Build.MODEL, channel, Build.VERSION.SDK_INT, BuildConfig.VERSION_NAME)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<NewSettingsEntity>() {
@Override
public void onSuccess(NewSettingsEntity data) {
@ -326,7 +322,6 @@ public class Config {
RetrofitManager.getInstance()
.getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<GameGuidePopupEntity>() {
@Override
public void onSuccess(GameGuidePopupEntity data) {
@ -338,7 +333,6 @@ public class Config {
if (manufacturer.equals("OPPO") || manufacturer.equals("VIVO")) {
RetrofitManager.getInstance().getNewApi().getBrowserHintUrl(manufacturer)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<ResponseBody>() {
@Override
public void onSuccess(ResponseBody data) {
@ -369,7 +363,6 @@ public class Config {
RetrofitManager.getInstance()
.getNewApi().getNewSettings(PackageUtils.getGhVersionName(), channel, filterString)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<NewApiSettingsEntity>() {
@Override
public void onSuccess(NewApiSettingsEntity data) {
@ -378,7 +371,7 @@ public class Config {
mNewSimulatorEntity = data.getSimulator();
if (HaloApp.getInstance().isNewForThisVersion && mNightModeSetting != null && mNightModeSetting.getInstall()) {
DarkModeUtils.INSTANCE.updateFollowSystemDarkModeToSp(true);
DarkModeUtils.INSTANCE.initDarkMode();
AppExecutor.getUiExecutor().execute(DarkModeUtils.INSTANCE::initDarkMode);
}
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
@ -396,7 +389,7 @@ public class Config {
// 更新包名监听是否开启
if (mNewApiSettingsEntity.isPackageObserveEnable()) {
observePackageChange(mNewApiSettingsEntity.getPackageObserveActions());
AppExecutor.getUiExecutor().execute(() -> observePackageChange(mNewApiSettingsEntity.getPackageObserveActions()));
}
}
});

View File

@ -89,4 +89,8 @@ class AppProviderImpl : IAppProvider {
}
override fun getPluginVersion(): String = VCore.getInstance().getPluginVersion()
override fun initImageLoaderIfNeeded() {
HaloApp.getInstance().initFresco()
}
}

View File

@ -3,12 +3,12 @@ package com.gh.common.util
import android.annotation.SuppressLint
import com.gh.gamecenter.common.entity.SignatureEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.schedulers.Schedulers
/**
* 存储光环网游使用的签名
@ -24,7 +24,7 @@ object SignatureRepository {
RetrofitManager.getInstance()
.newApi
.ghSignature
.compose(singleToMain())
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<ArrayList<SignatureEntity>>() {
override fun onSuccess(data: ArrayList<SignatureEntity>) {
signDigestList = ArrayList()

View File

@ -19,7 +19,7 @@ data class BottomTab(
@DrawableRes
val iconSelector: Int = 0, // 本地字段
@SerializedName("js_code")
val jsCode: String = "", // js代码
var jsCode: String = "", // js代码
val link: LinkEntity? = null, // 通用链接
@SerializedName("search_style")
val searchStyle: SearchStyle = SearchStyle(), // 搜索样式

View File

@ -39,6 +39,6 @@ class StartupAdEntity(
class TimeEntity(val start: Long = 0, val end: Long = 0)
companion object {
private const val AD_TYPE_IMG = "displayInterval"
private const val AD_TYPE_IMG = "img"
}
}

View File

@ -209,7 +209,6 @@ object PackageRepository {
@SuppressLint("CheckResult")
private fun loadInstalledGameDigestAndNotifyData(
filteredList: ArrayList<String>,
onWorkerThreadOnly: Boolean = false,
isVGame: Boolean = false,
updateInstallStatus: Boolean = false
) {
@ -226,12 +225,6 @@ object PackageRepository {
var observable = mNewApi.getPackageGames(PackageFilterManager.packageKey, page, PAGE_SIZE)
.subscribeOn(Schedulers.io())
if (!onWorkerThreadOnly) {
// 这里面的代码(根据包名获取签名?)或许是造成安装完成后的 ANR 和 startForegroundService did not then call startForeground 的原因
// 为了避免影响其它地方,这里只处理安装完成后的调用
observable = observable.observeOn(AndroidSchedulers.mainThread())
}
observable.subscribe(object : BiResponse<List<PackageGame>>() {
override fun onSuccess(data: List<PackageGame>) {
if (!data.isNullOrEmpty()) {
@ -446,7 +439,6 @@ object PackageRepository {
updateFilterPackage(list) {
loadInstalledGameDigestAndNotifyData(
filteredList = list,
onWorkerThreadOnly = true,
updateInstallStatus = false
)
}
@ -476,7 +468,6 @@ object PackageRepository {
updateFilterPackage(pkgNameList) {
loadInstalledGameDigestAndNotifyData(
filteredList = pkgNameList,
onWorkerThreadOnly = true,
isVGame = isVGame,
updateInstallStatus = updateInstallStatus
)

View File

@ -2,6 +2,7 @@ package com.gh.gamecenter.wrapper
import android.net.Uri
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.widget.Checkable
@ -13,7 +14,6 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.databinding.PieceBottomTabBinding
import com.gh.gamecenter.entity.BottomTab
@ -60,7 +60,7 @@ abstract class BaseBottomTabFragment<T: ViewBinding>: ToolbarFragment() {
PieceBottomTabBinding.bind(LayoutInflater.from(requireContext()).inflate(R.layout.piece_bottom_tab, null))
.apply {
tabTv.text = bottomTab.name
if (GsonUtils.isJSONValid(bottomTab.jsCode)) {
if (!TextUtils.isEmpty(bottomTab.jsCode)) {
tabLottie.setAnimationFromJson(bottomTab.jsCode, bottomTab.id + bottomTab.name)
}
if (bottomTab.iconSelector != 0) {

View File

@ -7,12 +7,14 @@ import com.gh.common.util.ViewPagerFragmentHelper
import com.gh.gamecenter.common.entity.LaunchRedirect
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SingletonHolder
import com.gh.gamecenter.entity.BottomTab
import com.gh.gamecenter.entity.DataUnionEntity
import com.gh.gamecenter.entity.MultiTabNav
import com.gh.gamecenter.home.custom.model.CustomPageData
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.MutableSharedFlow
@ -134,7 +136,7 @@ class MainWrapperRepository {
fun getDataUnion() {
processBottomTabData(emptyList())
mNewApi.dataUnion
.compose(singleToMain())
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<DataUnionEntity>() {
override fun onSuccess(data: DataUnionEntity) {
processBottomTabData(data.bottomTab)
@ -186,17 +188,23 @@ class MainWrapperRepository {
if (bottomTab.default) {
defaultBottomTabIndex = index
}
// 如果 jsCode 不是合法的 json则将 jsCode 置空
if (!GsonUtils.isJSONValid(bottomTab.jsCode)) {
bottomTab.jsCode = ""
}
if (bottomTab.link?.type == ViewPagerFragmentHelper.TYPE_VIDEO_STREAM) {
bottomTab.isTransparentStyle = true
}
}
bottomTabListLiveData.value = bottomTabList
bottomTabListLiveData.postValue(bottomTabList)
defaultNavId = bottomTabList.find { it.link?.type == ViewPagerFragmentHelper.TYPE_MULTI_TAB_NAV && it.default }?.link?.link ?: ""
defaultCustomPageId = bottomTabList.find { it.link?.type == ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE && it.default }?.link?.link ?: ""
} else {
HomeBottomBarHelper.getDefaultHomeBottomTabData().run {
bottomTabListLiveData.value = this
bottomTabListLiveData.postValue(this)
defaultNavId = find { it.link?.type == ViewPagerFragmentHelper.TYPE_MULTI_TAB_NAV && it.default }?.link?.link ?: ""
defaultCustomPageId = find { it.link?.type == ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE && it.default }?.link?.link ?: ""
}
@ -221,7 +229,7 @@ class MainWrapperRepository {
defaultCustomPageId =
multiTabNav?.linkMultiTabNav?.find { it.link?.type == ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE && it.default }?.link?.link ?: ""
multiTabNavLiveData.value = multiTabNav
multiTabNavLiveData.postValue(multiTabNav)
}
companion object : SingletonHolder<MainWrapperRepository>({ MainWrapperRepository() })

View File

@ -63,7 +63,6 @@ import com.gh.gamecenter.core.iinterface.IApplication;
import com.gh.gamecenter.core.provider.IFlavorProvider;
import com.gh.gamecenter.core.provider.IPushProvider;
import com.gh.gamecenter.core.provider.IQGameProvider;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.login.user.UserManager;
@ -92,7 +91,6 @@ import java.util.List;
import java.util.ServiceLoader;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.plugins.RxJavaPlugins;
import io.reactivex.schedulers.Schedulers;
import tv.danmaku.ijk.media.exo2.Exo2PlayerManager;
@ -212,13 +210,6 @@ public class HaloApp extends MultiDexApplication {
super.onCreate();
initArouter();
mInstance = this;
for (IApplication application : mApplicationList) {
application.onCreate(mInstance);
}
fixDebugIssueInAndroid14();
// 每个进程都用自己的进程名作为后缀的文件夹来存 WebView cache
// https://sentry.shanqu.cc/organizations/lightgame/issues/285063/?project=22&query=is%3Aunresolved
// https://stackoverflow.com/a/61748345/4812571 这个无效
@ -232,6 +223,13 @@ public class HaloApp extends MultiDexApplication {
}
}
mInstance = this;
for (IApplication application : mApplicationList) {
application.onCreate(mInstance);
}
fixDebugIssueInAndroid14();
ExtensionsKt.doOnMainProcessOnly(() -> {
// 似乎只是 load SO 不涉及方法调用,所以可以在隐私政策前调用吧?
OAIDHelper.INSTANCE.doSystemLoad();
@ -239,14 +237,16 @@ public class HaloApp extends MultiDexApplication {
PlayerFactory.setPlayManager(Exo2PlayerManager.class);
CacheFactory.setCacheManager(ExoPlayerCacheManager.class);
initFresco();
isNewForThisVersion =
PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Constants.SP_NEW_FIRST_LAUNCH_VERSION + PackageUtils.getGhVersionName(), true);
Tracker.init(this);
AppExecutor.getIoExecutor().execute(() -> {
// fresco 初始化约耗费 300ms所以放到工作线程初始化更合理一些
initFresco();
initDataHelper();
Tracker.init(this);
DownloadCore.init(this);
deviceRamSize = DeviceUtils.getTotalRamSizeOfDevice(this);
@ -311,10 +311,10 @@ public class HaloApp extends MultiDexApplication {
}
private void postInit(long delay) {
// 初始化 一键登录
QuickLoginHelper.init(this);
// 初始化 sentry
DataUtils.init(this, getChannel());
// 初始化 一键登录
QuickLoginHelper.init(this);
// 初始化广告 SDK
AdDelegateHelper.INSTANCE.initAdSdk(this);
@ -388,8 +388,6 @@ public class HaloApp extends MultiDexApplication {
AppExecutor.getUiExecutor().executeWithDelay(() -> {
FixedRateJobHelper.begin();
RegionSettingHelper.getRegionSetting();
if (PackageHelper.INSTANCE.isGetInstalledPackagesAgreed()) {
PackageHelper.INSTANCE.initPackageRelatedData();
}
@ -400,17 +398,12 @@ public class HaloApp extends MultiDexApplication {
initTimeConsumingAction();
getWebviewAbiList();
// 注册回调以用于做各种统计
ProcessLifecycleOwner.get().getLifecycle().addObserver(new ProcessorLifeCycleOwner());
// 初始化畅玩相关数据
retrieveVGameInfoIfNeeded();
// 移除已安装但还在本地数据库中的包(避免因为没有监听到安装结果导致安装包没有删除的问题)
removeInstalledButRemainedPackages();
// 开发环境不要强制捕获相关异常,这些异常通常是需要处理的
if (!BuildConfig.DEBUG) {
RxJavaPlugins.setErrorHandler(throwable -> {
@ -444,14 +437,12 @@ public class HaloApp extends MultiDexApplication {
e.printStackTrace();
}
}
AppExecutor.getIoExecutor().execute(() -> {
final String webviewPath = PackageUtils.getWebviewPath(this);
if (webviewPath == null) return;
final List<String> abiList = PackageUtils.getApkAbiList(webviewPath);
webViewAbiList = abiList;
SPUtils.setString(Constants.SP_WEBVIEW_ABI_LIST, GsonUtils.toJson(abiList));
SPUtils.setInt(Constants.SP_WEBVIEW_VERSION_CODE, webviewVersionCode);
});
final String webviewPath = PackageUtils.getWebviewPath(this);
if (webviewPath == null) return;
final List<String> abiList = PackageUtils.getApkAbiList(webviewPath);
webViewAbiList = abiList;
SPUtils.setString(Constants.SP_WEBVIEW_ABI_LIST, GsonUtils.toJson(abiList));
SPUtils.setInt(Constants.SP_WEBVIEW_VERSION_CODE, webviewVersionCode);
}
private void initDataHelper() {
@ -532,7 +523,6 @@ public class HaloApp extends MultiDexApplication {
return single;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
s -> Utils.log("IPushProvider->init push succeed, response: " + s + ",channel: " + getChannel()),
e -> Utils.log("IPushProvider->init push failed, error: " + e + ", channel: " + getChannel())
@ -553,23 +543,29 @@ public class HaloApp extends MultiDexApplication {
private void initTimeConsumingAction() {
AppExecutor.getIoExecutor().execute(() -> {
// 初始化地区设置
RegionSettingHelper.getRegionSetting();
// 初始化全局下载监听
DownloadObserver.initObserver();
if ("miui".equals(Build.MANUFACTURER) && Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
DisplayUtils.sShouldUseLegacyMiuiStatusBarMethod = true;
}
// 移除已安装但还在本地数据库中的包(避免因为没有监听到安装结果导致安装包没有删除的问题)
removeInstalledButRemainedPackages();
// 避免在华为设备上出现 `Register too many Broadcast Receivers` 异常,可见 https://github.com/llew2011/HuaWeiVerifier
LoadedApkHuaWei.hookHuaWeiVerifier(this);
DownloadMessageHandler.INSTANCE.init(SimpleDownloadDatabase.getInstance().downloadDao());
VHelper.INSTANCE.preparePluginUpdate();
// 初始化 WebView ABI 列表
getWebviewAbiList();
});
}
public void initFresco() {
if (ImageUtils.isFrescoInitialized()) return;
// 系统版本低于 6.0 以及设备内存小于 2500M 的设备禁用动图
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|| (deviceRamSize != 0 && deviceRamSize < 2500)) {
@ -618,26 +614,24 @@ public class HaloApp extends MultiDexApplication {
* 移除已安装但还在本地数据库中的包
*/
private void removeInstalledButRemainedPackages() {
AppExecutor.getIoExecutor().execute(() -> {
for (DownloadEntity downloadEntity : DownloadManager.getInstance().getAllDownloadEntity()) {
if (downloadEntity.getStatus() != DownloadStatus.done) {
continue;
}
try {
String versionName = downloadEntity.getVersionName();
String packageName = downloadEntity.getPackageName();
// 这里暴力删除会影响畅玩游戏快速安装功能,但先不管了
if (versionName != null
&& packageName != null
&& versionName.equals(PackageUtils.getVersionNameByPackageName(packageName))) {
DownloadManager.getInstance().cancel(downloadEntity.getUrl());
}
} catch (Exception ignored) {
// 不在乎删除的结果,尝试即可
}
for (DownloadEntity downloadEntity : DownloadManager.getInstance().getAllDownloadEntity()) {
if (downloadEntity.getStatus() != DownloadStatus.done) {
continue;
}
});
try {
String versionName = downloadEntity.getVersionName();
String packageName = downloadEntity.getPackageName();
// 这里暴力删除会影响畅玩游戏快速安装功能,但先不管了
if (versionName != null
&& packageName != null
&& versionName.equals(PackageUtils.getVersionNameByPackageName(packageName))) {
DownloadManager.getInstance().cancel(downloadEntity.getUrl());
}
} catch (Exception ignored) {
// 不在乎删除的结果,尝试即可
}
}
}
public boolean isReinstallTheSameVersion() {