sak*_*das 8 android android-intent android-activity android-annotations
我试图从服务调用一个活动(活动 A),我想要发生的是检查堆栈上是否已经有 A 的实例,如果有,将它带到堆栈的顶部(和触发 onNewIntent() 方法),而不是总是创建 A 的新实例。
想知道这是否可能。我的活动在 androidmanifest 中使用“singleTop”启动模式。从活动外部调用活动所需的通常 Intent.FLAG_ACTIVITY_NEW_TASK 标志不会将已经打开的活动 A 带到堆栈顶部,而是始终创建 A 的新实例。而且似乎当我同时使用两者时flags (intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) 同样的事情发生了(仍然是同一活动的 2 个实例)。有没有办法做到这一点,请始终牢记我是从服务,我不想将活动上下文传递给服务?
(PS 我正在使用 androidannotations,对打开活动 A 的调用发生在 @EBean 内部,@EBean 本身在服务中使用。是否有一种简单的方法可以将该活动上下文传递给该 @EBean?)
由于您想使用非活动context(例如applicationContext)来启动导致 use 的活动Intent.FLAG_ACTIVITY_NEW_TASK,因此您只有两种选择来避免每次调用时创建目标活动的新实例startActivity。
首先,通过android:launchMode="singleInstance"在活动的清单中指定,您可以强制在仅托管该实例的任务中只应存在该活动的一个实例。在这种情况下,如果宿主任务中存在该活动,则启动该活动会将其置于最前面,否则,将创建一个包含该活动的唯一实例的新任务。我认为这不是我们正在寻找的方式。
其次,通过android:launchMode="singleTask"在活动的清单中指定,我们可以获得更好的解决方案。在这种情况下,系统会创建一个新任务,并将该活动添加到该任务的根目录中(如果不存在该活动的实例)。否则,系统将包含活动实例的任务放在前面,然后路由到目标活动,并调用onNewIntent.
以下是第二种方法的示例代码,检查 2 个场景:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ActivityA" android:launchMode="singleTask" />
<activity android:name=".ActivityB" />
Run Code Online (Sandbox Code Playgroud)
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// First Scenario: ActivityA doesn't exist in back-stack
button1.setOnClickListener {
Intent(applicationContext, ActivityA::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}.let {
applicationContext.startActivity(it)
}
}
// Second Scenario: ActivityA exists in back-stack
button2.setOnClickListener {
startActivity(Intent(this, ActivityA::class.java))
// Start ActivityB after a while
Handler().postDelayed({
startActivity(Intent(this, ActivityB::class.java))
}, 1000)
}
}
}
Run Code Online (Sandbox Code Playgroud)
class ActivityA : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_a)
Toast.makeText(this, "onCreate on ActivityA", Toast.LENGTH_SHORT).show()
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
Toast.makeText(this, "onNewIntent on ActivityA", Toast.LENGTH_SHORT).show()
}
}
Run Code Online (Sandbox Code Playgroud)
class ActivityB : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_b)
button.setOnClickListener {
Intent(applicationContext, ActivityA::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}.let {
applicationContext.startActivity(it)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
…………

| 归档时间: |
|
| 查看次数: |
744 次 |
| 最近记录: |