Activity在我们开发中就是一个界面的载体,各种各样的应用都是通过Activity加载显示的。
一、单个Activity的生命周期
在Android Developer文档中有个图片描述了Activity具体的生命周期。
当Activity的onResume()方法执行完成之后,我们就可以看到这个界面了,整个Activity处于一个可见的状态。
onPause()方法使当前的Activity处于暂停的状态。
onStop()方法被调用后整个Activity处于隐藏的状态。
onDestroy()方法调用后Activity就从界面中消失掉了,一般在onDestroy方法中做一些收尾的工作
一个Activity从创建到销毁经历的方法:
显示状态的方法:onCreate、onStart、onResume
看不见状态的方法:onPause、onStop
销毁状态的方法:onDestory
二、多个Activity交互的生命周期
MainActivity启动后:
在MainActivity中有个Button按钮,点击后会跳转到SecondActivity
后台生命周期的方法调用:
首先执行了MainActivity的onPause方法,就把当前Activity的状态置为暂停状态,然后执行打开的SecondActivity的onCreate、onStart、onResume方法,当第二个Activity打开完成之后再去执行MainActivity的onStop方法,把MainActivity置为不可见状态。当前显示的是SecondActivity,但是它的背后还有个MainActivity。
当点击back键后,生命周期方法的调用:
当要显示的Activity属于隐藏的状态的时候,那么它会执行onRestart,而不是onCreate方法。
那Android为什么这么设计Activity生命周期的交互,为什么要先暂停当前显示的Activity?为什么在打开新的Activity的时候,不是先执行当前Activity的onPause,onStop方法,而是执行要打开的新的Activity的onCreate、onStart、onResume?
首先要不是先暂停当前Activity,如果当前Activity正在播放声音或视频,这时打开了一个新的Activity,在新Activity画面已经出现的时候,上个Activity的声音还在,这样就会给用户非常不好的感觉。再则,先执行当前Activity的onPause、onStop方法,这时google提供的一种安全保护机制,如果在启动一个Activity的时候出现了异常导致Activity界面的闪退,这时如果按照先onStop的话,那Activity就会处于不可见的状态,这时再打开的新Activity又因为异常闪退,那这时留给用户的就是黑屏状态了。
三、Activity横竖屏切换
Activity启动时调用的生命周期方法
横竖屏切换时调用额方法:
可以看出切换的时候是把Activity销毁后再新建一个,在这样的情况下,在处理横竖屏切换的时候不得不对Activity相关的状态进行保存,onSaveInstanceState方法是整个Activity销毁的时候提供给我们去保存一些当前的状态信息。
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("name", "nate");
Log.i(TAG, "MainActivity onSaveInstanceState");
}
在Activity销毁前可以把信息保存在Bundle中。存储在系统中的值怎么拿取出来呢?
我们可以在onCreate方法的Bundle参数中获取。可以判断这个参数是否为空,如果不为空获取其中的值
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG, "MainActivity onCreate");
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(this);
textview = (TextView) findViewById(R.id.textview);
if (savedInstanceState != null) {
textview.setText(savedInstanceState.getString("name"));
}
mediaPlayer = MediaPlayer.create(this, R.raw.sing);
mediaPlayer.start();
}
直接启动
一般在项目中启动自己的Activity都是通过这种直接启动方式,根据Activity的名字就可以拿到要启动的Activity。
//显示启动1
Intent intent = new Intent(this, FourActivity.class);
//显示启动2
Intent intent = new Intent();
ComponentName comonent = new ComponentName(this, FourActivity.class);
intent.setComponent(comonent);
匿名启动
比如想去启动别的app的Activity,我们不可能知道别的app的Activity的具体名字,那就只能通过另外一种方式,通过action具体的去启动Activity。
如果要隐式启动一个Activity,那么这个Activity要在Manifest文件中配置了action。
Category属性用于指定当前动作(Action)被执行的环境
<span style="white-space:pre"> </span><activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="www.imooc.com"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
//隐式启动
Intent intent = new Intent();
intent.setAction("www.imooc.com");
五、打开系统常见的Activity
//打开系统浏览器
intent.setAction(Intent.ACTION_VIEW);
Uri url = Uri.parse("http://www.imooc.com");
intent.setData(url);
//打开系统相册
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
//发送短信
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "I am a boy!");
//打开电话界面
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("tel:123456"));
startActivity(intent);