解决方案2:分析BUG现象,根据现象解决问题
目标是什么:App启动不重启
不重启意味着什么:点击Home键时的Activity回归任务栈顶部
任务栈:GET_TASKS权限于Android L废弃,REAL_GET_TASKS权限仅限系统应用有效!!!
因此,无法在App日志中查看任务栈信息。
任务栈查看方法:Android Studio 中 Terminal 输入 adb shell dumpsys activity activities
由于我在SplashActivity中写了finish方法,可以分别看到:
#0直接启动:
Running activities (most recent first):
TaskRecord{ea096c0 #1597 A=[packageName] U=0 StackId=1604 sz=1}
Run #0: ActivityRecord{e30acd0 u0 [packageName]/[packageName].activity.MainActivity t1597}
mResumedActivity: ActivityRecord{e30acd0 u0 [packageName]/[packageName].activity.MainActivity t1597}
mLastPausedActivity: ActivityRecord{f68c709 u0 [packageName]/[packageName].activity.SplashActivity t-1f}
#1点击Home键后,再次打开,在Splash页面时的任务栈:
Running activities (most recent first):
TaskRecord{ea096c0 #1597 A=[packageName] U=0 StackId=1604 sz=2}
Run #1: ActivityRecord{433989 u0 [packageName]/[packageName].activity.SplashActivity t1597}
Run #0: ActivityRecord{e30acd0 u0 [packageName]/[packageName].activity.MainActivity t1597}
两者对比,可以看到任务栈中Splash两次的id是不同的,而main是一致的。App并非重启,只是多启动了一次Splash。
可见:我们只需要消除往后打开时的Splash页面即可。
如何做?根据上述分析,有如下判断
在SplashActivity中
if(SplashActivity在 任务栈最底部 ){
//App为正常启动
}else{
//App为已经启动并且点击Home键后再次打开
关闭被错误打开的SplashActivity
}
判断是否为 任务栈最底部的 源码:
/**
* Return whether this activity is the root of a task. The root is the
* first activity in a task.
*
* @return True if this is the root activity, else false.
*/
@Override
public boolean isTaskRoot() {
try {
return ActivityManager.getService().getTaskForActivity(mToken, true) >= 0;
} catch (RemoteException e) {
return false;
}
}
判断方法:
public class SplashActivity extends BaseActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!this.isTaskRoot()) {//判断是否为根Activity
Intent mainIntent = getIntent();
String action = mainIntent.getAction();
//判断是否为启动页 如果App不会因为其他原因调用该页面,可以不写if语句
if (mainIntent.hasCategory(Intent.CATEGORY_LAUNCHER)
&& Intent.ACTION_MAIN.equals(action)) {
finish();
return;
}
}
}
}
这个代码应该紧随着super.onCreate(savedInstanceState);之后。
onCreate确保当前Activity是正在创建状态,而在setContentView之前,确保Activity是未渲染的,此时关闭不会让用户察觉