从服务调用带有FLAG_ACTIVITY_REORDER_TO_FRONT的活动

问题描述 投票:5回答:1

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

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

(P.S。我正在使用androidannotations,对打开活动A的调用发生在@EBean中,该本身在服务中使用。是否有一种简单的方法可以将活动上下文传递给该@EBean?]

android android-intent android-activity android-annotations
1个回答
0
投票

由于您要使用非活动context(例如applicationContext)来启动导致使用Intent.FLAG_ACTIVITY_NEW_TASK的活动,因此只有两种选择,避免每次您创建目标活动的新实例重新调用startActivity

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

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

这里是第二种方法的示例代码,研究了两种情况:

manifest.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)
        }
    }
}

ActivityA.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()
    }
}

ActivityB.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)
            }
        }
    }
}

结果:

“”“

© www.soinside.com 2019 - 2024. All rights reserved.