当前位置:   article > 正文

Activity中使用注解进行状态保存_super.onsaveinstancestate(outstate); //保存销毁之前的数据 o

super.onsaveinstancestate(outstate); //保存销毁之前的数据 outstate.putstring
转载请注明出处: http://blog.csdn.net/allen315410/article/details/43567229

问题描述        

        一般开发中,当调用Activity生命周期方法onPause()和onStop()方法后,Activity的实例并没有被直接销毁,它仍然保存在内存中,Activity里面所有的信息和状态数据都将保存下来,当这个Activity重新回到前台的时候,所有的数据都会得到保留并且可被使用。

       但是在一些特殊情况下,例如设备上装载了“XX大师”“XX助手”等清理内存的工具时,也有可能直接干掉我们后台的Activity,还有一种情况就是当系统的内存不足时,垃圾回收机制被自动回收到我们在之前已经onPause()和onStop()的Activity,这样的话,Activity里面的信息和状态数据都消失了,当重新启动Activity时,就找不到数据。这时,一般情况我们程序员可以在Activity销毁之前将需要保留下来的数据进行本地化保存,SharedPrefence是个不错的选择的,但是这样做起来似乎比较麻烦一点。


一般解决办法

       还有一种方法就是使用Activity里的onSaveInstanceState(Bundle outState)方法里做一些保存数据的工作,onSaveInstanceState(Bundle outState)方法传递一个Bundle对象,我们使用Bundle对象put一些需要保存的数据进去,当我们重新将Activity放到前台工作时,在onCreate()方法中先判断Bundle是否为空,根据判断条件来取舍数据来使用,或者直接重写Activity下的onRestoreInstanceState(Bundle savedInstanceState)方法,在这个方法下取数据。例如:

  1. public class ExampleActivity1 extends Activity {
  2. private String mState;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. if (savedInstanceState != null) {
  7. mState = savedInstanceState.getString("state");
  8. }
  9. }
  10. // Activity被回收前,会调用这个方法,保存数据
  11. @Override
  12. protected void onSaveInstanceState(Bundle outState) {
  13. super.onSaveInstanceState(outState);
  14. outState.putString("state", mState);
  15. }
  16. // 也可以在这个方法里恢复数据
  17. @Override
  18. protected void onRestoreInstanceState(Bundle savedInstanceState) {
  19. super.onRestoreInstanceState(savedInstanceState);
  20. mState = savedInstanceState.getString("state");
  21. }
  22. }

        以上几行简单的代码可以解决Activity状态保存问题,但是有个问题出现了,如果我们需要保存的数据不止一两个一两种数据类型呢?也可以,我们可以不停的putXXX()不同的数据到Bundle中,然后在不停的getXXX()不同的数据出来使用。可行性是没有任何问题的,但是稍微显得有些繁琐啊,下面就是使用注解来简化了这样的一些不必要的重复性的操作,大大简化了源码的书写。


