Activity、AppCompatActivity、FragmentActivity和ActionBarActivity:何时使用哪个?

320
我来自iOS,在那里使用UIViewController很容易。但是在Android中,似乎更加复杂,需要为特定的API级别使用特定的UI组件。我正在阅读BigNerdRanch的Android书籍(大约两年前出版),他们建议我使用Activity来托管我的FragmentActivities。但是,我以为Activity已经被弃用了。

所以,对于API级别22(最低支持API级别15或16),我应该使用什么来托管这些组件?组件本身又该用什么呢?所有这些都有用途,还是应该只使用一两个?


1
你不会托管 FragmentActivity。你只能托管 Fragment。在较新的 Android 版本中,Activity 类本身已经更新以直接托管它们。为了支持旧版本,引入了 FragmentActivity - Ravi K Thapliyal
6
同样地,从API 11+开始,Activity支持ActionBar。早期版本通过ActionBarActivity来实现该功能,但它现在已经被弃用并被替换为AppCompatActivity。由于这两个类都扩展自FragmentActivity,因此它们也支持Fragment的托管。 - Ravi K Thapliyal
7个回答

383
  • 使用Activity作为基线。
  • 如果需要使用片段并支持API Level 16或更低版本,则使用support-v4support-v13库中的回退片段,同时使用FragmentActivity来支持嵌套片段。
  • 如果需要回退动作栏并支持API Level 11或更低版本,则使用appcompat-v7库中的AppCompatActivity
  • 不要使用ActionBarActivity,除非某个第三方库必须使用它。
  • 如果您想要使用后移的Material Design外观,请使用AppCompatActivity。如果不需要,但是需要嵌套片段,请使用FragmentActivity。如果都不需要,请使用Activity。请注意AppCompatActivity扩展了FragmentActivity,因此需要使用FragmentActivity功能的人可以使用AppCompatActivity

    如果我想要使用Material Design外观并且还想要嵌套片段怎么办?AppCompatActivity是否继承自FragmentActivity? - Orcun Sevsay
    5
    @MiloRambaldi说:是的,FragmentActivityAppCompatActivity 的祖先类。虽然我不建议使用嵌套片段,但只要嵌套片段起作用,AppCompatActivity 就支持嵌套片段。 - CommonsWare
    感谢您详细的回答,@CommonsWare。您能否说一下哪个minSDK可以允许只使用Activity获取大部分最新的内容而不需要support-v7,即非后向移植的Material Design。我的目标是min 19,target 25。 - jugutier
    1
    @jugutier:要使用Theme.Material,您需要minSdkVersion为21或更高。 - CommonsWare

    104

    Activity 是所有其他活动的基类,我不认为它会被弃用。它们之间的关系是:

    Activity <- FragmentActivity <- AppCompatActivity <- ActionBarActivity

    '<-' 在这里表示继承关系。根据参考资料ActionBarActivity已经被弃用,应该使用AppCompatActivity代替。

    因此,基本上使用AppCompatActivity总是正确的选择。它们之间的区别如下:

    • Activity是基本的。
    • 在基于Activity的情况下,FragmentActivity提供了使用Fragment的功能。
    • 在基于FragmentActivity的情况下,AppCompatActivity提供了ActionBar的功能。

    1
    实际上,FragmentActivity 继承自 ComponentActivity,而 ComponentActivity 又继承自 Activity - Sourav Kannantha B

    76

    2019: 使用 AppCompatActivity

    截至撰写本文时(请查看链接以确认此仍然正确),Android 文档建议使用 AppCompatActivity 如果您正在使用应用栏。

    这是给出的理由:

    从 Android 3.0(API 级别 11)开始,所有使用默认主题的活动都具有 ActionBar 作为应用栏。然而,随着各个 Android 版本的推出,原生 ActionBar 逐渐增加了应用栏功能。因此,原生 ActionBar 的行为取决于设备可能使用的 Android 系统版本。相比之下,最新功能添加到支持库的 Toolbar 版本中,并且可以在任何能够使用支持库的设备上使用。

    因此,您应该使用支持库的 Toolbar 类来实现您的活动应用栏。使用支持库的工具栏有助于确保您的应用程序在最广泛的设备范围内具有一致的行为。例如,Toolbar 小部件在运行 Android 2.1(API 级别 7)或更高版本的设备上提供材料设计体验,但本机操作栏除非设备运行 Android 5.0(API 级别 21)或更高版本,否则不支持材料设计。

    添加 ToolBar 的一般方向为:

    1. 添加 v7 appcompat 支持库
    2. 使您的所有活动都扩展 AppCompatActivity
    3. 在清单中声明您希望使用 NoActionBar
    4. ToolBar 添加到每个活动的 XML 布局中。
    5. 在每个活动的 onCreate 中获取 ToolBar

    有关详细信息,请参见文档说明。它们非常清晰和有用。


    嗨@Suragch,感谢您的帮助。假设我今天正在制作一个仅支持21及以上版本的应用程序。实际上,我永远不想要操作栏或应用栏(更像是全屏应用程序)。Studio建议(2016年11月)我可以使用“向后兼容(AppCompat)”。我的直觉是不要使用AppCompat。您作为专家有何看法?再次感谢您的帮助。 - Fattie
    我不是专家,所以不能给您专业意见,但文档建议支持尽可能多的设备,这就是我所做的。我在所有应用程序中使用AppCompat,迄今为止效果很好。如果您真的不想支持21之前的版本,那么可以忽略Studio的建议。 - Suragch

    51
    对于最低API级别为15,您应该使用AppCompatActivity。例如,您的MainActivity将如下所示:
    public class MainActivity extends AppCompatActivity {
        ....
        ....
    }
    

    如果要使用 AppCompatActivity,请确保已下载了Google支持库(您可以在“工具”->“Android”->“SDK管理器”中检查此项)。然后,在您应用的 gradle.build 文件中,只需包含gradle依赖项:

    compile 'com.android.support:appcompat-v7:22:2.0'
    

    你可以将这个AppCompat作为你的主要Activity,然后可以用它来启动Fragments或其他Activities(这取决于你正在构建的应用程序类型)。

    《BigNerdRanch》这本书是一个很好的资源,但是它已经过时了。阅读一下里面关于Android如何工作的通用信息,但不要指望它们使用的具体类是最新的。


    好的,我的gradle.build文件中确实有这个依赖项。因此,例如,如果我正在制作一个带有大量行的表格(就像任何笔记应用程序一样),我的主屏幕将是AppCompat,任何其他托管内容也将是AppCompat?我基本上只需要使用AppCompat吗? - Jameson
    所以你的AppCompat将会填充一些指定设计(带有一堆行的表格)的布局资源。但是假设你想在点击某一行时打开一个新页面。你可以设置一个onClick监听器来打开一个新的AppCompat活动或片段。 - adao7000
    1
    @adao7000,你在哪里看到说15或以上可以使用AppCompatActivity的?我认为在android.support.v7.app中的v7是指最低要求的sdk版本为7。 - codebased
    1
    @codebased android.support.v7 可以在 API 级别 9 开始使用。来源:https://developer.android.com/topic/libraries/support-library/features.html#v7 - adao7000
    你在哪里读到/找到这些信息的?有 Stack Overflow 这样的问答网站确实很棒,但我从来不知道这些文档藏在哪儿! - LifeQuestioner

    33

    Activity类是基础类,自API 11开始支持Fragment管理。因为其专业化程度更高,不再推荐纯粹使用。

    ActionBarActivity曾一度成为Activity类的替代品,因为它使得在应用程序中处理ActionBar变得容易。

    AppCompatActivity新的方法,因为不再鼓励使用ActionBar,而应该使用Toolbar(当前ActionBar的替代品)。 AppCompatActivity继承自FragmentActivity,所以如果您需要处理Fragment,则可以通过Fragment Manager实现。 AppCompatActivity适用于任何API,不仅仅是16+(谁说过这话?)。 您可以通过在Gradle文件中添加compile 'com.android.support:appcompat-v7:24:2.0'来使用它。我在API 10上使用它,表现很好。


    1
    "ActionBar现已过时" -- 操作栏并非过时。 "您需要使用Toolbar替代" -- 应用程序不需要使用Toolbar - CommonsWare
    @CommonsWare 好的,它已经不再被弃用了,但是它的使用方式不再被鼓励(旧的那种)。现在,如果你想在你的应用中有一个操作栏,你应该手动添加一个工具栏。 - Joaquin Iurchuk
    “不再鼓励以更纯粹的形式使用它”-- 我在文档或官方博客文章中没有看到任何可以证明你说法的东西。你有链接吗? - CommonsWare
    @CommonsWare 您是这里的权威,您是正确的。只有Material Design指南建议使用工具栏作为操作栏。也许我应该删除我的答案,因为它不够精确。谢谢。 - Joaquin Iurchuk
    2
    从Support Library 26.0.0版本(于2017年7月发布)开始,所有支持库包的最低支持API级别已更改为Android 4.0(API级别14)。 - Andrea Leganza
    新的更新正在使我们离开旧设备远远落后... - gumuruh

    16

    这里存在很大的混淆,尤其是如果您阅读过时的资料。

    基本的一个是Activity,它可以显示片段(Fragments)。如果您的Android版本> 4,可以使用此组合。

    但是,还有一个支持库,涵盖了您提到的其他类:FragmentActivityActionBarActivityAppCompat。最初它们被用来支持Android版本< 4上的片段,但实际上它们也用于从较新版本的Android中回溯功能(例如Material Design)。

    最新的是AppCompat,另外两个已经过时。我使用的策略是始终使用AppCompat,以便在将来的Android版本回溯时应用程序已准备就绪。


    谢谢!好的,所以我可以使用AppCompat来代替Activity来托管...什么?是为了托管其他AppCompats吗?还是为了托管FragmentActivities? - Jameson
    一个活动通常只托管其他片段......不用担心FragmentActivity,它更像是所有其他花哨的XXXActivity派生自的“基础”类。 - Mehdi
    但是我的AppCompat应该承载哪个类?另一个AppCompat还是其他什么东西? - Jameson
    你只需要明白一件事情:活动托管片段。顺便提一下,活动不会由其他任何东西托管,它们不能嵌套。Appcompat 只是另一种类型的活动。在此之后,您可以继续嵌套片段,但这开始变得复杂难以管理。 - flower_green
    好的,非常感谢。我想我现在明白了。我将使用AppCompat作为我的“Activity”,并托管FragmentActivities。对吗? - Jameson
    1
    不,你应该使用AppCompat作为Activity并托管Fragment,而不是FragmentActivity。 - flower_green

    3

    由于Android未来版本中名称可能会更改(目前最新的是AppCompatActivity,但它可能在某个时候更改),因此我认为一个好的做法是创建一个类Activity,该类继承AppCompatActivity,然后所有的活动都从该类继承。如果明天他们将名称更改为AppCompatActivity2,您只需要在一个地方进行更改。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接