总述
活动是应用程序的组件,提供一个让用户可进行交互相关的操作的屏幕。例如,拨打电话,照相,发短信,显示地图。系统分配给每个活动一个窗口,用来绘制它的用户界面。一般窗口会充满屏幕,但也可能比屏幕更小或浮在其它窗口的顶端(用户看到的最外层)。
一个应用程序通常包括许多互相松散的绑定一起的activity(藕合度低)。典型地,有一个activity被特殊的作为‘main’activity,代表用户第一次使用该程序所启动的第一个界面。activity之间可互相跳转(被系统启动),来完成不同的操作指令。每启动一个新的activity,系统则会停止之前的activity,并将其保存到一个栈中(未调用finish()),每次启动都会压入该返回栈,获得用户的聚焦。返回栈遵循“后进先出”原则。因此当用户在当前activity操作完,按back键,当前活动则被销毁,从栈中推出。之前的activity重新获得焦点。
当系统因为启动了一个新活动而停止了一个活动,它的这种状态改变会通过生命周期回调方法来通知。通过状改变状态,活动可执行这些回调方法。每个回调方法提供你实现特定的工作来适应状态的改变。举例:activity stopped时,activity应该释放大量对象(减少内容使用),如网络或数据库连接。当resumes ,你可以重新获取所需资源和恢复中断的指令。这些都是生命周期的一部分。
OnCreate()方法中必须调用setContentView()
实现用户界面(Implementing a user interface)
所有的用户界面(xml)提供一种views-objects 层级机制,通过view传递事件。
在onCreate()中调用setContentView();
Intent.putExtra()内部实现
public Intent putExtra(String name, String[] value) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putStringArray(name, value);
return this;
}
用Bundle来存储, Bundle 实现了Parcelable接口 采取单例模式,ArrayMap<> + 同步机制(synchronized方法)来存储。
startActivity()封装了startActivityForResult();
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
onActivityResult():
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// If the request went well (OK) and the request was PICK_CONTACT_REQUEST
if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
// Perform a query to the contact's content provider for the contact's name
Cursor cursor = getContentResolver().query(data.getData(),
new String[] {Contacts.DISPLAY_NAME}, null, null, null);
if (cursor.moveToFirst()) { // True if the cursor is not empty
int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
String name = cursor.getString(columnIndex);
// Do something with the selected contact's name...
}
}
}
注意必须判断resultCode是否等于Activity.RESULT_OK!
关于销毁activity
提供方法:
- finish():内部最终调用了finishActivity()
if (ActivityManagerNative.getDefault()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
- finishActivity()
官方不建议使用上述方法,可能影响到用户体验。
管理activity生命周期 (Managing the Activity Lifecycle)
If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its finish() method), or simply killing its process. When the activity is opened again (after being finished or killed), it must be created all over.
activity处于paused或者stopped状态时,系统可以为了内存空间通过调用它自身finish()或简单地杀死它的进程来释放它。当这个activity再次被打开,必须被重新创建。
Taken together, these methods define the entire lifecycle of an activity. By implementing these methods, you can monitor three nested loops in the activity lifecycle:
//一些使用规范
- entire lifetime 整个activity生命周期是从onCreate()到onDestroy(),在onCreate()里设置”global” state(全局的状态,如创建线程),onDestroy()里面释放资源(如,终止线程)。
- visible lifetime 可见的生命周期是从onStart()到onStop(),这个时期,一般与用户进行交互。onStart():注册广播监听UI。
onStop():销毁广播。
- foreground lifetime 最前窗口的生命周期,onResume()【运行中】 to onPause()【在设备进入睡眠或有对话框弹出时调用】;
流程图:
各个生命周期方法的使用建议或特性:
1.onCreate()
create views, bind data to lists, and so on. This method is passed a Bundle object containing the activity’s previous state, if that state was captured.
主要用来创建视图,初始化数据绑定到ListView中。还可以恢复之前保存在Bundle的数据(通过Bundle savedInstanceState)。
2.onStart()
if the activity comes to the foreground, or onStop() if it becomes hidden.
调用该方法时,表示activity已经可见.
3.onResume()
Called just before the activity starts interacting with the user. At this point the activity is at the top of the activity stack, with user input going to it.
activity与用户交互时启用,表示正在运行中,activity置于活动桟顶部。
4.onPause()?
Called when the system is about to start resuming another activity. This method is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, and so on. It should do whatever it does very quickly, because the next activity will not be resumed until it returns.
5.onStop()
Called when the activity is no longer visible to the user. This may happen because it is being destroyed, or because another activity (either an existing one or a new one) has been resumed and is covering it.Followed either by onRestart() if the activity is coming back to interact with the user, or by onDestroy() if this activity is going away.
activity完全不可见
6.onDestroy()
Called before the activity is destroyed. This is the final call that the activity will receive. It could be called either because the activity is finishing (someone called finish() on it), or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
isFinishing():If the activity is finishing, returns true; else returns false.
可能为了节省空间,短暂的销毁activity
7.onRestart():
Called after the activity has been stopped, just prior to it being started again.
Always followed by onStart()
保存Activity状态(Saving activity state)
横竖屏切换的Log:
保存机制流程:
Note: There’s no guarantee that onSaveInstanceState() will be called before your activity is destroyed, because there are cases in which it won’t be necessary to save the state (such as when the user leaves your activity using the Back button, because the user is explicitly closing the activity). If the system calls onSaveInstanceState(), it does so before onStop() and possibly before onPause().
Note: Because onSaveInstanceState() is not guaranteed to be called, you should use it only to record the transient state of the activity (the state of the UI)—you should never use it to store persistent data. Instead, you should use onPause() to store persistent data (such as data that should be saved to a database) when the user leaves the activity.
activity协调交互 (Coordinating activities)
This predictable sequence of lifecycle callbacks allows you to manage the transition of information from one activity to another. For example, if you must write to a database when the first activity stops so that the following activity can read it, then you should write to the database during onPause() instead of during onStop().