zoukankan      html  css  js  c++  java
  • Fragment、Activity 保存状态

    Activity 保存状态
    1. void onCreate(Bundle savedInstanceState) 
    当Activity被第首次加载时执行。我们新启动一个程序的时候其主窗体的onCreate事件就会被执行。如果Activity被销毁后(onDestroy后),再重新加载进Task时,其onCreate事件也会被重新执行。注意这里的参数 savedInstanceState(Bundle类型是一个键值对集合,大家可以看成是.Net中的Dictionary)是一个很有用的设计,由于前面已经说到的手机应用的特殊性,一个Activity很可能被强制交换到后台(交换到后台就是指该窗体不再对用户可见,但实际上又还是存在于某个Task中的,比如一个新的Activity压入了当前的Task从而“遮盖”住了当前的 Activity,或者用户按了Home键回到桌面,又或者其他重要事件发生导致新的Activity出现在当前Activity之上,比如来电界面),而如果此后用户在一段时间内没有重新查看该窗体(Android通过长按Home键可以选择最近运行的6个程序,或者用户直接再次点击程序的运行图标,如果窗体所在的Task和进程没有被系统销毁,则不用重新加载Process, Task和Task中的Activity,直接重新显示Task顶部的Activity,这就称之为重新查看某个程序的窗体),该窗体连同其所在的Task和Process则可能已经被系统自动销毁了,此时如果再次查看该窗体,则要重新执行 onCreate事件初始化窗体。而这个时候我们可能希望用户继续上次打开该窗体时的操作状态进行操作,而不是一切从头开始。例如用户在编辑短信时突然来电,接完电话后用户又去做了一些其他的事情,比如保存来电号码到联系人,而没有立即回到短信编辑界面,导致了短信编辑界面被销毁,当用户重新进入短信程序时他可能希望继续上次的编辑。这种情况我们就可以覆写Activity的void onSaveInstanceState(Bundle outState)事件,通过向outState中写入一些我们需要在窗体销毁前保存的状态或信息,这样在窗体重新执行onCreate的时候,则会通过 savedInstanceState将之前保存的信息传递进来,此时我们就可以有选择的利用这些信息来初始化窗体,而不是一切从头开始。 2. void onStart() 
    onCreate事件之后执行。或者当前窗体被交换到后台后,在用户重新查看窗体前已经过去了一段时间,窗体已经执行了onStop事件,但是窗体和其所在进程并没有被销毁,用户再次重新查看窗体时会执行onRestart事件,之后会跳过onCreate事件,直接执行窗体的onStart事件。 3. void onResume() 
    onStart事件之后执行。或者当前窗体被交换到后台后,在用户重新查看窗体时,窗体还没有被销毁,也没有执行过onStop事件(窗体还继续存在于Task中),则会跳过窗体的onCreate和onStart事件,直接执行onResume事件。 4. void onPause() 
    窗体被交换到后台时执行。
    5. void onStop() 
    onPause事件之后执行。如果一段时间内用户还没有重新查看该窗体,则该窗体的onStop事件将会被执行;或者用户直接按了Back键,将该窗体从当前Task中移除,也会执行该窗体的onStop事件。 6. void onRestart() 
    onStop事件执行后,如果窗体和其所在的进程没有被系统销毁,此时用户又重新查看该窗体,则会执行窗体的onRestart事件,onRestart事件后会跳过窗体的onCreate事件直接执行onStart事件。 7. void onDestroy() 
    Activity被销毁的时候执行。在窗体的onStop事件之后,如果没有再次查看该窗体,Activity则会被销毁。 

    最后用一个实际的例子来说明Activity的各个生命周期。假设有一个程序由2个Activity A和B组成,A是这个程序的启动界面。当用户启动程序时,Process和默认的Task分别被创建,接着A被压入到当前的Task中,依次执行了 onCreate, onStart, onResume事件被呈现给了用户;此时用户选择A中的某个功能开启界面B,界面B被压入当前Task遮盖住了A,A的onPause事件执行,B的 onCreate, onStart, onResume事件执行,呈现了界面B给用户;用户在界面B操作完成后,使用Back键回到界面A,界面B不再可见,界面B的onPause, onStop, onDestroy执行,A的onResume事件被执行,呈现界面A给用户。此时突然来电,界面A的onPause事件被执行,电话接听界面被呈现给用户,用户接听完电话后,又按了Home键回到桌面,打开另一个程序“联系人”,添加了联系人信息又做了一些其他的操作,此时界面A不再可见,其 onStop事件被执行,但并没有被销毁。此后用户重新从菜单中点击了我们的程序,由于A和其所在的进程和Task并没有被销毁,A的onRestart 和onStart事件被执行,接着A的onResume事件被执行,A又被呈现给了用户。用户这次使用完后,按Back键返回到桌面,A的 onPause, onStop被执行,随后A的onDestroy被执行,由于当前Task中已经没有任何Activity,A所在的Process的重要程度被降到很低,很快A所在的Process被系统结束。 
        
    当一个程序有多个activity时,按back键,上一个activity会退出,怎么配备布置可以不退出?下次启动它时他还是运行的。另有就是主程序,怎么让他在按back键时天然后台?   
    重写返回按钮事件public void onBackPressed()此方法当返回按钮事件出发时,体系会默许调用finish(),你直接return别让体系调用就行,back键后台参考源码home的事件并重写  
    @Override 
    public void onBackPressed() { 
    // 这里处理逻辑代码,该方法仅适用于2.0或更新版的sdk return; }  
    android的手机的back键默认行为是finish处于前台的Activity的即Activity的状态为Destroy状态,再次启动该Activity是从onCreate开始的。 而Home键默认是stop前台的Activity即状态为onStop而不是Destroy,若再次启动它,则是从OnResume开始的,即会保持上次Activityd的状态。 back键也有例外的,按back键不会关闭Activity的,比如播放音乐,按了back键之后仍可以继续播放音乐,这是Music这支ap已经重写了back键的事件处理。 为什么需要Home键和Back键呢?一个使得Activity 为Stop一个使得为Destroy呢?我想原因的原因在于是android也是一个多任务的操作系统,通过Home键切换不同的任务,而通过back关闭任务中的某一个活动。若仔细想想就觉得PC的多任务行为一样的。 详细的解说可以看官方文档,也可以看看这文章:http://www.360doc.com/content/09/1201/15/79031_10135626.shtml还有例子 注意:点击Back键后,activity会先去执行finish(), 然后执行onDestroy(); 在乐phone的手机上开发应用,它的左上角有一个“返回”按钮, 如果想在返回后把一些东西销毁掉,可以重写finish()方法。  
    http://blog.csdn.net/sirdonker/archive/2010/06/04/5647625.aspx   Android Activity导航   
    http://www.cnblogs.com/xirihanlin/archive/2009/08/05/1539420.html  Android 保存Activity状态  
    http://dev.10086.cn/cmdn/wiki/index.php?edition-view-6259-1.html  (onsaceInstance)  
    http://cnitcastsdut.blog.163.com/blog/static/14601809320109261141571/ 
    Android 保存Activity状态 
    如果你想保存Activity的信息(例如,类实例的变量)而又不需要和其它的组件共享的话,你可以调用Activity的getPreferences方法,不用指定一个Preference的名字。对返回的SharedPreference的访问只限于调用的Activity;每个Activity支持一个不命名的Shared Preference对象。 
    1、使用Activity的私有Shared Preference:  
    对于保存Activity实例的变量来说,Android提供了一种替代Shared Preference的特殊方法。   
    通过重写Activity的onSaveInstanceState事件处理函数,你可以使用它的Bundle参数来保存实例的值。保存数据的方法还是使用与在Shared Preference中相同的get和put方法。在完成Bundle的修改后,将其传入父类的处理函数中,如下面的代码片段所示:   
    private static final String TEXTVIEW_STATE_KEY = “TEXTVIEW_STATE_KEY”; @Override 
    public void onSaveInstanceState(Bundle outState) { // Retrieve the View 
    TextView myTextView = (TextView)findViewById(R.id.myTextView);   
    // Save its state 
    outState.putString(TEXTVIEW_STATE_KEY, myTextView.getText().toString());   
    super.onSaveInstanceState(outState); } 


    2、onSaveInstanceState 
    /**   * 保存Activity销毁前的一些状态信息   * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)   */  @Override 
      public void onSaveInstanceState(Bundle outState){    super.onSaveInstanceState(outState);    outState.putString("fileName", fileName); 


    这个处理函数会在Activity的Active生命周期结束时触发,但仅在它不是显式地结束(即异常结束)。因此,它一般用于确保在单个用户会话中的Active生命周期间Activity状态的一致性。   
    如果一个会话期间,应用程序被迫重启,那么,保存的Bundle会传入到onRestoreInstanceState和onCreate方法中。下面的片段显示了如何从Bundle中提取值来更新Activity实例的状态:   
    @Override 
    public void onCreate(Bundle icicle) { super.onCreate(icicle); 
    setContentView(R.layout.main); 
    TextView myTextView = (TextView)findViewById(R.id.myTextView); String text = “”; 
    if (icicle != null && icicle.containsKey(TEXTVIEW_STATE_KEY)) text = icicle.getString(TEXTVIEW_STATE_KEY); myTextView.setText(text); }   
    有一点很重要的是,记住onSaveInstanceState仅在Activity变成非Active状态时调用,但不在调用finish来关闭它或用户按下Back按钮时调用。



    Fragment 保存状态

    Fragment是activity的界面中的一部分或一种行为。你可以把多个Fragment们组合到一个activity中来创建一个多面界面并且你可以在多个activity中重用一个Fragment。你可以把Fragment认为模块化的一段activity,它具有自己的生命周期,接收它自己的事件,并可以在activity运行时被添加或删除。

    Fragment不能独立存在,它必须嵌入到activity中,而且Fragment的生命周期直接受所在的activity的影响。例如:当activity暂停时,它拥有的所有的Fragment们都暂停了,当activity销毁时,它拥有的所有Fragment们都被销毁。然而,当activity运行时(在onResume()之后,onPause()之前),你可以单独地操作每个Fragment,比如添加或删除它们。当你在执行上述针对Fragment的事务时,你可以将事务添加到一个棧中,这个栈被activity管理,栈中的每一条都是一个Fragment的一次事务。有了这个栈,就可以反向执行Fragment的事务,这样就可以在Fragment级支持“返回”键(向后导航)。

    当向activity中添加一个Fragment时,它须置于ViewGroup控件中,并且需定义Fragment自己的界面。你可以在layoutxml文件中声明Fragment,元素为:<fragment>;也可以在代码中创建Fragment,然后把它加入到ViewGroup控件中。然而,Fragment不一定非要放在activity的界面中,它可以隐藏在后台为actvitiy工作。

    接下来讲如何使用fragment,包括fragment在加入activity的后退棧中时如何保持自己的状态,如何与activity以及其它fragment们共享事件,如何显示在activity的动作栏,等等。

     

    Android从3.0开始引入fragment,主要是为了支持更动态更灵活的界面设计,比如在平板上的应用。平板机上拥有比手机更大的屏幕空间来组合和交互界面组件们。Fragment使你在做那样的设计时,不需应付view树中复杂的变化。通过把activity的layout分成fragment,你可以在activity运行时改变它的样子,并且可以在activity的后退栈中保存这些改变。

     

    其实Fragment在SDK1.6之后就可以使用了,在1.6上使用需要借助 android-support-v4.jar包实现。android-support-v4.jar在:SDK根目录extrasandroid compatibilityv4下可以找到,如果想了解Fragment在SDK1.6上怎么实现的请参考Fragment 在Android SDK1.6上实现

     

    http://blog.csdn.net/lilu_leo/article/details/7671533这个帖子讲的很清楚

    我在项目中也碰到了不能保存Fragment状态用到时隐藏和显示!

    杭州ios交流群  372471379      杭州android交流群:369469730

  • 相关阅读:
    LeetCode 461. Hamming Distance
    LeetCode 442. Find All Duplicates in an Array
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode Find the Difference
    LeetCode 415. Add Strings
    LeetCode 445. Add Two Numbers II
    LeetCode 438. Find All Anagrams in a String
    LeetCode 463. Island Perimeter
    LeetCode 362. Design Hit Counter
    LeetCode 359. Logger Rate Limiter
  • 原文地址:https://www.cnblogs.com/xishui2011/p/3916434.html
Copyright © 2011-2022 走看看