使用注解保存状态信息

       下面是完整的实现代码,不难懂,为了便于在Activity里面使用,要创建一个Activity的基类BaseActivity,在基类中将这些代码写上,以后没创建一个新的Activity实例都要继承BaseActivity,保证每个Activity都有相应的状态信息保存方法。

  1. package com.example.activitystatesave;
  2. import java.io.Serializable;
  3. import java.lang.annotation.Annotation;
  4. import java.lang.annotation.ElementType;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8. import java.lang.reflect.Field;
  9. import android.app.Activity;
  10. import android.os.Bundle;
  11. import android.os.Parcelable;
  12. import android.util.Log;
  13. public class BaseActivity extends Activity {
  14. private final String TAG = "BaseActivity";
  15. @Retention(RetentionPolicy.RUNTIME)
  16. @Target(ElementType.FIELD)
  17. public @interface SavedInstanceState {
  18. }
  19. @Override
  20. protected void onCreate(Bundle savedInstanceState) {
  21. super.onCreate(savedInstanceState);
  22. // 恢复数据
  23. if (savedInstanceState != null) {
  24. restoreInstanceState(savedInstanceState);
  25. }
  26. }
  27. /**
  28. * 保存状态
  29. */
  30. @Override
  31. protected void onSaveInstanceState(Bundle outState) {
  32. Field[] fields = this.getClass().getDeclaredFields();
  33. Field.setAccessible(fields, true);
  34. Annotation[] ans;
  35. for (Field f : fields) {
  36. ans = f.getDeclaredAnnotations();
  37. for (Annotation an : ans) {
  38. if (an instanceof SavedInstanceState) {
  39. try {
  40. Object o = f.get(this);
  41. if (o == null) {
  42. continue;
  43. }
  44. String fieldName = f.getName();
  45. if (o instanceof Integer) {
  46. outState.putInt(fieldName, f.getInt(this));
  47. } else if (o instanceof String) {
  48. outState.putString(fieldName, (String) f.get(this));
  49. } else if (o instanceof Long) {
  50. outState.putLong(fieldName, f.getLong(this));
  51. } else if (o instanceof Short) {
  52. outState.putShort(fieldName, f.getShort(this));
  53. } else if (o instanceof Boolean) {
  54. outState.putBoolean(fieldName, f.getBoolean(this));
  55. } else if (o instanceof Byte) {
  56. outState.putByte(fieldName, f.getByte(this));
  57. } else if (o instanceof Character) {
  58. outState.putChar(fieldName, f.getChar(this));
  59. } else if (o instanceof CharSequence) {
  60. outState.putCharSequence(fieldName, (CharSequence) f.get(this));
  61. } else if (o instanceof Float) {
  62. outState.putFloat(fieldName, f.getFloat(this));
  63. } else if (o instanceof Double) {
  64. outState.putDouble(fieldName, f.getDouble(this));
  65. } else if (o instanceof String[]) {
  66. outState.putStringArray(fieldName, (String[]) f.get(this));
  67. } else if (o instanceof Parcelable) {
  68. outState.putParcelable(fieldName, (Parcelable) f.get(this));
  69. } else if (o instanceof Serializable) {
  70. outState.putSerializable(fieldName, (Serializable) f.get(this));
  71. } else if (o instanceof Bundle) {
  72. outState.putBundle(fieldName, (Bundle) f.get(this));
  73. }
  74. } catch (IllegalArgumentException e) {
  75. Log.e(TAG, e.getMessage());
  76. } catch (IllegalAccessException e) {
  77. Log.e(TAG, e.getMessage());
  78. } catch (Exception e) {
  79. Log.e(TAG, e.getMessage());
  80. }
  81. }
  82. }
  83. }
  84. super.onSaveInstanceState(outState);
  85. }
  86. /**
  87. * 在这里恢复数据
  88. *
  89. * @param savedInstanceState
  90. */
  91. private void restoreInstanceState(Bundle savedInstanceState) {
  92. Field[] fields = this.getClass().getDeclaredFields();
  93. Field.setAccessible(fields, true);
  94. Annotation[] ans;
  95. for (Field f : fields) {
  96. ans = f.getDeclaredAnnotations();
  97. for (Annotation an : ans) {
  98. if (an instanceof SavedInstanceState) {
  99. try {
  100. String fieldName = f.getName();
  101. Class cls = f.getType();
  102. if (cls == int.class || cls == Integer.class) {
  103. f.setInt(this, savedInstanceState.getInt(fieldName));
  104. } else if (String.class.isAssignableFrom(cls)) {
  105. f.set(this, savedInstanceState.getString(fieldName));
  106. } else if (Serializable.class.isAssignableFrom(cls)) {
  107. f.set(this, savedInstanceState.getSerializable(fieldName));
  108. } else if (cls == long.class || cls == Long.class) {
  109. f.setLong(this, savedInstanceState.getLong(fieldName));
  110. } else if (cls == short.class || cls == Short.class) {
  111. f.setShort(this, savedInstanceState.getShort(fieldName));
  112. } else if (cls == boolean.class || cls == Boolean.class) {
  113. f.setBoolean(this, savedInstanceState.getBoolean(fieldName));
  114. } else if (cls == byte.class || cls == Byte.class) {
  115. f.setByte(this, savedInstanceState.getByte(fieldName));
  116. } else if (cls == char.class || cls == Character.class) {
  117. f.setChar(this, savedInstanceState.getChar(fieldName));
  118. } else if (CharSequence.class.isAssignableFrom(cls)) {
  119. f.set(this, savedInstanceState.getCharSequence(fieldName));
  120. } else if (cls == float.class || cls == Float.class) {
  121. f.setFloat(this, savedInstanceState.getFloat(fieldName));
  122. } else if (cls == double.class || cls == Double.class) {
  123. f.setDouble(this, savedInstanceState.getDouble(fieldName));
  124. } else if (String[].class.isAssignableFrom(cls)) {
  125. f.set(this, savedInstanceState.getStringArray(fieldName));
  126. } else if (Parcelable.class.isAssignableFrom(cls)) {
  127. f.set(this, savedInstanceState.getParcelable(fieldName));
  128. } else if (Bundle.class.isAssignableFrom(cls)) {
  129. f.set(this, savedInstanceState.getBundle(fieldName));
  130. }
  131. } catch (IllegalArgumentException e) {
  132. Log.e(TAG, e.getMessage());
  133. } catch (IllegalAccessException e) {
  134. Log.e(TAG, e.getMessage());
  135. } catch (Exception e) {
  136. Log.e(TAG, e.getMessage());
  137. }
  138. }
  139. }
  140. }
  141. }
  142. }

       以上是全部的BaseActivity的源码,使用时创建新的Activity extends BaseActivity,需要哪些成员变量Filed的数据得到保存,就在哪些成员变量Filed上加上这个定义好的注解。关于注解的基础知识,可以先找其他的资料看一下,也可以参考http://blog.csdn.net/allen315410/article/details/16829801,但是这里讲的也特别基础,希望多了解Java注解和反射的,还是去查查其他的资料吧!



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/211405
推荐阅读
相关标签
  

闽ICP备14008679号