Activity系列之---<Activity中的两大守护>

本文探讨了Android中Activity的onSaveInstanceState和onRestoreInstanceState方法的作用及使用场景,通过实例展示了这两种方法如何帮助保存和恢复瞬时数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家好,又到了今天探讨Activity的时间啦。那么今天要研究些什么内容呢?还记得上一篇博文中小菜提到的一种情形吗?从一个Activity启动了新的Activity,旧的Activity就会转入到后台。这时候如果系统需要释放内存,很有可能把旧的Activity给销毁掉。当时小菜建议大家在onPause这个方法中将持久数据保存起来。那么除了咱们手动去保存一些数据,难道就没有其他办法了吗?系统忽然就把Activity销毁了,难道就一点不为用户考虑?

   其实android系统的开发者早就为我们考虑到这种情形了,并且提供了相应的方法应对这种突如其来的状况。onSaveInstanceState方法就可以在Activity变得“脆弱”时被调用在此期间可以将一些瞬时数据保存起来。而onRestoreInstanceState方法和onCreate方法又可以将这些瞬时数据恢复。所以小菜就称onSaveInstanceStateonRestoreInstanceState 为两大守护。

  肯定有童鞋要问啦:“小菜,你说的是啥啊?啥叫变得脆弱?你就不能说些正常点的词语吗?”其实脆弱一词我也是根据英文直译过来的。那什么时候Activity将变得“脆弱”呢?

比如从一个Activity中启动了一个新的Acitivty,而旧的Activity不确定什么时候会再被运行,它就有可能被系统销毁,这时候它就会变得脆弱。大家还记得我上一篇文章中提到的2种不同的退出方式吗?其中一种是按Home键退出的,这时候的Activity实际上是没有被销毁掉的,这时候的Activity也是有可能被系统销毁掉的,所以它也是“脆弱”的。变得“脆弱”的例子有很多,但是我们只要抓住一点,就基本上能判别系统是否会调用onSaveInstanceState方法,那这一点是什么呢?

  这一点就是,如果系统有可能在“未经你许可”的情况下销毁Activity,都会调用此方法。因为系统对不起你,所以它会给你一个机会补偿你。如果是你自愿要销毁Activity的话,是不会调用onSaveInstanceState方法的,比如你按back键退出,系统就不会去调用这个方法,因为是你明确的要退出。但是如果调用了这个方法它调用的时机有可能是在onStop方法之前或者onPause方法之前。

  “呀,小菜,听你这么一说,我感觉还挺危险的。因为我以前写过的Activity重来都没有实现过这个方法。”

   别着急,androdi系统的几乎所有view都已经默认的实现了onSaveInstanceState方法,你只需要为这些View提供一个ID,剩余的事系统会自动完成。如果没有提供这个ID就不会进行自动的保存和恢复操作了。

  “那你说个P啊,害我瞎着急,别急别急,当你需要保存额外的数据时,你就应该覆写该方法了。但是记住,该方法只应该存放瞬时数据,而不应该存放持久性数据,因为它不是每次都会被调用。

   那么onRestoreInstanceState方法呢它是什么时候被调用呢?

   onRestoreInstanceState方法被调用的前提一定是Activity的确被销毁了。如果只是有可能被销毁是不会调用这个方法的。例如,当用户按下Home键时,由于此刻的Activity将变得“脆弱”,所以系统会调用onSaveInstanceState方法,但是用户紧接着又回到了Activity中,那么这时候就不会调用onRestoreInstanceState方法。从这我们也可以看出,这两个方面并不一定是成对出现的。

  接下来我们就动手验证一下,这两大守护的启动时机以及如何应用。

1.     创建一个android 项目,取名叫Activity_03,Activity名称为ActivityGuard。

2.     修改布局文件,在布局文件中添加一个可编辑框和一个按钮。

3.     修改ActivityGuard文件。实现咱们Activity的7个回调方法,当然还有我们的onSaveInstanceState方法,onRestoreInstanceState方法。在这些方法中打印一句话。并在onCreate方法中通过findViewById(),去找到我们的可编辑框和按钮。

package edu.activity.viking.test;

 

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

 

public class ActivityGuard extends Activity

