问题:
如果目标可能取决于配置(屏幕大小,方向等),如何决定应启动哪种Activity
?当人们使用Notification
时经常会发生这种情况?
细节:
让我们考虑NewsReader sample,它演示了如何使用Fragment
来生成可以在多种屏幕尺寸和方向下正常播放的应用程序。这个程序的结构如下:
Fragment
。 HeadlinesFragment
。 ArticleFragment
)。在双 Pane 模式下,此 Activity 包含两个片段。在单 Pane 模式下,它仅包含NewsReaderActivity
。 HeadlinesFragment
。此 Activity 仅在单 Pane 模式下使用。它包含ArticleActivity
。 现在,假设我要增强此应用程序,以添加一个后台
ArticleFragment
来侦听新闻更新,并在有新新闻项时通过状态栏通知通知用户。合理的需求 list 可能如下所示:请注意,这些要求会根据当前配置转换为不同的目标 Activity 。特别是,
两种模式下的
Service
。 NewsReaderActivity
。 NewsReaderActivity
。 实现上述(2)和(3)的一种优雅方法是什么?我认为可以安全地排除
ArticleActivity
对当前配置进行探测的可能性,以决定使用Service
定位的 Activity 。我想到的一种解决方案是跳过(2)并始终执行(3)-即,如果只有一个新闻更新,则始终启动
PendingIntent
。 ArticleActivity的此片段看起来很有希望:@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
//...
// If we are in two-pane layout mode, this activity is no longer necessary
if (getResources().getBoolean(R.bool.has_two_panes)) {
finish();
return;
}
//...
//...
}
此代码可确保如果正在查看ArticleActivity
,但切换到不再需要的配置(例如,从纵向到横向);然后 Activity 简单结束。但是,这在我们的情况下不起作用,因为该意图将设置
ArticleActivity
标志;我们将创建一个新任务,并且堆栈上没有“先前” Activity 。因此,调用FLAG_ACTIVITY_NEW_TASK
只会清除整个堆栈。因此,如果要启动的 Activity 取决于屏幕配置,则如何确定从通知启动的 Activity ?
最佳答案
这是一个非常好的问题!
我同意将UI决策保留在UI层是可取的,但是让服务做出决策无疑是一个权宜之计。您可能会在UI层类上使用静态方法来将决策代码严格地保留在服务之外(例如,服务用于构建其createArticlePendingIntent()
的NewsReaderActivity
上的静态Notification
方法)。
在getActivity()
中的PendingIntent
中使用NewsReaderActivity
Notification
,并有足够的额外内容,以便NewsReaderActivity
知道它在此“显示文章”方案中。在调用setContentView()
之前,让它确定ArticleActivity
是否是正确的答案。如果是这样,NewsReaderActivity
会调用startActivity()
来启动ArticleActivity
,然后会调用finish()
摆脱自身(或者,如果您希望从本文中返回到NewsReaderActivity
,则不会这样做)。
或者,在getActivity()
中为PendingIntent
使用ICanHazArticleActivity
Notification
。 ICanHazArticleActivity
具有Theme.NoDisplay
,因此它将没有UI。它决定是启动NewsReaderActivity
还是ArticleActivity
,在正确的答案上调用startActivity()
,然后调用finish()
。与先前解决方案相比的优势在于,如果最终目标是NewsReaderActivity
,则不会短暂闪烁ArticleActivity
。
或者,使用我在答案第一段中提到的createArticlePendingIntent()
选项。
也许还有其他选择,但是这些都是我想到的。