activity的生命周期——第一行代码阅读笔记
1、对话框活动
DialogActivity 的注册代码有些不同,它使用了一个 android:theme 属性,这是用于给当前活动指定主题的,Android 系统内置有很多主题可以选择,当然我们也可以定制自己的主题,而这里@android:style/Theme.Dialog 则毫无疑问是让 DialogActivity 使用对话框式的主题。
2、活动被回收(stop)前保存离线数据
onSaveInstanceState()方法会携带一个 Bundle 类型的参数
活动被回收后,再次进入会再次进入oncreate()方法
在 MainActivity 中添加如下代码就可以将临时数据进行保存:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
String tempData = "Something you just typed";
outState.putString("data_key", tempData);
}
数据是已经保存下来了,那么我们应该在哪里进行恢复呢?其实我们一直使用的 onCreate()方法其实也有一个 Bundle 类型的参数。这个参数在一般情况下都是null,但是当活动被系统回收之前有通过 onSaveInstanceState()方法来保存数据的话,这个参数就会带有之前所保存的全部数据,我们只需要再通过相应的取值方法将数据取出即可。
修改 MainActivity 的 onCreate()方法,如下所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
String tempData = savedInstanceState.getString("data_key");
Log.d(TAG, tempData);
}
……
}
取出值之后再做相应的恢复操作就可以了,比如说将文本内容重新赋值到文本输入框
3、活动启动模式:
活动activity中配置android:launchMode=""
standard
(默认的启动模式)
每次启动都创建该活动的一个新的实例放入栈顶
singleTop
启动时,若发现栈顶已经是该活动,则直接使用不再创建
若该活动不在栈顶,则仍需新建
singleTask
(让某个活动在整个应用程序的上下文中只存在一个实例)
启动时,检查栈中是否有该活动,有则直接使用(onRestart()),并将其上的所有活动出栈(onDestroy())
其他活动onDestory(),该活动onRestart();
singleInstance
(指定为 singleInstance 模式的活动会启用一个新的返回栈来管理这个活动)
场景:程序中的一个活动允许其他活动调用,其他程序和我们的程序共享该活动的实例
每个应用程序都有自己的返回栈,同一活动在不同的返回栈中入栈必然会创建新的实例,该模式可以解决这个问题。
该模式下会有一个单独的返回栈来管理这个活动,不论哪个程序来访问这个活动,都公用同一个返回栈。
singleInstance:
按下 Back 键进行返回,你会发现 ThirdActivity 竟然直接返回到了 FirstActivity,再按下 Back 键又会返回到 SecondActivity,再按下 Back 键才会退出程序,这是为什么呢?
其实原理很简单,由于 FirstActivity 和 ThirdActivity 是存放在同一个返回栈里的,当在ThirdActivity 的界面按下 Back 键,ThirdActivity 会从返回栈中出栈,那么 FirstActivity 就成
为了栈顶活动显示在界面上,因此也就出现了从 ThirdActivity 直接返回到 FirstActivity 的情况。然后在 FirstActivity 界面再次按下 Back 键,这时当前的返回栈已经空了,于是就显示了
另一个返回栈的栈顶活动,即 SecondActivity。最后再次按下 Back 键,这时所有返回栈都已经空了,也就自然退出了程序。
Android栈:
1.一个应用程序一般都是由多个activity组成的。
2.任务栈(task stack)(别名back stack后退栈) 记录存放用户开启的activity的。
3.一个应用程序一被开启系统就给他分配一个任务栈,当所有的activity都退出的时候,任务栈就清空了。
4.任务栈的id是一个integer的数据类型 自增长的。
5.在android操作系统里面会存在多个任务栈,一个应用程序一个任务栈。
6.桌面应用和一般的应用程序是一样的,任务栈的行为也是一样。
7.默认情况下, 关闭掉一个应用程序,清空了这个应用程序的任务栈。应用程序的进程还会保留。
Android用栈存放activity
启动一个新的活动,入栈,并处于栈顶。
销毁一个活动时,栈顶活动出栈。
系统总是会显示处于栈顶的活动给用户,即栈顶活动可见。
4、活动状态:
1、运行
一个活动位于栈顶时,这活动处于运行状态。
2、暂停
一个活动不处于栈顶位置,但仍然可见时,这活动处于暂停状态。活动完全存活着。(比如栈顶活动为对话框形式)
3、停止
一个活动不处于栈顶位置,且完全不可见,这活动处于停止状态。(还在栈中)
4、销毁
一个活动从栈中移除后,这活动处于销毁状态。
activity的生存期
1. onCreate()
活动第一次被创建的时候调用,在该方法中完成初始化操作,加载布局、绑定事件等。
2. onStart()
由不可见变为可见的时候调用。(非栈顶到栈顶)
3. onResume()
在活动准备好和用户交互的时候调用。(栈顶)
4. onPause()
准备去启动或恢复另一个活动时调用。
5. onStop()
在活动完全不可见时调用。
6. onDestroy()
在活动被销毁前调用。完成释放内存操作。
7. onRestart()
在活动由停止状态变为运行状态前调用。
除onRestart()外,其他两两对应,活动分为三种生存期:
1. 完整生存期
onCreate()和onDestroy()之间所经历的,就是完整生存期。
2. 可见生存期
onstart()和onStop()之间所经历的,就是可见生存期。
3. 前台生存期
onResume()和onPause()之间所经历的,就是可见生存期。
5、活动跳转
activity1:
传递参数:
Intent intent = new Intent(MainActivity.this , SecondActivity.class);
intent.putExtra("welcome","Hello world !");
intent.putExtra("isTrue",true);
intent.putExtra("int2",11);
//startActivity(intent);
startActivityForResult(intent,1);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
String returnedData = data.getStringExtra("data_return");
Log.d("FirstActivity", returnedData);
}
break;
default:
}
}
activity2:
接收:
Intent intent = getIntent();
String data = intent.getStringExtra("welcome");
回传:
Intent intent = new Intent();
intent.putExtra("data_return", "Hello FirstActivity");
setResult(RESULT_OK, intent);
//在setResult后,要调用finish()销毁当前的Activity,否则无法返回到原来的Activity
finish();
活动跳转的另一方法(启动活动的最佳写法)
可方便知悉需要传递的参数
常规方法:
Intent intent = new Intent(FirstActivity.class,SecondActivity.class);
intent.putExtra("param1",data1);
intent.putExtra("param2",data2);
startActivity(intent);
该方法在SecondActivity中接收参数时,若不了解SecondActivity中需要的参数,就会很不方便。
改良方法:
MainActivity中这样传递参数:
SecondActivity.actionStart(MainActivity.this,"11","22");
SecondActivity中:
public class SecondActivity extends BaseActivity {
/*自定义方法*/
public static void actionStart(Context context,String data1,String data2){
Intent intent = new Intent(context,SecondActivity.class);
intent.putExtra("param1",data1);
intent.putExtra("param2",data2);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
Intent intent = getIntent();
Log.d("SecondActivity","data1:"+intent.getStringExtra("param1")+",data2:"+intent.getStringExtra("param2"));
}
}
6、知晓当前是哪个活动
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);
//在BaseActivity的onCreate()方法中添加:
Log.d("BaseActivity",getClass().getSimpleName());
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
}
然后让 BaseActivity 成为项目中所有活动的父类。
7、随时随地退出程序:
自定义一个活动管理器ActivityCollector
public class ActivityCollector {
private static List ls = new ArrayList();
public static void addActivity(Activity activity){
ls.add(activity);
}
public static void removeActivity(Activity activity){
ls.remove(activity);
}
public static void finishAll(){
for(Activity activity : ls){
if(!activity.isFinishing()){
activity.finish();
}
}
}
}
//BaseActivity中调用:
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Log.d("BaseActivity", getClass().getSimpleName());
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
}
8、全局Context
Android 提供了一个 Application 类,每当应用程序启动的时候,系统就会自动将这个类进行初始化。而我们可以定制一个自己的 Application 类,以便于管理程序内一些全局的状态
信息,比如说全局 Context。
public class MyApplication extends Application {
private static Context context;
@Override
public void onCreate() {
context = getApplicationContext();
}
public static Context getContext() {
return context;
}
}
配置完整包名:
……
获取全局Context使用 MyApplication.getContext() 即可。
9、Intent传递复杂对象
Serializable 方式
//对象序列化:
public class Person implements Serializable{
private String name;
private int age;
//get/set...
}
//传递
Person person = new Person();
person.setName("Tom");
person.setAge(20);
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("person_data", person);
startActivity(intent);
//接收:
Person person = (Person) getIntent().getSerializableExtra("person_data");
Parcelable 方式 Parcelable 方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是
Intent 所支持的数据类型,这样也就实现传递对象的功能了。
public class Person implements Parcelable {
private String name;
private int age;
……
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name); // 写出name
dest.writeInt(age); // 写出age
}
public static final Parcelable.Creator CREATOR = new Parcelable.
Creator() {
@Override
public Person createFromParcel(Parcel source) {
Person person = new Person();
//读取的顺序一定要和刚才写出的顺序完全相同
person.name = source.readString(); // 读取name
person.age = source.readInt(); // 读取age
return person;
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
//接收:
Person person = (Person) getIntent().getParcelableExtra("person_data");
。。。
=================================================================================
面试:
1、什么是Activity
通俗一点说Activity就是一个界面,这个界面里面可以放置各个控件。Activity的界面也是用xml表示,放置在res->layout下面。每生成一个新的Activity后,我们需要在AndroidManifest.xml中注册一下这个Activity。
2、请描述一下Activity的生命周期
onCreate(Bundle savedInstanceState):创建Activity时调用,设置在该方法中,还以Bundle的形式提供对以前存储的任何状态的访问。
onStart():activity变为在屏幕上对用户可见时调用
onResume():activity开始与用户交互时调用(无论是启动还是重新启动一个activity,该方法总是被调用)
onPause():activity被暂停或者收回cpu和其他资源时调用,该方法用于保存活动状态的,也是保护现场,压栈吧
onStop():activity被停止并转为不可见阶段及后续的生命周期事件时调用。
onRestart():重新启动activity时调用,该活动仍在栈中,而不是启动新的activity
onDestroy():activity被完全从系统内存中移除时调用
3、两个Activity之间跳转时必然会执行的是哪几个方法:
onCreate():在activity生命周期开始时调用
onRestoreInstanceState():用来恢复UI状态
onRestart():当activity重新启动时调用
onStart():当activity对用户即将可见时调用
onResume():当activity与用户交互时,绘制界面
onSaveInstanceState():当activity即将移除栈顶保留UI状态时被调用
onPause():暂停当前活动的activity,提交持久数据的改变,停止动画和其他占用CPu资源的东西,由于下一个activity在这个方法返回之前不会resume,所以这个方法的代码执行要快
onStop():activity不再可见时调用
onDestroy():在activity销毁栈时被调用的最后一个方法
4、横竖屏幕切换时候activity的生命周期
①不设置activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,且竖屏时会执行两次
②设置activity的android:configChanges=”orientation"时,切屏还是会调用各个生命周期,切横屏,竖屏时只会执行一次
③设置activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
5、你后台的Activity被系统回收怎么办?
系统会帮我们记录下回收之前Activity的状态,再次调用被回收的Activity就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里面带上参数savedInstanceState,savedInstanceState是一个Bundle对象,基本上可以把它理解为系统帮你维护的一个map对象,使用它可以恢复到回收前的状态
6、如何将一个activity设置为窗口的样式
①在你的style.xml文件中可以新建一如下的类似Dialog的style: