撸撸Android的羊毛(二)----Activity生命周期

转载请注明出处:juejin.im/post/5c947a…

前言

部分内容参考Google爸爸的资料: developer.android.google.cn/guide/compo…

最近由于部门的发展需要,加上就楼主一个一线开发人员,于是乎。惨被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文件下注册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的网站已经给出一张比较好的参考图:

acivity的生命周期

我们使用一个表格对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,

image.png
然后我们查看logcat下的日志
image.png
此时activity经过onCreate--->onStart--->onResume,Activity获取到焦点,并展示在界面上。 然后我们点击home键,这时logcat日志如下:
image.png
过程中activity经过onPause---->onStop最终是去焦点,并退到后台栈中。 再次启动该界面,logcat展示:
image.png
在这过程中activity经过onStart---->onResume 最终获取焦点,展示在界面上。 我们退出该界面,logcat展示如下:
image.png
在这过程中activity经过onPause-->onStop--->onDestroy.结合之前的google官方图,能够很好的了解Activity的生命周期

学习的参考项目在我的github下,该项目是我从学习到现在整理的一些常用资料,欢迎大家star github.com/jixiang5200…

猜你喜欢

转载自juejin.im/post/5c947ae25188252db6452880