activity lifecycle

activity在生命周期之间的切换由android系统自动调用相关函数,而不应该手动去调用这些函数,只要重载相关函数即可

logging the activity lifecycle

making log messages

android.util.log类可以将日志信息发送到系统级的日志中心。Log类有多个记录日志的函数,例如:

public static int d(String tag, String msg)

d代表debug,表示日志级别。第一个参数表示日志来源,通常一个常量,通常设为相应的类名。第二个参数即为实际的日志内容
例如在QuizActivity中,

public class QuizActivity extends AppCompatActivity{
  private static final String TAG = "QuizActivity";
}

然后在onCreate()函数中使用Log.d()记录一条日志

@Override
protected void onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);
  Log.d(TAG, "onCreate(Bundle) called");
  setContentView(R.layout.activity_quiz);
  // ...
}

使用同样的方式为其它函数添加日志

@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");
}

你可以在Logcat中查看打印的日志内容

rotation and the activity lifecycle

当旋转手机时,有竖屏变成横屏,我们可以在日志中看到 onPause(), onStop(), onDestroy(), onCreate(), onStart(), onResume() 先后被调用。也就是说在旋转后QuizActivity先被销毁然后再次创建了一个新的实例

device configuration and alternative resource

device configuration就是设备的规格参数表,保存有设备的各种配置信息,包括屏幕方向,分辨率,语言等。 有些参数时不会改变的,如分辨率,但有些会改变,如屏幕方向。所以当配置参数改变时,android会尝试寻找更适合当前配置的资源。 而载入资源/视图等都是在onCreate(Bundle)函数中进行的,所以要先销毁再重新创建activity

create a landscape layout

Project视图中,右键res选择New - Android resource directory在弹出的对话框中
Resource type = layout, Source set = main, qualifiers = Orientation,点击>>
此时对话框改变,Screen orientation = Landscape,确认此时Directory name == layout-land
上面这些操作就是为了创建res/layout-land/文件夹

-land后缀时一个configuration qualifier

res/layout/activity_quiz.xml复制到文件夹res/layout-land中,并做修改
使用FrameLayout代替LinearLayout然后为其它组建添加android:layout_gravity属性进行排版

save data across rotation

可以通过重载下面的函数在旋转时缓存数据

protected void onSaveInstanceState(Bundle outState)

该方法通常会在onPause(), onStop(), onDestroy()之前被调用,数据被缓存在Bundle结构中, 然后在onCreate(Bundle)中被读取。
Bundle是存储字符串键与特定类型值映射关系(键值对)的一种结构, Bundle中只能存储基本数据类型和实现了Seriablizable接口的对象。

首先添加字符串键

public class QuizActivity extends AppCompatActivity{
  private static final String KEY_INDEX = "index";
}

重载onSaveInstanceState()函数将mCurrentIndex的值保存到相应的键中

@Override
protected void onSaveInstanceState(Bundle savedInstanceState){
  super.onSaveInstanceState(savedInstanceState);
  Log.i(TAG, "onSaveInstanceState");
  savedInstanceState.putInt(KEY_INDEX, mCurrentIndex);
}

onCreate(Bundle)中通过键获取缓存的值

@Override
protected void onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);

  if(savedInstanceState != null){
    mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0);
  }
}

运行结果来看lifecycle函数调用顺序:onPause(), onSaveInstanceState(), onStop(), onDestroy().

返回键会调用onDestroy(),而按Home键只会调用onStop()

log level

Log Level Method Notes
ERROR Log.e() Errors
WARNING Log.w() Warnings
INFO Log.i() Informational messages
EDBUG Log.d() Debug output; may be filtered out
VERBOSE Log.v() For development only