319

I'm coming from iOS where it's easy and you simply use a UIViewController. However, in Android things seem much more complicated, with certain UIComponents for specific API Levels. I'm reading BigNerdRanch for Android (the book is roughly 2 years old) and they suggest I use Activity to host my FragmentActivities. However, I thought Activity was deprecated.

So for API Level 22 (with a minimum support for API Level 15 or 16), what exactly should I use both to host the components, and for the components themselves? Are there uses for all of these, or should I be using one or two almost exclusively?

Majid
  • 13,853
  • 15
  • 77
  • 113
Jameson
  • 4,198
  • 4
  • 17
  • 31
  • 1
    You won't be hosting `FragmentActivity`ies. You only host `Fragment`s. On newer Android versions the `Activity` class itself has been updated to host them directly. To support older versions `FragmentActivity` was introduced. – Ravi K Thapliyal Jul 08 '15 at 15:45
  • 6
    Similarly, with API 11+ `Activity`ies had support for an `ActionBar`. This was supported on older versions through `ActionBarActivity` first which now has been deprecated and replaced with `AppCompatActivity`. Since, both of these classes extend `FragmentActivity` they support hosting `Fragment`s as well. – Ravi K Thapliyal Jul 08 '15 at 15:50

7 Answers7

383

I thought Activity was deprecated

No.

So for API Level 22 (with a minimum support for API Level 15 or 16), what exactly should I use both to host the components, and for the components themselves? Are there uses for all of these, or should I be using one or two almost exclusively?

Activity is the baseline. Every activity inherits from Activity, directly or indirectly.

FragmentActivity is for use with the backport of fragments found in the support-v4 and support-v13 libraries. The native implementation of fragments was added in API Level 11, which is lower than your proposed minSdkVersion values. The only reason why you would need to consider FragmentActivity specifically is if you want to use nested fragments (a fragment holding another fragment), as that was not supported in native fragments until API Level 17.

AppCompatActivity is from the appcompat-v7 library. Principally, this offers a backport of the action bar. Since the native action bar was added in API Level 11, you do not need AppCompatActivity for that. However, current versions of appcompat-v7 also add a limited backport of the Material Design aesthetic, in terms of the action bar and various widgets. There are pros and cons of using appcompat-v7, well beyond the scope of this specific Stack Overflow answer.

ActionBarActivity is the old name of the base activity from appcompat-v7. For various reasons, they wanted to change the name. Unless some third-party library you are using insists upon an ActionBarActivity, you should prefer AppCompatActivity over ActionBarActivity.

So, given your minSdkVersion in the 15-16 range:

  • If you want the backported Material Design look, use AppCompatActivity

  • If not, but you want nested fragments, use FragmentActivity

  • If not, use Activity

Just adding from comment as note: AppCompatActivity extends FragmentActivity, so anyone who needs to use features of FragmentActivity can use AppCompatActivity.

Lii
  • 11,553
  • 8
  • 64
  • 88
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • What if I want to use Material Design look and also want nested fragments? Does AppCompatActivity inherits from FragmentActivity? – Orcun Sevsay Nov 17 '15 at 11:38
  • 5
    @MiloRambaldi: Yes, `FragmentActivity` is an ancestor of `AppCompatActivity`. While I do not recommend using nested fragments, to the extent that nested fragments work at all, `AppCompatActivity` will support nested fragments. – CommonsWare Nov 17 '15 at 11:40
  • Thanks for the detailed answer @CommonsWare. Could you say which minSDK would allow to just use `Activity` getting most of the latest without `support-v7` i.e non-backported Material Design. My aim is min 19 target 25 – jugutier Feb 17 '17 at 14:05
  • 1
    @jugutier: To use `Theme.Material`, you need `minSdkVersion` of 21 or higher. – CommonsWare Feb 17 '17 at 15:21
104

Activity is the base class of all other activities, I don't think it will be deprecated. The relationship among them is:

Activity <- FragmentActivity <- AppCompatActivity <- ActionBarActivity

'<-' means inheritance here. The reference said ActionBarActivity is deprecated, use AppCompatActivity instead.

So basically, using AppCompatActivity is always the right choice. The differences between them are:

  • Activity is the basic one.
  • Based on Activity, FragmentActivity provides the ability to use Fragment.
  • Based on FragmentActivity, AppCompatActivity provides features to ActionBar.
Junaid Pathan
  • 3,850
  • 1
  • 25
  • 47
Ted Yu
  • 1,784
  • 1
  • 10
  • 16
76

2019: Use AppCompatActivity

At the time of this writing (check the link to confirm it is still true), the Android Documentation recommends using AppCompatActivity if you are using an App Bar.

This is the rational given:

Beginning with Android 3.0 (API level 11), all activities that use the default theme have an ActionBar as an app bar. However, app bar features have gradually been added to the native ActionBar over various Android releases. As a result, the native ActionBar behaves differently depending on what version of the Android system a device may be using. By contrast, the most recent features are added to the support library's version of Toolbar, and they are available on any device that can use the support library.

For this reason, you should use the support library's Toolbar class to implement your activities' app bars. Using the support library's toolbar helps ensure that your app will have consistent behavior across the widest range of devices. For example, the Toolbar widget provides a material design experience on devices running Android 2.1 (API level 7) or later, but the native action bar doesn't support material design unless the device is running Android 5.0 (API level 21) or later.

The general directions for adding a ToolBar are

  1. Add the v7 appcompat support library
  2. Make all your activities extend AppCompatActivity
  3. In the Manifest declare that you want NoActionBar.
  4. Add a ToolBar to each activity's xml layout.
  5. Get the ToolBar in each activity's onCreate.

See the documentation directions for more details. They are quite clear and helpful.

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • Hi @Suragch, thanks for this. Say I'm making an app today that ONLY supports 21 onwards. Indeed, as it happens I do not want, ever, an action bar or app bar (more of a fullscreen app). Studio is suggesting (November 16) I might use **"Backwards compatability (AppCompat)"**. My gut instinct is DON'T use AppCompat. What is your expert opinion? I can only thank you, thanks. – Fattie Nov 26 '16 at 14:58
  • I'm not an expert so I can't give you an expert opinion, but the documentation suggests supporting as many devices as possible so that is what I do. I use AppCompat with all my apps and it has worked well so far. I suppose if you really don't want to support pre 21 then you can ignore the Studio suggestion. – Suragch Jun 24 '17 at 23:51
51

For a minimum API level of 15, you'd want to use AppCompatActivity. So for example, your MainActivity would look like this:

public class MainActivity extends AppCompatActivity {
    ....
    ....
}

To use the AppCompatActivity, make sure you have the Google Support Library downloaded (you can check this in your Tools -> Android -> SDK manager). Then just include the gradle dependency in your app's gradle.build file:

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

