如何正确调用上下文以启动 Activity
How do I call the context correctly to start an Activity
自从我遇到这种类型的崩溃:
Calling startActivity() from outside of an Activity context requires
the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
一开始我开始想知道上下文的正确用法Activity-Intent。
这是我的 Kotlin 代码(Activity -> Activity):
btn_scan.setOnClickListener {
val mIntent = Intent(applicationContext, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
applicationContext.startActivity(mIntent)
}
我可以用 "this":
修复
btn_scan.setOnClickListener {
val mIntent = Intent(this, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
this.startActivity(mIntent)
}
但现在我对它的正确用法有点不安全,因为从内部函数访问它需要 this@ActivityName。
因此,我想请您礼貌地向我解释,当从 Activity、片段或函数或使用 CoroutineScope[=14] 开始 Activity 时,如何知道哪个是正确的上下文=]
谢谢
不确定我是否可以回答你所有的问题,但这是我的两分钱:
当您的应用程序崩溃时,您的代码如下所示:
btn_scan.setOnClickListener {
val mIntent = Intent(applicationContext, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
applicationContext.startActivity(mIntent)
}
错误消息说当从 Activity
上下文之外启动 Activity
时,您应该使用 FLAG_ACTIVITY_NEW_TASK
。您使用了 Application
上下文,它类似于 Activity
上下文继承的 "cousin"(请参阅 ContextWrapper 了解子类及其关系),因此 Intent
检查了标志,但缺少所需的标志。
但是如果明确设置了标志,为什么会丢失?
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
那是因为你紧接着给mIntent.flags赋了另一个值:
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
如果你想同时拥有这两个标志,你必须 添加 它们:
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + Intent.FLAG_ACTIVITY_CLEAR_TOP
现在应用程序不再崩溃。
但是 Application
上下文在这里是必要的吗?毕竟您的代码是 Activity
的一部分,并且 Activity
是 Context
.
的间接子类
您可能尝试了以下方法并且有效:
btn_scan.setOnClickListener {// Note: your IDE tells you "it: View!"
val mIntent = Intent(applicationContext, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
this.startActivity(mIntent)
}
因为在 OnClickListener
lambda 内部,View
被 "it" 引用,没有歧义:"this" 引用 Activity
,没有崩溃。
(当然现在你可以跳过Intent.FLAG_ACTIVITY_NEW_TASK
)
当你有这样的东西时,事情看起来会有所不同:
with(btn_scan){ // this: Button!
setOnClickListener{ // it: View!
val mIntent = Intent(applicationContext, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + Intent.FLAG_ACTIVITY_CLEAR_TOP
this.startActivity(mIntent)
}
}
现在您的 IDE 不会接受 this.startActivity(mIntent)
。这是因为这里的"this"指的是Button
。如果你想要另一个,"outer this",你必须明确地说出是哪个。在 Kotlin 中,您可以通过添加 @ActivityName 来实现。
我想 Activity
中的协程代码也是如此(尽管我必须承认我还不是协程专家):只要 Activity
"this" 隐藏在后面一些本地 "this",你需要注释。
回到熟悉的地方:Fragment
的 context
属性 是 Activity
的上下文,如果 Fragment
附加到 Activity
,否则就是null
。因此,如果它不是 null
,您可以使用它来启动 Activity
。
但您甚至可以使用 Button
的 context
属性,因为它也与 Activity
上下文相同:
with(btn_scan){ // this: Button!
setOnClickListener{
val mIntent = Intent(applicationContext, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
this.context.startActivity(mIntent)
}
}
如果使用科特林
btn_scan.setOnClickListener {
val mIntent = Intent(this, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
this.startActivity(mIntent)
}
自从我遇到这种类型的崩溃:
Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
一开始我开始想知道上下文的正确用法Activity-Intent。
这是我的 Kotlin 代码(Activity -> Activity):
btn_scan.setOnClickListener {
val mIntent = Intent(applicationContext, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
applicationContext.startActivity(mIntent)
}
我可以用 "this":
修复btn_scan.setOnClickListener {
val mIntent = Intent(this, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
this.startActivity(mIntent)
}
但现在我对它的正确用法有点不安全,因为从内部函数访问它需要 this@ActivityName。 因此,我想请您礼貌地向我解释,当从 Activity、片段或函数或使用 CoroutineScope[=14] 开始 Activity 时,如何知道哪个是正确的上下文=]
谢谢
不确定我是否可以回答你所有的问题,但这是我的两分钱:
当您的应用程序崩溃时,您的代码如下所示:
btn_scan.setOnClickListener {
val mIntent = Intent(applicationContext, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
applicationContext.startActivity(mIntent)
}
错误消息说当从 Activity
上下文之外启动 Activity
时,您应该使用 FLAG_ACTIVITY_NEW_TASK
。您使用了 Application
上下文,它类似于 Activity
上下文继承的 "cousin"(请参阅 ContextWrapper 了解子类及其关系),因此 Intent
检查了标志,但缺少所需的标志。
但是如果明确设置了标志,为什么会丢失?
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
那是因为你紧接着给mIntent.flags赋了另一个值:
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
如果你想同时拥有这两个标志,你必须 添加 它们:
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + Intent.FLAG_ACTIVITY_CLEAR_TOP
现在应用程序不再崩溃。
但是 Application
上下文在这里是必要的吗?毕竟您的代码是 Activity
的一部分,并且 Activity
是 Context
.
您可能尝试了以下方法并且有效:
btn_scan.setOnClickListener {// Note: your IDE tells you "it: View!"
val mIntent = Intent(applicationContext, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
this.startActivity(mIntent)
}
因为在 OnClickListener
lambda 内部,View
被 "it" 引用,没有歧义:"this" 引用 Activity
,没有崩溃。
(当然现在你可以跳过Intent.FLAG_ACTIVITY_NEW_TASK
)
当你有这样的东西时,事情看起来会有所不同:
with(btn_scan){ // this: Button!
setOnClickListener{ // it: View!
val mIntent = Intent(applicationContext, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + Intent.FLAG_ACTIVITY_CLEAR_TOP
this.startActivity(mIntent)
}
}
现在您的 IDE 不会接受 this.startActivity(mIntent)
。这是因为这里的"this"指的是Button
。如果你想要另一个,"outer this",你必须明确地说出是哪个。在 Kotlin 中,您可以通过添加 @ActivityName 来实现。
我想 Activity
中的协程代码也是如此(尽管我必须承认我还不是协程专家):只要 Activity
"this" 隐藏在后面一些本地 "this",你需要注释。
回到熟悉的地方:Fragment
的 context
属性 是 Activity
的上下文,如果 Fragment
附加到 Activity
,否则就是null
。因此,如果它不是 null
,您可以使用它来启动 Activity
。
但您甚至可以使用 Button
的 context
属性,因为它也与 Activity
上下文相同:
with(btn_scan){ // this: Button!
setOnClickListener{
val mIntent = Intent(applicationContext, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
this.context.startActivity(mIntent)
}
}
如果使用科特林
btn_scan.setOnClickListener {
val mIntent = Intent(this, Scanner::class.java)
mIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
this.startActivity(mIntent)
}