【问题标题】:open android activity in new task without using android:launchMode="singleTask"在新任务中打开 android 活动而不使用 android:launchMode="singleTask"
【发布时间】:2014-05-26 07:37:56
【问题描述】:

我创建了一个带有主要活动的浏览器应用程序,它响应以下意图:

 <intent-filter> 
       <data android:scheme="http"/>
       <data android:scheme="https"/>
       <category android:name="android.intent.category.DEFAULT"/>
       <category android:name="android.intent.category.BROWSABLE"/>
       <action android:name="android.intent.action.VIEW"/>
 </intent-filter>

如果我选择我的应用程序,则在其他任务(gmail、sms)的 url 上单击,活动将在与调用任务相同的任务中打开。 当我选择不同的浏览器(Mozila firefox、chrome、dolphine)时,它们会在不同的任务中打开。

查看其他浏览器清单,我看到没有人使用 android:launchMode="singleTask"

我不想使用单任务标志,因为它不被谷歌推荐,也让我有其他问题。

我试图了解其他浏览器是如何做到的,但没有弄明白。

有什么想法吗?有没有其他方法可以在不使用 singleTask 标志的情况下在不同的任务中打开我的活动?

【问题讨论】:

  • 也许您可以在启动活动的意图上设置一个标志:Intent.FLAG_ACTIVITY_NEW_TASK 或 Intent.FLAG_ACTIVITY_SINGLE_TOP 查看文档:developer.android.com/guide/components/…developer.android.com/reference/android/content/Intent.html
  • 不,因为发送活动的应用程序不是我的(例如 gmail)
  • @user3398598,Guy 的建议是有道理的:您应该将它与 Emanuel 的答案结合起来 - 请参阅我的评论。我知道您已经实施了一种解决方法,但是这种方法更简单恕我直言,仅供参考。

标签: android android-intent


【解决方案1】:

如果活动在单个任务中运行,您可以签入 onCreate。如果不只是完成()它并使用 FLAG_ACTIVITY_NEW_TASK 再次创建它

这可能对你有帮助

   ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);

    for (RunningTaskInfo task : tasks) {
        if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName())) 
          // check if it's the only one activity or whatever                               
    }

【讨论】:

  • 感谢您的回答,getRunningTasks 仅用于调试,请参阅:developer.android.com/reference/android/app/…
  • 这是最好的方法,但应该简化:不需要检查正在运行的任务。在onCreate 方法中检查getData() 就足够了,如果它不为null,则使用FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK 重新启动活动的新实例,通过自定义额外将Uri 传递给它,然后finish() 当前实例。我确定这就是其他浏览器的工作方式
【解决方案2】:

我在Android Developerssite找到了如下描述:

作为另一个示例,Android 浏览器应用程序声明 Web 浏览器活动应始终在其自己的任务中打开——通过指定 元素中的 singleTask 启动模式。这意味着 如果您的应用程序发出打开 Android 浏览器的意图,它的 活动未与您的应用程序放在同一任务中。反而, 为浏览器启动一个新任务,或者,如果浏览器已经 有一个任务在后台运行,该任务被提前到 处理新的意图。

如您所见,android:launchMode=singleTask 是您的正确选择。您已经提到您在使用此属性时遇到了问题,所以也许让我们关注它们。

28.05.2014 更新

Google 关于 singleTask 启动模式的说明:

其他模式——singleTask 和 singleInstance——不合适 对于大多数应用程序,因为它们会产生一个交互模型 用户可能不熟悉,并且与大多数人有很大不同 其他应用程序。

来自 Google 的 singleTask 和 singleInstance 用例:

专门启动(不推荐用于一般用途)

正如您所见,可能不建议将 singleTask 用于一般用途,但您的情况并不普遍,实际上它是 singleTask 非常适合的情况之一。 换句话说,singleTask 不是被禁止的,它只是需要谨慎使用,以便为最终用户提供与您的应用程序的共同体验。

我希望我现在已经为你说清楚了。在您的情况下,对这种启动模式感到满意。

【讨论】:

  • 我已经尝试过了(将我的包 ID 作为 Affinity),但它不起作用。我想因为我的任务还没有开始,所以活动将在调用任务中打开。
  • 即使您的活动没有开始,它也应该在新任务中打开。你能告诉你如何确定你的活动在同一个任务中吗?
  • 两个指示: 第一个:在任务管理器中我只看到一个任务(消息传递任务),点击它时我看到我的活动。第二:在“运行活动”中运行“adb shell dumpsys 活动”我看到一个任务有两个活动:mms 和我的活动。
  • 我已将我的包名作为 Affinity,对吗?
  • 是的,没关系。你还记得设置allowTaskReparenting 和affinity 吗?你能解释一下为什么你需要你的活动在单独的任务中吗?出于最初的原因,也许我们可以想出另一个解决方案。
【解决方案3】:

您正在尝试稍微“改变规则”,但您对不使用 android:launchMode="singleTask" 试图避免的事情还不够清楚。

所以我建议研究一下:

  1. 创建一个Service 并让Service 监听意图过滤器。然后让这个Service 打开你的Activity,并正确设置Activity 的亲和力以匹配Service 的。这将使您能够克服亲和力未正确绑定 Activity 的问题。

  2. 有一个沉默的Activity 开始一个新的Activity 并退出。静默的Activity 将在一个新堆栈中启动(而不是在单任务模式下),并在启动您实际需要的Activity 时自行关闭。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
相关资源
最近更新 更多