现象描述
app 在应用市场下载完成后,点击打开,按照 app 的一般流程首先会启动 Splash 界面,再进入首页。此时你按下 home 键,再从桌面点击应用图标,你会发现应用又走到了 Splash 界面再进入首页。再次按 home 键重复刚才的动作现象依旧,通过将应用结束或杀掉进程应用就会恢复正常。当然这种现象理论上来说在你安装完应用后只会出现一次,但终归还是会影响用户体验。(如果用户进入了比较深层次的页面,这个体验对用户来说绝对是个灾难)
大家可以去随便下一款 app 试一下,大概率会有这种现象,比如下面的 app。
大厂 app 就不要试了,别人早就处理好了这个问题。所以先看一下网易和 b站是怎么解决这个问题的。
解决方案
我们先来看网易的解决办法:
paramJoinPoint = paramAdActivity.getIntent();
int k = 0;
int i;
if ((paramJoinPoint != null) && (paramAdActivity.getIntent().getBooleanExtra("out", false))) {
i = 1;
} else {
i = 0;
}
long l = System.currentTimeMillis();
paramAdActivity.setTheme(2131689487);
int j = k;
if (!paramAdActivity.isTaskRoot()) // 关键代码1
{
j = k;
if (paramAdActivity.getIntent() != null)
{
j = k;
if ((paramAdActivity.getIntent().getFlags() & 0x400000) != 0) { // 关键代码 2
j = 1;
}
}
}
if (j == 0) {
fp.a(paramAdActivity.getIntent(), AdFragment.class.getName(), "AdFragment", null);
}
paramAdActivity.onCreate(paramBundle);
if (j != 0)
{
paramAdActivity.finish();
return;
}
核心逻辑如下
if(!isTaskRoot) {
if((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
finish();
return;
}
}
/**
* This flag is not normally set by application code, but set for you by
* the system as described in the
* {@link android.R.styleable#AndroidManifestActivity_launchMode
* launchMode} documentation for the singleTask mode.
*/
public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 0x00400000;
接着是 B 站的:
Object localObject;
if ((m.a.a((Context)this)) && (!isTaskRoot()))
{
localObject = getIntent();
Intrinsics.checkExpressionValueIsNotNull(localObject, "intent");
localObject = ((Intent)localObject).getAction();
if ((getIntent().hasCategory("android.intent.category.LAUNCHER")) && (TextUtils.equals((CharSequence)localObject, (CharSequence)"android.intent.action.MAIN")))
{
m.a.b((Context)this);
b(); // 调用 finish()
return;
}
}
核心逻辑如下:
if(!isTaskRoot()) {
if ((getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)) && (TextUtils.equals(getIntent().getAction(), Intent.ACTION_MAIN)) {
finish();
return
}
}
总结
两种方案的逻辑判断都很简单,且前置条件都是先判断 isTaskRoot,差异在于后续的判断处理,就我个人而言觉得 b 站的方案更易于理解。