转载请注明出处:https://www.jianshu.com/p/d78c53f4b1b9
前言
部分内容参考Google爸爸的资料:
https://developer.android.google.cn/guide/components/activities?hl=zh-cn
最近由于部门的发展需要,加上就楼主一个一线开发人员,于是乎。惨被HR当做苦力去做技术面试官。在其中楼主发现,一些一两年经验的开发人员对于基础的Android知识不是很了解,所以打算整理一下,面试中一些技术点和面试者对于一些问题自己新颖的看法,希望可以让大家能够升职加薪,走上人生巅峰。。。。
接上上一篇的文章,有喜欢的朋友可以回去查看:
撸撸Android的羊毛(一)----Activity启动模式
本篇将讨论我们面试中经常会被问的问题,Activity的生命周期。
1.什么是Activity
提到Activity,每个做Android开发的程序员都有自己的理解,“展示界面的”,“应用的前端界面”,“功能和展示的实现面”...这里我们直接摘录Google官网对于Activity的定义:
Activity是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话、拍摄照片、发送电子邮件或查看地图等操作。 每个 Activity 都会获得一个用于绘制其用户界面的窗口。窗口通常会充满屏幕,但也可小于屏幕并浮动在其他窗口之上。
2.如何创建Activity
要创建Activity,就必须继承(extends)并实现其子类,这里我们直接使用系统原生的Activity,其他衍生类如FragmentActivity,AppCompatActivity也基本相似。
public class BActivity extends Activity {
long value; // 保存从A传递过来的N值
TextView valueTextView;
TextView running;
TextView result;
long fab;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取到从A传递过来的值
if (getIntent() != null && getIntent().hasExtra("value")) {
value = getIntent().getLongExtra("value", 0);
}
setContentView(R.layout.b_activity);
valueTextView = (TextView) findViewById(R.id.value);
running = (TextView) findViewById(R.id.running);
result = (TextView) findViewById(R.id.result);
// 将获取到的value设置到当前的valueTextView控件上去
valueTextView.setText(value + "");
running.setVisibility(View.VISIBLE);
new MyThread(value).start();
}
}
这需要在onCreate方法中使用setContengtView()方法定义当前Activity使用的界面。然后在AndroidManifest文件<application>下注册Activity
<activity android:name=".BActivity ">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
android:name 属性是唯一必需的属性—它指定 Activity 的类名。应用一旦发布,即不应更改此类名,否则,可能会破坏诸如应用快捷方式等一些功能。
3. Activity 生命周期
3.1 Activity三种存在状态
在讲到Activity的生命周期之前,我们先了解一下Activity的三种存在状态:
继续
此 Activity 位于屏幕前台并具有用户焦点。(有时也将此状态称作“运行中”。)暂停
另一个 Activity 位于屏幕前台并具有用户焦点,但此 Activity 仍可见。也就是说,另一个 Activity 显示在此 Activity 上方,并且该 Activity 部分透明或未覆盖整个屏幕。 暂停的 Activity 处于完全活动状态Activity对象保留在内存中,它保留了所有状态和成员信息,并与窗口管理器保持连接),但在内存极度不足的情况下,可能会被系统终止。停止
该 Activity 被另一个 Activity 完全遮盖(该 Activity 目前位于“后台”)。 已停止的 Activity 同样仍处于活动状态Activity 对象保留在内存中,它保留了所有状态和成员信息,但未与窗口管理器连接)。 不过,它对用户不再可见,在他处需要内存时可能会被系统终止。
如果 Activity 处于暂停或停止状态,系统可通过要求其结束(调用其 finish() 方法)或直接终止其进程,将其从内存中删除。(将其结束或终止后)再次打开 Activity 时,必须重建,也就是会重新调用onCreate方法。
3.2 Activity生命周期方法
Activity的生命周期有七个方法,这里google的网站已经给出一张比较好的参考图:
[图片上传失败...(image-f8198b-1535094868734)]
我们使用一个表格对Activity生命周期中的七个方法做一个总结,并且其中对每一种方法做了更详细的描述,并说明了每一种方法在 Activity 整个生命周期内的位置,包括在方法完成后系统能否终止 Activity。
方法 | 说明 | 是否能事后终止 | 后接 |
---|---|---|---|
onCreate() | 首次创建 Activity 时调用。 您应该在此方法中执行所有正常的静态设置 — 创建视图、将数据绑定到列表等等。 系统向此方法传递一个 Bundle 对象,其中包含 Activity 的上一状态,不过前提是捕获了该状态。始终后接 onStart()。 | 否 | onstart() |
onRestart() | 在 Activity 已停止并即将再次启动前调用。始终后接 onStart() | 否 | onstart() |
onStart() | 在 Activity 即将对用户可见之前调用。如果 Activity 转入前台,则后接 onResume(),如果 Activity 转入隐藏状态,则后接 onStop()。 | 否 | onResume() 或onStop() |
onResume | 在 Activity 即将开始与用户进行交互之前调用。 此时,Activity 处于 Activity 堆栈的顶层,并具有用户输入焦点。始终后接 onPause()。 | 否 | onPause() |
onPause() | 当系统即将开始继续另一个 Activity 时调用。 此方法通常用于确认对持久性数据的未保存更改、停止动画以及其他可能消耗 CPU 的内容,诸如此类。 它应该非常迅速地执行所需操作,因为它返回后,下一个 Activity 才能继续执行。如果 Activity 返回前台,则后接 onResume(),如果 Activity 转入对用户不可见状态,则后接 onStop()。 | 是 | onResume() 或onStop() |
onStop() | 在 Activity 对用户不再可见时调用。如果 Activity 被销毁,或另一个 Activity(一个现有 Activity 或新 Activity)继续执行并将其覆盖,就可能发生这种情况。如果 Activity 恢复与用户的交互,则后接 onRestart(),如果 Activity 被销毁,则后接 onDestroy()。 | 是 | onRestart()或onDestroy() |
onDestory() | 在 Activity 被销毁前调用。这是 Activity 将收到的最后调用。 当 Activity 结束(有人对 Activity 调用了 finish(),或系统为节省空间而暂时销毁该 Activity 实例时,可能会调用它。 您可以通过 isFinishing() 方法区分这两种情形。 | 是 | 无 |
上面的文本对于Activity的生命周期的 7个方法做了一个较为详细的讲解,但是程序员还是采用比较直观的代码展现:
public class FirstActivity extends Activity implements OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("Activity LifeCycle","FirstActivity----->onCreate");
setContentView(R.layout.first_layout);
findViewById(R.id.pause).setOnClickListener(this);
findViewById(R.id.pause_stop).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.pause:
//跳转到一个非全屏的activity 或者一个全透明的activity
Intent intent = new Intent(this, TransparentActivity.class);
startActivity(intent);
break;
case R.id.pause_stop:
Intent intent2 = new Intent(this, SecondActivity.class);
startActivity(intent2);
break;
}
}
@Override
protected void onStart() {
super.onStart();
Log.d("Activity LifeCycle","FirstActivity----->onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.d("Activity LifeCycle","FirstActivity----->onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.d("Activity LifeCycle","FirstActivity----->onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.d("Activity LifeCycle","FirstActivity----->onStop");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d("Activity LifeCycle","FirstActivity----->onRestart");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("Activity LifeCycle","FirstActivity----->onDestroy");
}
}
之后我们会使用该类来实现相应的操作,验证流程。
首先,我们进入该activity,
然后我们查看logcat下的日志
此时activity经过onCreate--->onStart--->onResume,Activity获取到焦点,并展示在界面上。
然后我们点击home键,这时logcat日志如下:
过程中activity经过onPause---->onStop最终是去焦点,并退到后台栈中。
再次启动该界面,logcat展示:
在这过程中activity经过onStart---->onResume 最终获取焦点,展示在界面上。
我们退出该界面,logcat展示如下:
在这过程中activity经过onPause-->onStop--->onDestroy.结合之前的google官方图,能够很好的了解Activity的生命周期
学习的参考项目在我的github下,该项目是我从学习到现在整理的一些常用资料,欢迎大家star
https://github.com/jixiang52002/MyAndroid