{

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState)

    {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        System.out.println("run onCreate");

        //找到可编辑框

        EditText editText=(EditText)findViewById(R.id.edit);

        //找到按钮

        Button jumpButton=(Button)findViewById(R.id.button);

        //为按钮添加监听器

        jumpButton.setOnClickListener(new View.OnClickListener()

        {

 

           public void onClick(View v)

           {

              Intent intent = new Intent();

       intent.setClass(ActivityGuard.this, OtherActivity.class);

              ActivityGuard.this.startActivity(intent);

           }

       

        });

    }

   

    @Override

    protected void onStart()

    {

    System.out.println("run onStart");

    super.onStart();

    }

   

    @Override

    protected void onResume()

    {

    System.out.println("run onResume");

    super.onResume();

    }

   

    @Override

    protected void onRestart()

    {

    System.out.println("run onRestart");

    super.onRestart();

    }

   

    @Override

    protected void onSaveInstanceState(Bundle outState)

    {

    System.out.println("run onSaveInstanceState");

    super.onSaveInstanceState(outState);

    }

   

    @Override

    protected void onRestoreInstanceState(Bundle savedInstanceState)

    {

    System.out.println("run onRestoreInstanceState");

    super.onRestoreInstanceState(savedInstanceState);

    }

   

    @Override

    protected void onPause()

    {

    System.out.println("run onPause");

    super.onPause();

    }

   

    @Override

    protected void onStop()

    {

    System.out.println("run onStop");

    super.onStop();

    }

   

    @Override

    protected void onDestroy()

    {

    System.out.println("run onDestroy");

    super.onDestroy();

    }

}


 

4.    创建一个新的Activity,取名为OtherActivity.在这个新的Activity中我们只使用TextView控件显示一句话。因为只测试旧的Activity所以,新的Activity我只实现它的onCreate方法。

 

好啦,我们现在可以开始验证我们的想法了。

首先我们的看看onSaveInstanceState方法的调用时机。是否在Activity变得脆弱时,系统会自动调用它。

测试步骤:

1.     跳转到新的Activity

2.     按Home键退出

我们可以看到点击跳转按钮以后,旧的Activity运行了,onSaveInstanceState方法。

这是我们按back键后的图,从图中我们可以看到,虽然旧的Activity一度成为脆弱的状态,但是它并没有被销毁,所以当返回的时候也并没有调用onRestoreInstanceState方法。

  我们继续测试,按Home键的情况。

我们可以看到按home键后一样调用了onSaveInstanceState方法.

当又回到Activity时也同样没有调用onRestoreInstanceState方法。

那么什么时候会用到onRestoreInstanceState方法呢?让我们进入下一个测试。

  我们知道手机有横竖屏之分,当它们之间进行切换的时候,系统就会把Activity销毁,这种销毁是未经我们允许的。我们来试试,这个时候会不会调用onSaveInstanceStateonRestoreInstanceState方法。

  为了实现屏幕转换,我们在onResume方法中加入一些代码。

OK,这时候我们再次启动程序。

我们可以看到,执行到onResume方法的时候,屏幕进行了切换,接着就调用了onSaveInstanceState方法,由于屏幕的切换Activity被停止销毁了,切换好以后重新运行了onCreate方法,并且运行了onRestoreInstanceState方法.

  现在我们找到了2个方法同时运行的情况了,前文我们说到,基本上所有的View都默认实现了onSaveInstanceState方法,如果我在编辑框输入了数据,当屏幕切换后,数据是否还存在呢?

  为了进行测试,我们新增加一个按钮,当用户点击这个按钮时,屏幕会进行切换。

这个是布局文件中新添加的按钮。

然后我们将onResume里面的修改屏幕方向的代码移到按钮事件中去。

这时我们来看看,在编辑框中输入了数据,当点击旋转按钮时数据是否仍然存在,如果存在则说明编辑框自己已经默认实现了onSaveInstanceState方法和onRestoreInstanceState方法。

从图中可以看到,编辑框中的数据还是存在的,说明编辑框自己也实现了这2个方法。

  那么接下来,我们完成我们最后一个测试,那就是尝试重写onSaveInstanceState方法和onRestoreInstanceState方法,保存我们的变量。

  为了让大家更好的体会到这2个方法的用途,咱们先把onSaveInstanceState方法中的super.onSaveInstanceState(outState); 这段代码注释起来。

我们在看看编辑框是否还会自动帮我们保存数据。

变换前。

变换后,我们可以看到,就算系统调用了onSaveInstanceState方法也没有把数据保存起来。

  所以,接下来就看我们的啦,自己动手丰衣足食。怎么做呢?咱们在先得到编辑框的内容,然后保存起来,在变换后,在赋值到编辑框就行了,就是这个思路,咱们试试。

先修改onSaveInstanceState方法。

代码很简单,只不过做了一下保存的操作。

咱们再修改onRestoreInstanceState方法。

也就是把刚刚保存的数据提取出来,显示在编辑框。

我们这时再来运行一下程序。

变化前。

变化后。

我们可以看到,数据的确被保存了。当然onRestoreInstanceState方法中的代码放到onCreate方法中也一样可以的噢。我这里就不做演示了,童鞋们可以自己试试。

  那么今天的博文就到这了,因为博文写的时间跨度有点长,所以中间思路可能断了,如果童鞋们觉得我语无伦次的话,那也纯属正常。OK,下一篇博文我们继续深入Activity.我是你们的小菜。88

代码下载地址:http://pan.baidu.com/share/link?shareid=3765&uk=2852626994

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值