想要 Activity 在启动时就不显示(不会出现闪一下或黑屏的情形),只要在 AndroidManifest.xml 中设置 Activity 的 theme 即可:
<activity
android:theme="@android:style/Theme.NoDisplay"
……
activity/>
但在某些情况下,我们需要按照流程的判断来动态设定 Activity 的 theme。
Activity 类提供了 public void setTheme(int resid) 方法,但实测下来,把 setTheme 放在 onCreate 方法的 super.onCreate 之前屏幕会变黑;放在 super.onCreate 之后则屏幕还是会闪一下;
查了一些资料后,最终的做法是重载 Activity 的 setTheme 方法,如下所示:
@Override
public void setTheme(int resid)
{
if (xxx) //满足条件,设置指定的theme
{
super.setTheme(R.style.mytheme);
return;
}
super.setTheme(resid);
}
上述做法要结合
<activity
android:theme="@android:style/Theme.NoDisplay"
……
activity/>
一起使用才行!
引申出一个小试验:
如果我把 AndroidManifest 中的 theme 设置成自己定义的样式,在重载的 setTheme 方法中设置 R.style.Theme.NoDisplay 的话还会是相同效果吗?
<activity
android:theme="@style/mytheme"
……
activity/>
@Override
public void setTheme(int resid)
{
if (yyy) //满足条件,设置Theme.NoDisplay
{
super.setTheme(android.R.style.Theme_NoDisplay);
return;
}
super.setTheme(resid);
}
结果发现,这样的情况下启动 Activity,屏幕还是会闪一下。
很奇怪,查了一下 setTheme 的源码:
@Override
public void setTheme(int resid)
{
if (mThemeResource != resid)
{
mThemeResource = resid;
initializeTheme();
}
}
做一下简单的猜测:在 AndroidManifest 中设置的 theme 在 Activity 启动时会进行预加载,然后在 setTheme 方法中判断传入的 theme 的 id 是否与已加载的 theme 的 id 相同,如果不同,则重新进行加载,而重新加载是需要时间的,所以就出现了屏幕闪一下的情况。