前边看了两天理论,今天接着看书上的代码.
生命周期方法编写
这里用到了import android.util.Log
这个类, 使用其中的方法就可以在AS
中显示日志.
随便创建一个项目,添加一个文本输入框EditText
,右侧的Attributes
中,有一个inputType
,点框里前边的小旗子,可以看到有很多预设的输入,这里简单一点,把顶上的预设去掉,就勾一个text
.
然后在MainActivity
中编写一系列生命周期方法:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "StateChange";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate");
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "onRestart");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG, "onSaveInstanceState");
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.i(TAG, "onRestoreInstanceState");
}
}
这其中的onSaveInstanceState
和onRestoreInstanceState
是为了读取和载入数据准备的,当然一会也要看看它们的表现.
生命周期方法与操作的关系
我是直接使用了我的K30S
来启动程序,比用安卓模拟器对于我公司的这台低压本子压力要小好多.而且很方便的是,LogCat
一样可以追踪实机的日志.
启动程序的时候,显示如下:
2021-06-17 11:03:21.685 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onCreate
2021-06-17 11:03:21.704 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onStart
2021-06-17 11:03:21.704 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onResume
参考上一篇的图,程序进入前台状态,依次经过了图里的三个方法.现在切换一下看看.
写到这里的时候,手机自动熄屏了,显示如下:
2021-06-17 11:04:22.106 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onPause
2021-06-17 11:04:22.118 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onStop
2021-06-17 11:04:22.143 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onSaveInstanceState
可以看到由于程序不再被显示,所以调用了onPause
,然后是onStop
,之后给了个机会来保存数据,这个地方顺序显示和图里有所不同,不过反正是给了保存数据的机会.
然后我又按亮屏幕,程序回到前台,日志如下:
2021-06-17 11:04:36.663 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onRestart
2021-06-17 11:04:36.664 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onStart
2021-06-17 11:04:36.665 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onResume
可以看到是符合之前的声明周期方法图的.
由于我的系统是类似于Pixel
的原生系统,我试验进入切换程序的界面,也就是手指从屏幕下方往上滑:
2021-06-17 11:07:35.344 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onPause
2021-06-17 11:07:35.359 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onStop
2021-06-17 11:07:35.359 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onSaveInstanceState
这个就和熄灭屏幕是一样的,所以凡是导致程序不再前台,都有这几个方法.点一下让程序返回前台,则和上边熄屏恢复是一样的.
最后在程序里,从侧边栏采用手势退出程序,可以看到:
2021-06-17 11:09:11.906 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onPause
2021-06-17 11:09:12.452 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onStop
2021-06-17 11:09:12.455 17470-17470/com.ebookfrenzy.androidsample I/StateChange: onDestroy
读取和保存数据
这里有一个很有意思的行为.如果在中间的输入框上输入一些文字,然后切换横屏竖屏,在之前已经知道,横屏和竖屏中间实际上销毁了一次Activity
,但是会发现,输入框中的文字依然被保留了,但是我们并没有编写保存数据的代码,这是为什么呢?
自动保存
实际上,这些安卓通用组件,都可以默认保存自己的状态,在onSaveInstanceState
和onRestoreInstanceState
方法中一开始调用的super
就是对这个功能的支持.可以通过XML
来控制这个功能的开关,比如关闭EditText
的自动保存数据的功能:
<EditText
android:saveEnabled="false"
这样横屏之后就会发现输入框被清空.
Bundle
对象
这个Bundle
对象,其实就可以理解为JSP
里往session
中放数据,只要应用还在,这个Session
就在.
往其中放的数据形式是键值对,键是一个字符串,值可以是基本类型,也可以是一个实现了Parcelable
接口的对象.
这里我们用Bundle
提供的方法来放入和存储数据,修改两个方法如下:
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
EditText text = findViewById(R.id.editText);
outState.putCharSequence("content", text.getText());
Log.i(TAG, "onSaveInstanceState");
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
EditText text = findViewById(R.id.editText);
text.setText(savedInstanceState.getCharSequence("content"));
Log.i(TAG, "onRestoreInstanceState");
}
之后即使保留EditText XML
中的android:saveEnabled="false"
,也依然可以保持数据.
所以有了这两个方法,就可以把程序需要加载和保存的数据,通过这两个方法来操作了.接下来来理解一下View
, View Groups
, Layout
这几个概念.