Android 常用的状态恢复与保存方案

包含不同类型的状态保存与恢复方案

  1. Activity 的状态恢复与保存方案
  2. Fragment 的状态恢复与保存方案
  3. ListView 的状态恢复与保存方案
  4. RecyclerView 的状态恢复与保存方案

1. Activity 的状态恢复与保存方案

  • onSaveInstanceState() 与 onRestoreInstanceState()

    class MainActivity : AppCompatActivity() {
    private val S_INT_NAME: String="s_int_name"
    private var intValue=10
    private val S_STRING_NAME: String="s_string_name"
    private var stringValue="test"
    //保存状态方法
    override fun onSaveInstanceState(outState: Bundle?) {
        if (outState != null) {
            outState.putInt(S_INT_NAME,intValue)
            outState.putString(S_STRING_NAME,stringValue)
        }
        super.onSaveInstanceState(outState)
    }
    //恢复状态方法
    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        super.onRestoreInstanceState(savedInstanceState)
        if (savedInstanceState != null) {
            intValue=savedInstanceState.getInt(S_INT_NAME)
            stringValue=savedInstanceState.getString(S_STRING_NAME)
        }
    }
    }
    
  • onSaveInstanceState() 默认实现保存 Activity 中 View 的状态

  • onRestoreInstanceState() 相比于onCreate相比,子类可以控制是否需要实现,该方法在初始化之后才会执行


    2. Fragment 的状态恢复与保存方案

  • 方案一、通过 onSaveInstanceState() 与 onCreateView()

    class BlankFragment : Fragment() {
    private val S_NAME_INT="s_name_int"
    private var intValue=10
    override fun onSaveInstanceState(outState: Bundle?) {
        if (outState != null) {
            outState.putInt(S_NAME_INT,intValue)
        }
        super.onSaveInstanceState(outState)
    }
    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        if (savedInstanceState != null) {
            intValue=savedInstanceState.getInt(S_NAME_INT)
        }
        return inflater!!.inflate(R.layout.fragment_blank, container, false)
    }
    }
    

  • 方案二、通过 Fragment 的 Tag 属性``` private val TAG_BLACK_FRAGMENT="tag_black_fragment" private lateinit var blackFragment: BlankFragment override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) findViewById(R.id.button).setOnClickListener { val intent = Intent(this@MainActivity, Main2Activity::class.java) startActivity(intent) } if (savedInstanceState != null){ blackFragment= supportFragmentManager.findFragmentByTag(TAG_BLACK_FRAGMENT) as BlankFragment }else if(blackFragment==null){ blackFragment=BlankFragment.newInstance("param1","param2") } if(blackFragment.isInLayout.not()){ supportFragmentManager.beginTransaction().replace(R.id.fragment_content,blackFragment,TAG_BLACK_FRAGMENT) } }

    
    * * *
    
    

  • 方案三、仅针对Fragment中只有View状态需要保存的情况``` class BlankFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) retainInstance=true } }

  • 使用该方案,使 Fragment 生命周期不受 Activity 影响


3. ListView 的状态恢复与保存方案

class MainActivity : AppCompatActivity() {
    private lateinit var listView:ListView
    private var mListViewState: Parcelable? = null
    private val LIST_STATE="list_stat"
    override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
        mListViewState=listView.onSaveInstanceState()
        if (outState != null) {
            outState.putParcelable(LIST_STATE,mListViewState)
        }
    }
    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        super.onRestoreInstanceState(savedInstanceState)
        if (savedInstanceState != null) {
           mListViewState=savedInstanceState.getParcelable(LIST_STATE)
        }
    }
    override fun onResume() {
        super.onResume()
        loadData(){
            if(mListViewState!=null){
                listView.onRestoreInstanceState(mListViewState)
                mListViewState==null
            }
        }
    }
    // 先通知Adapter数据变化,再恢复ListView状态
    private fun loadData(loadDataFinish:() -> Unit) {
// listView.adapter.setData
        loadDataFinish
    }
}

ListView状态的保存与恢复^1


4. RecyclerView 的状态恢复与保存方案

class MainActivity : AppCompatActivity() {
    private lateinit var listView: RecyclerView
    private var mRecyclerViewState: Parcelable? = null
    private val LIST_STATE = "list_stat"
    override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
        mRecyclerViewState = listView.layoutManager.onSaveInstanceState()
        if (outState != null) {
            outState.putParcelable(LIST_STATE, mRecyclerViewState)
        }
    }
    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        super.onRestoreInstanceState(savedInstanceState)
        if (savedInstanceState != null) {
            mRecyclerViewState = savedInstanceState.getParcelable(LIST_STATE)
        }
    }
    override fun onResume() {
        super.onResume()
        if (mRecyclerViewState != null) {
            listView.layoutManager.onRestoreInstanceState(mRecyclerViewState)
            mRecyclerViewState == null
        }
    }
}

RecyclerView状态的保存与恢复^2