生命周期管理实例和保存提取数据

生命周期管理实例和保存提取数据

写几个生命周期方法在实机上试验一下

前边看了两天理论,今天接着看书上的代码.

生命周期方法编写

这里用到了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");
    }
}

这其中的onSaveInstanceStateonRestoreInstanceState是为了读取和载入数据准备的,当然一会也要看看它们的表现.

生命周期方法与操作的关系

我是直接使用了我的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,但是会发现,输入框中的文字依然被保留了,但是我们并没有编写保存数据的代码,这是为什么呢?

自动保存

实际上,这些安卓通用组件,都可以默认保存自己的状态,在onSaveInstanceStateonRestoreInstanceState方法中一开始调用的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这几个概念.

LICENSED UNDER CC BY-NC-SA 4.0
Comment