android - 从服务调用带有 FLAG_ACTIVITY_REORDER_TO_FRONT 的 Activity

标签 android android-intent android-activity android-annotations

我正在尝试从服务中调用一个 Activity ( Activity A),我想要发生的是检查堆栈上是否已经存在 A 的实例,如果有,将其带到堆栈的顶部(并且触发 onNewIntent() 方法),而不是总是创建 A 的新实例。

想知道这是否可能。我的 Activity 在 androidmanifest 中使用“singleTop”启动模式。从 Activity 外部调用 Activity 所需的通常 Intent.FLAG_ACTIVITY_NEW_TASK 标志不会将已经打开的 Activity A 带到堆栈的顶部,但总是会创建 A 的新实例。似乎当我同时使用两者时flags (intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) 发生同样的事情(仍然是同一 Activity 的 2 个实例)。有没有办法做到这一点,始终记住我是从一个服务,我不想将 Activity 上下文传递给服务?

(附注:我正在使用 androidannotations,对打开 Activity A 的调用发生在 @EBean 内部,该 @EBean 本身用于服务中。有没有一种简单的方法可以以某种方式将该 Activity 上下文传递给该 @EBean?)

最佳答案

由于您想使用非 Activity context (例如 applicationContext )启动导致使用 Intent.FLAG_ACTIVITY_NEW_TASK 的 Activity ,您只有两个选择来避免每次调用 startActivity 时都创建目标 Activity 的新实例。 .

首先,通过指定 android:launchMode="singleInstance"在 Activity 的 list 中,您可以强制在仅托管此实例的任务中只存在一个 Activity 实例。在这种情况下,如果宿主任务中存在 Activity ,则启动 Activity 会将其置于最前面,否则,将创建一个包含 Activity 唯一实例的新任务。我认为这不是我们正在寻找的方式。

二、通过指定android:launchMode="singleTask"在 Activity list 中,我们可以实现更好的解决方案。在这种情况下,如果不存在该 Activity 的实例,系统将创建一个新任务并将该 Activity 添加到该任务的根目录。否则,系统会将包含该 Activity 实例的任务带到最前面,然后路由到目标 Activity ,并调用onNewIntent。 .

这是第二种方法的示例代码,检查了 2 个场景:

list .xml:

<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" />

MainActivity.kt:
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)
        }
    }
}

Activity A.kt
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()
    }
}

Activity B.kt
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)
            }
        }
    }
}

结果:


…………

关于android - 从服务调用带有 FLAG_ACTIVITY_REORDER_TO_FRONT 的 Activity ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29538477/

相关文章:

java - 转换 Java 代码以解决 Android 问题?

java - 为管理员 Firebase Android 创建重置密码

android - 在 Android 上保持后台服务活跃

android - 尝试从其他应用安装 APK 时如何使用默认包安装程序(Android)?

android - Activity exported=false 在 Activity 选择器中列出

android - 将特定 Activity 作为堆栈中的根 Activity

安卓 : Full Screen Activity with Title bar

android 检查联系人是否安装了 android 应用程序(如 whatsapp)

android - 优步服务器 token

java - Android:从另一个 Activity 获取不正确的复选框值