现在的位置: 首页 > 综合 > 正文

Android学习札记36:一个关于onSaveInstanceState ()方法的例子

2018年04月04日 ⁄ 综合 ⁄ 共 2824字 ⁄ 字号 评论关闭

package cn.com.sxp;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class OnrestoreActivity extends Activity {
	private static final String TAG = OnrestoreActivity.class.getSimpleName();

	private int count = 0;
	private boolean thread;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (null != savedInstanceState) {
			int preSavedInt = savedInstanceState.getInt("preSavedInt");
			String preSavedStr = savedInstanceState.getString("preSavedStr");
			Log.e(TAG, "onCreate we get prior preSavedInt is: " + preSavedInt
				+ " and preSavedStr is: " + preSavedStr);
		}

		setContentView(R.layout.main);
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					if (!thread) {
						Log.v(TAG, Boolean.toString(thread));
						try {
							Thread.sleep(1000);
						} catch (Exception e) {
							e.printStackTrace();
						}
						count++;
						Log.v(TAG, "count : " + count);
					}
				}
			}
		}).start();
	}

	// 为了防止万一程序被销毁的风险,这个方法可以保证重要数据的正确性
	// 不写这个方法并不意味着一定出错,但是一旦遇到了一些非常奇怪的数据问题的时候
	// 可以看看是不是由于某些重要的数据没有保存,在程序被销毁时被重置
	@Override
	public void onSaveInstanceState(Bundle savedInstanceState) {
		savedInstanceState.putInt("preSavedInt", count);
		savedInstanceState.putString("preSavedStr", "we are saved in onSaveInstanceState");
		super.onSaveInstanceState(savedInstanceState);
		Log.e(TAG, "onSaveInstanceState");
	}

	@Override
	public void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
		int preCount = savedInstanceState.getInt("preSavedInt");
		String preStr = savedInstanceState.getString("preSavedStr");
		Log.e(TAG, "onRestoreInstanceState we get preCount is: " + preCount + " and preStr is: "
			+ preStr);
	}

	public void onDestroy() {
		super.onDestroy();
		this.thread = true;
	}

	public void onPause() {
		Log.v(TAG, "onPause");
		super.onPause();
		thread = true;
	}

	public void onResume() {
		Log.v(TAG, "onResume");
		super.onResume();
		thread = false;
	}

	public void onStop() {
		Log.v(TAG,"onStop");
		super.onStop();
		this.thread = true;
	}
}


当Activity onResume 时打印日志如下:

此时一切正常,没有调用 onSaveInstanceState() 等方法;就这样我让这个线程跑了30多次,之后做了一个横竖屏切换,发生的日志如下:

可以看到,Activity 即将转入 onPause() 方法,在这之前系统调用了 onSaveInstanceState() 方法,果然啊,系统怕在onPause () 时销毁掉 Activity,所以调用该方法保存一些数据,后面才依次调用 onPause() 和 onStop() 方法。

再看看,切换到竖屏后,Activity 被重新构建,果然此时 Activity 就从之前保存的数据再读出来。onCreate() 方法后又调用了 onRestoreInstanceState() 方法,之后才是正常的其他状态出马,继续恢复起线程的运行。


好了,到这里我手痒,又按下了 Home 键,日志打印如下:


可以看到,与切换到竖屏是一样的效果。

好吧,恢复这个程序的运行吧,日志如下:


继续 onResume()。


很强大。以上事例说明,我本人不想销毁,但是系统由于内存的原因或者其他什么原因不得不销毁,系统还不给我机会让我保存数据?倘若该 Activity 被我主动销毁的话,例如我闲的蛋疼按下 Back 键,这个方法就不会被调用(值得一试)。

    先总结以下几点关于onSaveInstanceState方法被调用的场景:

    1、爷按下 Home 键

        按下后,当然是 Home 界面了,原来的应用程序当然不可见啦,应该是 onStop 状态(以上已经测试);这就危险了,该活动可能被销毁,所以被调用(以上已经测试);

    2、按下电源按键(关闭屏幕显示)

        也就是我要待机了

    3、从一个 Activity 启动第二个 Activity(没有测试)

    4、横竖屏切换(以上已经测试)


那还有一个 onRestoreInstanceState() 方法呢。这个方法调用的前提是,一个 Activity 被创建了(以上已经测试)。因为一个 Activity 被创建后,你哪知道它之前是销毁了还是没有被销毁的。当然啦,如果是被销毁的,那么 onCreate() 与 onRestoreInstanceState() 的 Bundle参数是一个参数吧(已经测试,输出是一样的)。


参考资料:

http://www.cnblogs.com/itblog/archive/2011/12/08/2281266.html






抱歉!评论已关闭.