3.1 日志跟踪理解Activity生命周期
3.1.1 输出日志信息
Android内部的android.util.log类能够发送日志信息到系统级别的共享日志中心。Log类有好几个日志信息记录方法。本书使用最多的是:
public static int d(String tag, String msg)
d代表着“debug”,表示日志信息的级别。(最后一节有详解)第一个参数表示日志信息的来源,第二个参数表示日志的具体内容。
该方法的第一个参数通常以类名为值得TAG常量传入。
清单3-1 新增一个TAG常量(QuizActivity.java):
private static final String TAG = "QuizActivity"; //新增TAG常量
清单3-2 为onCreate(...)方法添加日志输出代码(QuizActivity.java):
Log.d(TAG, "onCreat(Button) called"); //onCreate()方法日志输出
若Eclipse提示无法识别Log类的错误,则Windows系统使用Ctrl+Shift+O(Mac系统的:Command+Shift+O)进行类包组织导入,选择android.util.Log类。
接下来,继续覆盖其他五个生命周期方法:
清单3-3 覆盖更多生命周期方法(QuizActivity.java):
} //End of onCreate(Bundle)
//继续覆盖五个生命周期
@Override //使用此注解,即要求编译器保证当前类具有准备覆盖的方法
public void onStart() {
super.onStart();
Log.d(TAG, "onStart() called");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause() called");
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume() called");
}
@Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop() called");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy() called");
}
3.1.2 使用LogCat
应用运行时,可以使用LogCat工具来查看日志。
打开LogCat,选择window—show view—other... 。
为方便日志信息的查找,可使用TAG常量过滤日志输出:
可通过LogCat里的QuizActivity看日志信息。
3.2设备旋转与Activity生命周期
设置配置与备选资源
旋转设备会改变设备配置。设备配置是用来描述设备当前状态的一系列特征,这些特征包括:屏幕的方向、屏幕的密度、屏幕的尺寸、键盘类型、底座模式以及语言,等等。
创建水平模式布局
在res目录下创建一个新文件夹layout-land,并将activity_quiz.xml复制到其下。这样,就有了一个水平模式布局以及一个默认布局(竖直模式)。注意,两个布局文件必须具有相同的文件名,这样,它们才能以同一个资源ID被引用。
为与默认的布局文件相区别,需要对水平模式布局文件做出一些修改。
清单3-4 水平模式布局修改(layout-land/activity_quiz.xml):
备注:android:layout_gravity="center_horizontal" (中心—水平)
center,中心,top,顶部,bottom,底部;
horizontal,水平,vertical,垂直。
运行程序,旋转屏幕至水平方位,查看新的布局界面。这不仅仅是一个新的布局界面,也是一个新的QuizActivity。
效果:横竖屏在翻转时,总是会回到第一页:
此时在第二页,
翻转后回到第一页。
3.3 设备旋转前保存数据
为解决设备旋转导致的activity销毁与新建带来的麻烦。
要修正这个缺陷,旋转后新创建的QuizActivity需要知道mCurrentIndex变量的原有值。因此,在设备运行中发生配置变更时,如设备旋转,需采用某种方式保存以前的数据。
一种实现方式:
protected void onSaveInstanceState(Bundle outState)
覆盖onSaveInstanceState(Bundle)方法
通过覆盖onSaveInstanceState(...)方法,将一些数据保存在Bundle中,然后在onCreate(...)方法中取回这些数据。设备旋转时,将采用这种方式保存mCurrentIndex变量值。
清单3-5 新增键-值对的键(QuizActivity.java):
private static final String KEY_INDEX = "index";
清单3-6 覆盖onSaveInstanceState(...)方法(QuizActivity.java):
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log.i(TAG, "onSaveInstanceState");
savedInstanceState.putInt(KEY_INDEX, mCurrentIndex);
}
清单3-7 在onCreate(...)方法中检查存储的bundle信息(QuizActivity.java):
if (savedInstanceState != null) {
mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0);
}
效果:
竖屏第二页,
翻转为横屏,还在第二页,数据保存了。
3.4 再探Activity生命周期
增加一个暂存状态(stashed state)到activity生命周期:
3.5 深入学习:测试onSaveInstanceState(Bundle)方法
(我现在用的是手机测试,所以不需书上的设置)
运行应用,单击主屏幕键,会暂停并停止当前activity,但再打开应用,数据还是保存的。但是,单击后退键,就相当于通知系统“用户不再需要使用当前的activity”,重新打开应用,之前数据已被清除,又重新回到第一页了。
3.6 深入学习:日志记录的级别与方法
使用android.util.Log类记录日志信息,不仅可以控制日志信息内容,还可以控制用来划分信息重要程度的日志级别。
Log Level | Method | 说明 |
ERROR | Log.e(...) | 错误 |
WARNING | Log.w(...) | 警告 |
INFO | Log.i(...) | 信息型消息 |
DEBUG | Log.d(...) | 调试输出:可能被过滤掉 |
VERBOSE | Log.v(...) | 只用于开发 |
所有的日志记录方法都有两种参数签名:string类型的tag参数和msg参数;再加上Throwable实例参数,为应用抛出异常时记录异常信息提供了方便。
两种方法不同参数签名的使用实例:
清单3-8:Android的各种日志记录方式
//Log a message at "debug" log level
Log.d(TAG, "Current question index: " + mCurrentIndex);
TrueFalse question;
try {
question= mQuestionBank[mCurrentIndex];
} catch (ArrayIndexOutOfBoundsException ex) {
// Log a message at "error" log level, along with an exception stack trace
Log.e(TAG, "Index was out of bounds",ex);
}
整体代码链接:《Android编程权威指南》第三章程序