1.生命周期:
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState);
//未被Destroy的Activity重新可见后会调用onRestart
protected void onRestart();
//onStart描述的是当前Activity是否处于可见的状态
protected void onStart();
//onResume描述的是当前Activity是否处于可以交互的状态
protected void onResume();
//onPause是保证Activity结束时可以执行的最后一个生命周期方法,onPause中不要做耗时操作
protected void onPause();
//onStop在Activity结束时不能被保证执行
protected void onStop();
//onDestroy在Activity结束时不能被保证执行,所以数据存储,回收资源不能完全依赖这个方法,
//可以通过一个标志位来检查并保证资源被正确回收
protected void onDestroy();
}
一个Activity启动另外一个Activity生命周期是这样的:
Activity1 onPause
Activity2 onCreate
Activity2 onStart
Activity2 onResume
Activity1 onStop
具体参考Activity启动过程
2.Activity意外情况:
Activity意外被杀死的情况包括:内存不足
,或屏幕旋转
,检测到系统语言切换
等;
可以通过修改manifest对映Activity的configChanges
属性来禁止横竖屏时重建
横竖屏切换生命周期:
onSaveInstanceState->onPause->onStop->onDestory->onCreate->onStart->onRestoreInstanceState->onResume
public class MainActivity extends Activity {
//这里的Bundle可以为空,只有在非正常启动才非空
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
savedInstanceState.getString("test"); //程序异常终止并恢复后,在这里也能收到备份信息
}
//在意外被杀死时调用
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("test","Hello");
}
//在意外被杀死并自动恢复时调用,这里的Bundle参数一定不为空
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getString("test"); //程序异常终止并恢复后,官方建议在这个方法接收备份信息
}
}
3.启动模式:
<activity android:name=".TestActivity"
android:launchMode="standard"
android:launchMode="singleTop"
android:launchMode="singleTask"
android:launchMode="singleInstance"/>
1.standard标准模式
新启动的Activity进入启动者的Activity栈中;
*ActivityB
*ActivityB ActivityB
ActivityA ----启动ActivityB---> ActivityA
2.singleTop栈顶复用模式
栈顶相同的Activity不重新创建,同时栈顶Activity的onNewIntent
方法被调用;
*ActivityB *ActivityB
ActivityA ----启动ActivityB---> ActivityA
*ActivityA
*ActivityB ActivityB
ActivityA ----启动ActivityA---> ActivityA
3.singleTask栈内复用模式
1)新建的Activity要进入已存在的栈,且Activity在指定的栈中不存在,则简单新建Activity;
*ActivityC
*ActivityB ActivityB
ActivityA ----启动ActivityC---> ActivityA
2)新建的Activity要进入已存在的栈,且Activity在指定的栈中已经存在,则clearTop,并调用onNewIntent
方法
*ActivityC
ActivityB
ActivityA ----启动ActivityA---> *ActivityA
3)新建的Activity要进入不存在的栈,则先创建Activity栈,再新建Activity压入该栈中;
*ActivityC ActivityC
ActivityB ActivityB
ActivityA ----在指定栈启动ActivityD---> ActivityA *ActivityD
4.singleInstance单实例模式
这种模式的Activity启动时会新建一个栈,Activity会独占这个栈;
*ActivityC ActivityC
ActivityB ActivityB
ActivityA ----启动ActivityD---> ActivityA *ActivityD
通过Intent设置启动模式:
intent.addFlags(xxx)
也可以设置Activity的启动模式,通过Intent方式设置优先级高于
manifest文件配置
Intent intent = new Intent(this, TestActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //对应singleTask模式;
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); //对应singleTop模式;
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //添加clearTop效果,不对应某种启动模式
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); //不进入任务栈
startActivity(intent);
任务栈:
任务栈是为了和singleTask启动模式配对使用的,其他启动模式下定义任务栈没有意义;
默认情况下,所有Activity的任务栈的名字是应用的包名,设置任务栈的方式如下:
<activity android:name=".TestActivity"
android:taskAffinity="test" 任意字符串定义一个任务栈
android:launchMode="singleTask"/>
4.获取Activity返回给上一个页面的信息:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
Intent intent = new Intent(this, SecondActivity.class);
startActivityForResult(intent,0);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
}
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent();
intent.putExtra("name", "Tom");
setResult(1, intent);
finish();
}
}
Activity主题:
Activity主题可以在Manifest文件设置:
<application
android:name=".MyApplication"
...>
<activity
android:name=".MainActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
</application>
app.Activity包中的Activity在使用是不需要添加主题,
但是如果使用Appcompat包中的Activity,如果不设置主题,就会发生报错:
Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.