You can use this AppCompat as your main Activity, which can then be used to launch Fragments or other Activities (this depends on what kind of app you're building).

The BigNerdRanch book is a good resource, but yeah, it's outdated. Read it for general information on how Android works, but don't expect the specific classes they use to be up to date.

adao7000
  • 3,632
  • 2
  • 28
  • 37
  • OK, I do have that dependency in my gradle.build file. So, for example, if I'm making a table with a bunch of rows (like any Notes application), my main screen will be an AppCompat and also anything else that hosts will also be an AppCompat? Do I basically only need to use AppCompat? – Jameson Jul 08 '15 at 15:44
  • So your AppCompat will inflate some layout resource that specifies the design (table with a bunch of rows). But let's say you want to open a new page when you click on a row. You can set an onClickListener to open a new AppCompat Activity or a Fragment. – adao7000 Jul 08 '15 at 15:47
  • As of Aug 3, BigNerdRanch has a new edition of its book: http://www.amazon.com/Android-Programming-Nerd-Ranch-Guide/dp/0134171454/ref=sr_1_1?ie=UTF8&qid=1441896903&sr=8-1&keywords=big+nerd+ranch – bryant1410 Sep 10 '15 at 14:55
  • 1
    @adao7000 mate where it has mentioned that for 15 or above you can use AppCompatActivity - I thought v7 in android.support.v7.app is for minimum sdk required is 7. – codebased Jul 24 '16 at 11:43
  • 1
    @codebased android.support.v7 can be used started at API level 9. Source: https://developer.android.com/topic/libraries/support-library/features.html#v7 – adao7000 Sep 12 '16 at 15:56
  • Where did you read/find this information out? It's great having stack overflow to ask questions but I never have any idea where the documentation is on this! – LifeQuestioner Mar 21 '17 at 16:00
33

Activity class is the basic class. (The original) It supports Fragment management (Since API 11). Is not recommended anymore its pure use because its specializations are far better.

ActionBarActivity was in a moment the replacement to the Activity class because it made easy to handle the ActionBar in an app.

AppCompatActivity is the new way to go because the ActionBar is not encouraged anymore and you should use Toolbar instead (that's currently the ActionBar replacement). AppCompatActivity inherits from FragmentActivity so if you need to handle Fragments you can (via the Fragment Manager). AppCompatActivity is for ANY API, not only 16+ (who said that?). You can use it by adding compile 'com.android.support:appcompat-v7:24:2.0' in your Gradle file. I use it in API 10 and it works perfect.

Joaquin Iurchuk
  • 5,499
  • 2
  • 48
  • 64
  • 1
    "the ActionBar is now deprecated" -- the action bar is not deprecated. "you need to use Toolbar instead" -- apps do not need to use `Toolbar`. – CommonsWare Jul 08 '15 at 15:46
  • @CommonsWare Ok, it's no deprecated but its use is not encouraged anymore in its more pure form (the old one). Now, *if you want to have an Action Bar in your app* you should add it manually using a Toolbar . – Joaquin Iurchuk Jul 08 '15 at 15:52
  • "its use is not encouraged anymore in its more pure form" -- I have seen nothing in the documentation or official blog posts that would justify your claim. Do you have a link? – CommonsWare Jul 08 '15 at 15:55
  • @CommonsWare You are the eminence here and you're right. Only Material design guidelines suggest the use of a Toolbar as an Action Bar. Maybe I should delete my answer as it is not precise. Thanks – Joaquin Iurchuk Jul 08 '15 at 16:01
  • 2
    _Starting with Support Library version 26.0.0 (released in July 2017), the minimum supported API level has changed to Android 4.0 (API level 14) for all support library packages._ source: https://developer.android.com/topic/libraries/support-library/index.html – Andrea Leganza Aug 29 '17 at 06:14
  • the new update is making us leaving the older devices leeeefttt... behind... – gumuruh Jun 07 '20 at 07:48
16

There is a lot of confusion here, especially if you read outdated sources.

The basic one is Activity, which can show Fragments. You can use this combination if you're on Android version > 4.

However, there is also a support library which encompasses the other classes you mentioned: FragmentActivity, ActionBarActivity and AppCompat. Originally they were used to support fragments on Android versions < 4, but actually they're also used to backport functionality from newer versions of Android (material design for example).

The latest one is AppCompat, the other 2 are older. The strategy I use is to always use AppCompat, so that the app will be ready in case of backports from future versions of Android.

flower_green
  • 1,314
  • 2
  • 25
  • 30
  • Thank you! OK, so I can use AppCompat in place of Activity in order to host... what? In order to host other AppCompats? Or in order to host FragmentActivities? – Jameson Jul 08 '15 at 15:40
  • An activity normally only host other fragments... And don't worry about FragmentActivity, it's more of a "base" class, which all other fancy XXXActivity derive from. – Mehdi Jul 08 '15 at 15:42
  • But which class should my AppCompat host? Another AppCompat, or something else? – Jameson Jul 08 '15 at 15:43
  • You only have one thing to understand here: activities host fragments. Activities are not hosted by anything else by the way, they cannot be nested. Appcompat is just another kind of activity. After that you can go on and nest fragments, but that begins to be complex to manage. – flower_green Jul 08 '15 at 15:46
  • OK great. Thanks so much. I think I understand now. I'm going to use AppCompat as my "Activity" and host FragmentActivities. Right? – Jameson Jul 08 '15 at 15:50
  • 1
    No, you use appcompat as an activity and you host fragments, not fragmentactivities. – flower_green Jul 13 '15 at 19:02
3

Since the name is likely to change in future versions of Android (currently the latest is AppCompatActivity but it will probably change at some point), I believe a good thing to have is a class Activity that extends AppCompatActivity and then all your activities extend from that one. If tomorrow, they change the name to AppCompatActivity2 for instance you will have to change it just in one place.

Vasily Kabunov
  • 6,511
  • 13
  • 49
  • 53
ExpensiveBelly
  • 444
  • 5
  • 8