Activity, AppCompatActivity, FragmentActivity, and ActionBarActivity: When to Use Which?
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
.
What's the enhancement of AppCompatActivity over ActionBarActivity?
As Chris wrote, new deprecated version of ActionBarActivity
(the one extending AppCompatActivity
class) is a safe to use backward compatibility class. Its deprecation is just a hint for you asking to use new AppCompatActivity
directly instead. AppCompatActivity
is a new, more generic implementation which uses AppCompatDelegate
class internally.
If you start a new development, then you should rather use new AppCompatActivity
class right away. If you have a chance to update your app, then replace deprecated ActionBarActivity
by the new activity as well. Otherwise you can stay with deprecated activity and there will be no difference in behavior at all.
Regarding AppCompatDelegate
, it allows you to have new tinted widgets in an activity, which is neither AppCompatActivity
nor ActionBarActivity
.
For instance, you inherit an activity from an external library, which, in turn, does not inherit from AppCompatActivity
but you want this activity to have tinted materials widgets (views). To make it happen you need to create an instance of AppCompatDelegate
inside your activity, override methods of that activity like addContentView()
, setContentView()
etc. (see AppCompatDelegate
javadoc for the full list of methods), and inside of those overridden methods forward the calls to the inner AppCompatDelegate
instance. AppCompatDelegate
will do the rest and your "old-fashion" activity will be "materialized".
How to use the new ComponentActivity with ViewBinding and the other old AppCompatActivity components
Simplest solution from top of my head (hopefully it will work for you):
val menuHost: MenuHost = requireActivity() as MenuHost
This example is for fragment but I guess you can easily apply it to activity:
First extend fragment with MenuProvider:
class SomeFragment : SomethingIfYouHave(), MenuProvider { /* Your code */ }
Now in onCreateView:
val menuHost: MenuHost = requireActivity() as MenuHost
menuHost.addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.RESUMED)
Later in code override onCreateMenu and onMenuItemSelected.
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.info_menu, menu)
}
override fun onMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.something-> {
// Do something here
true
}
else -> false
}
}
AppCompatActivity extends FragmentActivity which extends ComponentActivity, why to use ComponentActivity directly?
Please revert it to:
class MainActivity : AppCompatActivity() { /* Your code here */ }
I think your only problem was in this line:
val menuHost: MenuHost = requireActivity() as MenuHost
------------------- UPDATE
*ComponentActivity has all you need for a Compose-only app.
If you need AppCompat APIs, an AndroidView which works with AppCompat or MaterialComponents theme, or you need Fragments then use AppCompatActivity.
- Reference*
You are not using purely ComposeUI, so that is why you need AppCompat and not ComponentActivity.
If you want to use ComponentActivity without AppCompat you need to get rid off supportFragmentManager.
This would go out of the scope but please check ComposeUI Fragments if you want to switch on ComposeUI (I didn't write article).
Difference between extending LifecycleActivity,Activity,ActionbarActivity & AppCompactActivity?
- extending
ActionBarActivity
gives you theActionBar
s functionality on every API level >= 7 - by extending
Activity
you can avoid adding additional projects/libraries to your project but you'll lack theActionBar
on api levels below 11
edit: More details:
ActionBarActivity
is part of the Support Library. Support libraries are used to deliver newer features on older platforms. For example the ActionBar
was introduced in API 11 and is part of the Activity
by default (depending on the theme actually). In contrast there is no ActionBar
on the older platforms. So the support library adds a child class of Activity
(ActionBarActivity
) that provides the ActionBar
's functionality and ui
edit2: Update April 2015 - it looks like the ActionBarActivity
is deprecated in revision 22.1.0
of the Support Library. AppCompatActivity
should be used instead.
edit3: Update Aug 2017 - LifecycleActivity is a LifecycleOwner but:
"Since the Architecture Components are in alpha stage, Fragment and
AppCompatActivity classes cannot implement it (because we cannot add a
dependency from a stable component to an unstable API). Until
Lifecycle is stable, LifecycleActivity and LifecycleFragment classes
are provided for convenience. After the Lifecycles project is
released, support library fragments and activities will implement the
LifecycleOwner interface; LifecycleActivity and LifecycleFragment will
be deprecated at that time."
(copied from the Architecture Components guideline)
Related Topics
How to Disable Mobile Data on Android
Android.View.Inflateexception: Binary Xml File Line #12: Error Inflating Class ≪Unknown≫
Difference Between Adjustresize and Adjustpan in Android
Java.Lang.Runtimeexception: Unable to Instantiate Activity Componentinfo
Runtimeexception: Your Content Must Have a Listview Whose Id Attribute Is 'Android.R.Id.List'
Android Studio Keeps Refusing to Resolve Com.Android.Support:Appcompat-V7:29.0.1
How to Refresh App Upon Shaking the Device
Android Error: Failed to Install *.Apk on Device *: Timeout
How to Change Colors of a Drawable in Android
Android: How to Have Viewpager Wrap_Content
How to Change the Text on the Action Bar
Clear the Entire History Stack and Start a New Activity on Android
How to Crop Circular Area from Bitmap in Android
How to Get the Actionbar Height
List of Android Permissions Normal Permissions and Dangerous Permissions in API 23
How to Customize Snackbar's Layout