返回

标准模式下在Application启动Activity报错分析

Android

在Android中,Activity是应用的基本组件,它代表了一个屏幕上的界面。Activity可以被启动、停止、暂停和恢复。当一个Activity被启动时,它会运行在一个任务栈中。任务栈是一个Activity的集合,它是一个后进先出的栈结构。

如果在Application中以标准模式启动Activity,则会报出以下错误:

Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires specifying and explicit new task flag. For example, use startActivity(intent, FLAG_ACTIVITY_NEW_TASK)

这个错误提示说,在Activity上下文之外调用startActivity()需要指定一个显式的new task标志。例如,可以使用startActivity(intent, FLAG_ACTIVITY_NEW_TASK)。

这是因为在Android 7.0及以上版本中,为了提高安全性和稳定性,系统引入了新的启动模式限制。在这些版本中,如果不在Activity上下文中启动Activity,则必须使用FLAG_ACTIVITY_NEW_TASK标志。

FLAG_ACTIVITY_NEW_TASK标志的作用是创建一个新的任务栈,并将要启动的Activity放在这个新任务栈的栈顶。这样,该Activity就与其他任务栈中的Activity隔离了。

解决此错误的方法是在Application中以FLAG_ACTIVITY_NEW_TASK标志启动Activity。例如:

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

如果使用的是Android 7.0及以下版本,则不需要添加FLAG_ACTIVITY_NEW_TASK标志。

值得注意的是,在Android 8.0中,系统对启动模式限制进行了进一步的修改。在Android 8.0中,如果在Application中以标准模式启动Activity,则会报出以下错误:

Caused by: android.app.RemoteServiceException: Bad notification posted from package android

这是因为在Android 8.0中,系统不允许在Application中以标准模式启动Activity。

解决此错误的方法是在Android 8.0中使用隐式Intent来启动Activity。例如:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);

隐式Intent可以启动任何能够处理该Intent的Activity。

总之,在Android中,在Application中以标准模式启动Activity会报出错误。解决此错误的方法是在Android 7.0及以上版本中使用FLAG_ACTIVITY_NEW_TASK标志,在Android 8.0中使用隐式Intent。