1.Android生命周期
Android是使用任务栈(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称作返回栈(Back Stack)。栈是一种后进先出的数据结构*(后来者居上)。在默认情况下,每当我们启动了一个新的活动,它会在返回栈中入栈,并处于栈顶的位置。而每当我们按下Back键或调用finish()方法去销毁一个活动时,处于栈顶的活动就会出栈,这时前一个入栈的活动就会重新处于栈顶的位置。系统总是会显示处于栈顶的活动给用户。活动生命周期的四种状态:
①运行状态,当一个活动位于返回栈的栈顶时,这时活动就处于运行状态。系统最不愿意回收的就是处于运行状态的活动,因为这会带来非常差的用户体验。
②暂停状态,当一个活动不再处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态,比如有一些活动以对话框的形式出现,只会占用屏幕中间的部分位置,处于其下仍然可见的活动就是暂停状态,系统也不愿去回收这种状态的活动(活动对于用户仍然是可见的)。
③停止状态:当一个活动不再处于栈顶位置,并且完全不可见的时候就进入了停止状态,当有其他地方需要内存时,处于停止状态的活动有可能会被系统回收。
④销毁状态:当一个活动从返回栈中移除后就变成销毁状态。系统会最倾向于回收这种状态的活动,从而保证手机内存充足。
二、活动生命周期具体分析:Activity类中定义了7个回调方法,覆盖了活动生命周期的每隔环节。
①onCreate(),它会在活动第一次被创建的时候调用。开发者要在这个方法中完成活动的初始化操作,比如说加载布局、绑定时间等。
②onStart(),这个方法在活动由不可见变为可见的时候调用。
③onResume(),这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的栈顶,并且处于运行状态。
④onPause(),这个方法在系统准备去启动或者恢复另一个活动的时候调用。我们通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度一定要快,不然会影响到新的栈顶活动的使用。
⑤onStop(),这个方法在活动完全不可见的手调用。它和onPause方法的主要区别在于,如果启动的新活动是一个对话框式的活动,那么onPause()方法会的得到执行,而onStop()方法并不会执行。
⑥onDestroy(),这个方法在活动被销毁之前调用,之后活动的状态将变成销毁状态。
⑦onRestart(),这个方法在活动活动由停止状态变为运行状态时调用。
以上7个方法除了onRestart()方法之外,都是两两对应的,从而又将活动分为三个生存期。
①完整生存期。活动在onCreate方法和OnDestroy方法之间所经历的,就是完整生存周期。一般情况下,一个活动会在onCreate方法中完成各种初始化操作,而在onDeatroy方法中完成释放内存的操作。
②可见生存期。活动在onStart方法和onStop方法之间所经历的,就是可见生存期。在可见生存期内,活动对于用户总是可见的,即便有可能无法和用户进行交互。我们可以通过这两个方法,合理地管理那些对用户的可见的资源。
③前台生存期。活动在onResume方法和onPause方法之间所经历的就是前台生存期。在前台生存期内,活动总是处于运行状态,此时的活动是可以和用户进行交互的,我们平时看到和接触最多的也就是处于这个状态下的活动。
小结:到这里我们来个小结,当Activity启动时,依次会调用onCreate(),onStart(),onResume(),而当Activity退居后台时(不可见,点击Home或者被新的Activity完全覆盖),onPause()和onStop()会依次被调用。当Activity重新回到前台(从桌面回到原Activity或者被覆盖后又回到原Activity)时,onRestart(),onStart(),onResume()会依次被调用。当Activity退出销毁时(点击back键),onPause(),onStop(),onDestroy()会依次被调用,到此Activity的整个生命周期方法回调完成。
2.Intent启动Activity
要创建并显示一个Activity,可以调用startActivity,并传递给它一个Intent,如下面的代码所示:
startActivity(Intent myIntent);
可以构造Intent来显示地指定要打开的Activity类,或者包含一个目标Activity必须执行的动作。在后一种情况中,运行时将会使用一个称为“Intent解析(Intent resolution)”的过程来动态选择Activity。
3. 多个Activity之间共享数据
Activity之间共享数据有五种方式:
1.基于消息的通信机制 Intent ---boudle ,extra
数据类型有限,比如遇到不可序列化的数据Bitmap,InputStream, 或者LinkList链表等等数据类型就不太好用。
2. 利用static静态数据,public static成员变量,也是可以是一个public类;
3.基于外部存储的传输, File/Preference/ Sqlite ,如果要针对第三方应用需要Content Provider
4.基于IPC的通信机制context 与Service之间的传输,如Activity与Service之间的通信,定义AIDL接口文件。
5. 基于Application Context
本程序是使用一个public类实现数据共
定义一个public类Status用来存储活动状态和显示状态在textview中,该public类定义了Map<String,String>类型的变量mMethodList存储Activity Status , List<String>类型的变量mStatusMap存储日志信息。
构造函数:
private Status() {
mStatusMap = new LinkedHashMap<String, String>();
mMethodList = new ArrayList<String>();
}
用一个getInstance()方法返回该类的一个对象(该对象封装了上述两个变量):
public static Status getInstance() {
return ourInstance;
}
clear()函数用清除mMethodLis和mStatusMap存储的活动状态:
public void clear() {//清除日志表和状态表
mMethodList.clear();
mStatusMap.clear();
}
setStatus()函数用来将当前活动的信息存进mMetodList和mStatusMap:
public void setStatus(String activityName, String status) {
mMethodList.add(activityName + "." + status + "()");
if (mStatusMap.containsKey(activityName)) mStatusMap.remove(activityName);
mStatusMap.put(activityName, status);
}
getStatus()函数用来获取活动状态,并转化为输出格式:
public String getStatus(String activityName) {
String status = mStatusMap.get(activityName);
status = status.substring(2, status.length());//把前面的on去掉
// String manipulation to ensure the status value is spelled correctly.
if (status.endsWith("e")) {
status = status.substring(0, status.length() - 1);//以e结尾直接加d
}
if (status.endsWith("p")) {
status = status + "p";//以p结尾双写p加ed
}
status = status + STATUS_SUFFIX;
return status;
}
由于在当前Activity执行onResume()后,onStop()或onDestroy()才执行而且执行的时间很短,如果在执行onResume()的时候直接显示到TextView会导致onStop或onDestroy()显示不了,所以在显示函数printStatus()中设置一个时间延迟,由图可知时延大概在1.4s左右。该实验将时延设置为2s。
public static void printStatus(final TextView viewMethods, final TextView viewStatus) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
StringBuilder sbMethods = new StringBuilder();
List<String> listMethods = mStatus.getMethodList();
for (String method : listMethods) {
sbMethods.insert(0, method + "\r\n");
}
if(viewMethods != null) {
viewMethods.setText(sbMethods.toString());
}
StringBuilder sbStatus = new StringBuilder();
for (String key : mStatus.keySet()) {
sbStatus.insert(0,key + ": " + mStatus.getStatus(key) + "\n");
}
if(viewStatus != null) {
viewStatus.setText(sbStatus.toString());
}
}
}, 2000);
}
然后在AActivity、BActivity、CActivity中定义Status对象,然后分别在onCreate(),onStart(),onResume(),onPause(),onDestroy()中调用相应函数
3.运行结果截图
启动程序初始化界面
紧接着点击START B按钮后出现的界面
再点击START C按钮后出现界面
然后点击FINISH C按钮出现的界面
最后点击DIALOG出现的界面