You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次打开App时自定义Splash Screen重复加载问题求助

问题:首次安装打开App时自定义启动页加载两次,仅首次进入引导页时出现

问题背景

我通过在themes.xml中添加以下代码禁用了默认Splash Screen:

<item name="android:windowIsTranslucent">true</item>

实现自定义Splash Screen后遇到异常:首次安装打开App时启动页加载两次,后续打开正常,且仅首次进入引导页(onBoarding)时出现该问题。

相关代码

SplashScreenActivity核心代码

Thread thread = new Thread(){
    public void run(){
        try{
            sleep(4000);
            onBoardingScreen = getSharedPreferences("onBoardingScreen", MODE_PRIVATE);
            boolean isFirstTime = onBoardingScreen.getBoolean("firstTime", true);
            if(isFirstTime)
            {
                SharedPreferences.Editor editor = onBoardingScreen.edit();
                editor.putBoolean("firstTime",false);
                editor.apply();
                Intent intent = new Intent(SplashScreen.this, onBoarding.class);
                startActivity(intent);
                finish();
            }
            else
            {
                Intent intent = new Intent(SplashScreen.this, MainActivity.class);
                startActivity(intent);
                finish();
            }
        }catch(Exception e){

        }

    }
}; thread.start();

OnBoardingActivity核心代码

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_on_boarding);
    //Hooks
    viewPager = findViewById(R.id.slider);
    dotsLayout = findViewById(R.id.dots);
    letsGetStarted = findViewById(R.id.get_started_btn);
    next_btn = findViewById(R.id.next_btn);
    if (getActionBar() != null) {
        getActionBar().hide();
    }
    letsGetStarted.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(onBoarding.this, MainActivity.class);
            startActivity(intent);
        }
    });
    //Call adapter
    sliderAdapter = new sliderAdapter(this);
    viewPager.setAdapter(sliderAdapter);
    //Dots
    addDots(0);
    viewPager.addOnPageChangeListener(changeListener);
}

原因分析

  1. 透明主题引发的启动时序冲突:设置android:windowIsTranslucent="true"后,系统会先创建透明过渡窗口,再加载你的SplashScreenActivity。首次安装时App初始化(含SharedPreferences首次创建)耗时更长,导致透明窗口+自定义启动页的视觉叠加,看起来像是启动页加载两次。
  2. SharedPreferences异步提交的延迟:editor.apply()是异步写入,首次启动时可能在SplashScreenActivity未完全finish时,OnBoarding已经启动,引发启动流程混乱。
  3. 硬编码线程休眠的不合理性:固定4秒延迟忽略设备性能差异,线程阻塞可能打乱Activity启动时序。

解决办法

1. 替换禁用默认启动页的主题配置

放弃android:windowIsTranslucent,为SplashScreenActivity配置专属启动主题,实现系统启动窗口与自定义页面无缝衔接:

<!-- themes.xml中添加专属主题 -->
<style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">@drawable/your_splash_background</item>
    <item name="android:windowFullscreen">true</item>
</style>

将@drawable/your_splash_background替换为你自定义启动页的背景图(需与SplashScreenActivity布局背景一致),然后在AndroidManifest.xml中为SplashScreenActivity指定该主题:

<activity
    android:name=".SplashScreenActivity"
    android:theme="@style/SplashTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

其他Activity使用正常主题即可。

2. 优化SplashScreenActivity逻辑

移除Thread.sleep,改用Handler.postDelayed实现延迟,同时将apply()改为同步提交的commit()(首次启动数据量小,不会阻塞主线程):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    new Handler(Looper.getMainLooper()).postDelayed(() -> {
        SharedPreferences onBoardingScreen = getSharedPreferences("onBoardingScreen", MODE_PRIVATE);
        boolean isFirstTime = onBoardingScreen.getBoolean("firstTime", true);
        
        Intent intent;
        if(isFirstTime) {
            SharedPreferences.Editor editor = onBoardingScreen.edit();
            editor.putBoolean("firstTime", false);
            editor.commit(); // 同步提交确保数据写入完成
            intent = new Intent(SplashScreenActivity.this, onBoarding.class);
        } else {
            intent = new Intent(SplashScreenActivity.this, MainActivity.class);
        }
        
        startActivity(intent);
        finish();
    }, 2000); // 推荐设置2秒以内的延迟,适配不同设备
}

3. 优化OnBoardingActivity启动配置

在AndroidManifest.xml中为OnBoardingActivity设置合理的启动模式,避免重复启动:

<activity
    android:name=".onBoarding"
    android:launchMode="singleTop"
    android:theme="@style/YourNormalTheme" />

4. 验证方案

卸载App后重新安装,首次打开确认启动页仅显示一次;进入引导页后退出App,再次打开确认正常进入主页面。

内容的提问来源于stack exchange,提问作者Okashi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 07:17:06