从服务调用时活动重新启动

Posted

技术标签:

【中文标题】从服务调用时活动重新启动【英文标题】:Activity restarts when called from service 【发布时间】:2019-02-27 04:10:15 【问题描述】:

我的应用程序中有一个浮动按钮服务(如 facebook messenger) 当点击时,我的活动从后台返回,但它不会以与缩小时相同的方式返回,它会再次调用 onCreate ,知道导致这种行为的原因吗?

在我的清单中,活动带有属性:

            android:launchMode="singleTask"

它是由我的服务调用的:

    Intent i = new Intent(FloatingViewService.this, DrawerActivity2.class);
    i.putExtra("fromController",true);
    i.setFlags(FLAG_FROM_BACKGROUND);
    FloatingViewService.this.startActivity(i);

我的主要问题是在活动内部,我有一个 web 视图,每次单击按钮时它都会重新加载并调用活动,而不是保持不变。

更新后这是我在清单中的活动

        <activity
        android:name=".DrawerActivity2"
        android:configChanges="orientation"
        android:launchMode="singleTop"
        android:screenOrientation="portrait"
        android:theme="@style/OtherTheme"/>

更新 2

值得一提的是,它是一个位于应用程序中的库。

我试过这段代码来打开活动:

Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); startActivity(intent);

它打开了第一个(原始应用程序的)活动,而不是打开的活动。

我们将不胜感激任何帮助

【问题讨论】:

请发布您的清单。 什么时候添加 singleTask 作为启动模式?哪个方法被调用?创建?还是 onNewIntent? 好吧,我没有覆盖 onNewIntent 但每次都调用 onCreate 添加了有关问题的更多信息.. 【参考方案1】:

我只能想象你的FLAG_FROM_BACKGROUND 是什么意思。而且我想知道它是否如此调用是因为您之前遇到了一些崩溃,例如“可以在没有来自 applicationContext bla bla 的 FLAG_NEW_TASK 的情况下启动活动”。随便。

因此,如果您有 Intent.FLAG_ACTIVITY_NEW_TASK,您将始终在 NEW_TASK 中实例化您的 DrawerActivity2。它将永远是,你知道“新的”活动。 将 launchMode 更改为 singleTop 不会产生预期的结果。 Read about launchModes and Flags here

请注意,您不能使用 ApplicationContext(或 BaseContext/ContextWrapper 扩展的 BaseContext/ContextWrapper)在同一 TASK 内启动 Activity。为此,你必须使用Activity的上下文开始新的Activity

关于Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); startActivity(intent); 可能它按预期工作

当前的实现首先在 类别 Intent.CATEGORY_INFO 和 next 中的主要活动 类别 Intent.CATEGORY_LAUNCHER。如果都没有找到,则返回 null。

Android developers source

你问

我的活动从后台返回,它从再次调用 onCreate 开始,知道是什么原因造成的 行为?

我的假设是FLAG_FROM_BACKGROUND

Intent i = new Intent(FloatingViewService.this, DrawerActivity2.class);
    i.putExtra("fromController",true);
    i.setFlags(FLAG_FROM_BACKGROUND); /*is it really Intent.FLAG_ACTIVITY_NEW_TASK ???*/
    FloatingViewService.this.startActivity(i);

如何解决?可能是用ActivityContext而不是ApplicationContext来启动Activity。但这是不同的故事。并且不能推荐如何实现它的“好”方式。

【讨论】:

很好的答案,有没有一种简单的方法可以将活动上下文获取到服务? 您确定您真的需要在 Service 中进行活动吗?还有其他方法可以改进您的应用程序吗?如果没有其他方法作为最后的手段,我会使用没有任何布局的后台活动。我可能会将它保存在 Application 类中作为静态字段。当 Service 调用 onDestroy() 时,我会清除该引用 好吧,服务是一个浮动按钮,当有来电时启动,按下它会导致返回到 dailer,另一个返回到活动等等......你会怎么做在这种情况下怎么办? 将活动上下文获取到服务的一种简单方法是启动一个启动 DrawerActivity2 的活动。如果您将launcherActivity noHistory 设置为true 并完成它应该有预期的结果。 @yanivtwin 你真的能用这个答案解决你的问题吗?你改变了什么?我在这里看不到任何有用的东西。我很好奇。【参考方案2】:

你需要:

<activity
        android:name=".DrawerActivity2"
        android:launchMode = "singleInstance" />

【讨论】:

【参考方案3】:

我认为如果您使用 launchMode singleTop 和 i.setFlags(FLAG_ACTIVITY_NEW_TASK) 它应该可以工作,但前提是 Activity 位于堆栈顶部。

如果你不能确保activity在栈顶,值得尝试将launchMode设置为singleTask和i.setFlags(FLAG_ACTIVITY_NEW_TASK)

【讨论】:

以上是关于从服务调用时活动重新启动的主要内容,如果未能解决你的问题,请参考以下文章

从通知意图启动活动时重新创建 Android ViewModel

启动相机意图时未调用 onActivityResult?

前台服务已终止且未重新启动

如何在不重新启动活动的情况下切换主题(夜间模式)?

应用程序从深层链接启动,然后从启动器再次激活重新启动活动

前台服务内容意图不是恢复应用程序而是重新启动它