目录
- Activity的状态
- 几个Activity过程
- 保存和恢复Activity状态
- Activity的四种启动模式
- 接收Activity返回结果
- 使用Activity的技巧
Activity的状态
- Resumed 处于前台用户可与其交互
- Paused 半透明或部分覆盖,不接收用户输入并且无法执行任何代码
- Stopped 完全隐藏不可见,它被视为处于后台无法执行任何代码
几个Activity过程
Activity活动 | 执行的方法 |
---|---|
1. 创建活动 | onCreate onStart onResume |
2. 打开对话框然后关闭对话框 | onPause onResume |
3. 点击Home回到桌面然后重新打开App | onPause onStop onRestart onStart onResume |
4. 点击back回到桌面、屏幕旋转、资源紧张被系统销毁 | onPause onStop onSaveInstanceState onDestroy |
Bundle对象中的key-value pairs保存数据 |
保存和恢复Activity
- 保存Activity状态
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
- 恢复Activity状态
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values for a new instance
}
...
}
Activity的四种启动模式
-
概念
-
task含义
* 一组activity的集合
* 存在于一个称为back stack的数据结构中
* task是可以跨应用的 -
taskAffinity属性
* 这个参数标识了一个Activity所需任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名。
* 我们可以单独指定每一个Activity的taskAffinity属性覆盖默认值
* 一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity。
* 在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个任务。
* taskAffinity属性不对standard和singleTop模式有任何影响 -
Standard 标准模式
- 不加选择的在Activity返回栈中创建Activity
- taskId相同 hashcode不同
- 可以重复创建相同Activity
-
SingleTop 栈顶复用模式
- 复用时调用onNewIntent()方法
- taskId相同,hashcode相同
- 解决在栈顶重复创建相同Activity
- 在一个Task中可以有重复Activity
-
SingleTask 栈内复用模式
- 复用时调用onNewIntent()方法
- 解决在一个Task中重复创建相同Activity的问题
- 一个示例:A->B->A
B启动A时,A成为栈顶活动(OnRestart),B出栈(OnDestroy)。
-
在启动一个singleTask的Activity实例时,如果系统中已经存在这样一个实例,就会将这个实例调度到任务栈的栈顶,并清除它当前所在任务中位于它上面的所有的activity。
-
SingleInstance
- 以singleInstance模式启动的Activity具有全局唯一性,即整个系统中只会存在一个这样的实例
- 以singleInstance模式启动的Activity具有独占性,即它会独自占用一个任务,被他开启的任何activity都会运行在其他任务中(官方文档上的描述为,singleInstance模式的Activity不允许其他Activity和它共存在一个任务中)
- 被singleInstance模式的Activity开启的其他activity,能够开启一个新任务,但不一定开启新的任务,也可能在已有的一个任务中开启
接收Activity返回结果
static final int PICK_CONTACT_REQUEST = 1; // The request code
...
private void pickContact() {
Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
// Do something with the contact here (bigger example below)
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request it is that we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// Get the URI that points to the selected contact
Uri contactUri = data.getData();
// We only need the NUMBER column, because there will be only one row in the result
String[] projection = {Phone.NUMBER};
// Perform the query on the contact to get the NUMBER column
// We don't need a selection or sort order (there's only one result for the given URI)
// CAUTION: The query() method should be called from a separate thread to avoid blocking
// your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
// Consider using CursorLoader to perform the query.
Cursor cursor = getContentResolver()
.query(contactUri, projection, null, null, null);
cursor.moveToFirst();
// Retrieve the phone number from the NUMBER column
int column = cursor.getColumnIndex(Phone.NUMBER);
String number = cursor.getString(column);
// Do something with the phone number...
}
}
}
使用Activity的技巧
- 创建BaseActivity知晓当前是在哪一个活动
- 使用ActivityCollector随时随地退出程序
- 使用actionStart()方法启动活动
Reference