作者:燕歆波
导读:我从来没碰到过这个问题,直到朋友碰到了告诉我,他说如果使用非activity的引用来启动activity,那么,系统会报出异常,我们当时在手机上也试了几次,可是竟然没出错?当时,我们并没有去百度这个问题。。。
问题
在启动页面时,我们经常使用当前页面的引用去开启新的页面,可是如果不使用页面的引用,会怎么样呢,我们使用application的引用试一下就知道了:
ECardApplication context = ECardApplication.getInstance();
Intent intent = new Intent(this, MySettingActivity.class);
context.startActivity(intent);
运行后,点击按钮执行上面的代码,直接就报错了:
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
错误中还给出了解决方法:
使用非activity引用启动页面,需要添加FLAG_ACTIVITY_NEW_TASK flag
既然这样,我们就按照他说的给intent添加一个flag,然后再试一次。
结果成功了!
突然想到,在使用自己的手机测试的时候,并没有出错,可是这里为什么出错了呢,于是我去掉flag,在自己手机上又测试了一次,还是没有出错,我和朋友当时很郁闷,为什么没有错误了呢,当时猜想是手机7.0的问题。
周一上班,朋友突然对我说,他发现了原因,的确是7.0的问题,原因呢,让我看一下ContextImpl类,这个类并不是公开的,于是我在sdk下找到了这个类:
@Override
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();
// Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
// generally not allowed, except if the caller specifies the task id the activity should
// be launched in.
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
&& options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}
看了7.0的,再看6.0的,我们就会发现问题:
@Override
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}
发现什么不同 的地方吗,在6.0
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0)
和7.0的
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
&& options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)
明显多了一些条件,
总结:6.0在启动页面之前会检查有没有Intent.FLAG_ACTIVITY_NEW_TASK,没有设置的话就报上面所说的那个异常,而7.0除此之外需要options不为null,还有启动的任务id不为-1,才会成立报出异常,