写在前面
最近在学习 android 开发~~(被逼无奈)~~,偶然发现 activity 有两个继承的类,而且不相同,一个是 Activity,另一个则是 AppcompatActivity,这两个类都可以继承来编写活动的逻辑,不过还是有一些微小的差别的,比如对于主题使用的语法不同(踩坑),这里吹一波 Google 的文档,无论什么项目的文档都写得巨详细,对新手的学习也特别友好
差异
最明显的差异就是继承两者的界面不同:
-
继承 Activity 的界面(无 ActionBar):
代码如下
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { String tempData = savedInstanceState.getString("data_key"); } Button startNormalActivity = (Button) findViewById(R.id.start_normal_activity); Button startDialogActivity = (Button) findViewById(R.id.start_dialog_activity); startNormalActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, NormalActivity.class); startActivity(intent); } }); startDialogActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, DialogActivity.class); startActivity(intent); } }); } }
-
继承 AppcompatActivity 的界面(有 ActionBar):
代码如下
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { String tempData = savedInstanceState.getString("data_key"); } Button startNormalActivity = (Button) findViewById(R.id.start_normal_activity); Button startDialogActivity = (Button) findViewById(R.id.start_dialog_activity); startNormalActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, NormalActivity.class); startActivity(intent); } }); startDialogActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, DialogActivity.class); startActivity(intent); } }); } }
对比两段代码可以看出,只有继承的头文件不同,运行出来的界面也不一样,顶部的 ActionBar 在 AS 中只有继承 AppCompatActivity时才会出现(注:在 Eclipse 中继承 Activity 的效果和 AS 中继承 AppCompatActivity 的效果才一样)
去掉 AppCompatActivity 的标题栏
if (getSupportActionBar() != null){
getSupportActionBar().hide();
}
Google 官方 api 文档对于 AppCompatActivity 功能的介绍
贴一段英文的科普回答
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
.
大致意思就是 AppcompatActivity 兼容老版本的新功能,如果你要在老版本系统使用 md 设计风格,就用 AppCompatActivity,如果你不想使用 md,但你又想使用 fragments,那你就用 FragmentActivity,如果你都不想要,那就直接用 Activity,当然由于 AppCompatActivity 又是继承 FragmentActivity 的,所以用 AppCompatActivity 就够了
加载流程的区别
通过分析源码可知,Activity 关于界面的绘制实际上是交给 PhoneWindow 中的 setContentView 实现的,而对于 AppCompatActivity 来说,通过拦截 View 的创建来实现对低版本进行相应的兼容,不执行系统的 onCreateView,而是执行自己的 onCreateView 进行替换所有系统的 View 控件
总结
Activity 和 AppCompatActivity 主要有两点变化
- 主界面带有 ActionBar 的标题栏
- theme 主题只能使用 android:theme=“@style/Theme.AppCompat.(主题)”, 而不能使用 android:style,否则会报错(踩坑警告!!!)