AndroidTraining学习------Managing-the-Activity-Lifecycle

Managing the Activity Lifecycle

当一个用户进入,退出以及回到我们的app时,Activity实例会在生命周期的不同状态间切换。例如,当我们的Activity第一次启动时,它来到系统的前台并接受用户的焦点。在这个过程中,Android系统在Activity上调用了一系列的生命周期方法,你可以设置用户界面或其他组件。如果用户执行了启动另一个Activity或切换到其他的app的操作,当Activity移动到后台时,Android系统又会调用一系列的生命周期方法(这时虽然activity不可见,但是实例和它的状态仍然存在)。
在生命周期回调方法中,我们可以声明用户在离开和重新进入activity时所要执行的操作。比如,如果你建立了一个streaming video player,当你切换到另一个app时,你也许会暂停视频并关闭网络连接。当用户返回时,可以重新连接网络并在相同的位置恢复播放。

Starting an Activity

不同于其他的编程范式,Android系统通过特定生命周期阶段的特定回调方法来执行代码。系统中有一套启动和销毁activity的回调方法。

Understand the Lifecycle Callbacks

在activity的生命周期中,系统会像金字塔一样调用一系列核心的生命周期方法。activity生命周期中的每一个阶段就是金字塔中的一个阶梯当系统创建一个activity实例,每个生命周期方法都会向上移动一阶activity的状态。处于金字塔的顶端意味着activity正在前台运行并且用户可以与之交互。
当用户离开activity,为了回收activity,系统会调用其他的方法来向下一阶梯移动activity的状态。在某些情况下,activity会隐藏在金字塔下等待,(比如当用户切换到其他的app),此时activity可以重新回到顶端(如果用户回到这个app)并且恢复离开时的状态。
activity_lifecycle.png
Figure 1.一个activity生命周期的简单图例,表现为一个金字塔模型。这里显示了每个回调方法是如何一步步将activity移动到最顶端的Resumed状态,回调方法如何将activity向下移动。activity可以从Paused和Stopped状态回到Resumed状态。
根据activity的复杂程度,我们也许不需要实现所有的生命周期方法。但是,理解每一个回调方法并实现,以确保如同用户期望那样执行是非常重要的。实现合适的回调方法确保我们的app操作良好,需要注意以下几点:
* 当用户使用你的app时,如果接到电话或者切换到另一个app,不能产生冲突。
* 当用户没有激活某个组件时不会消耗宝贵的系统资源。
* 离开app并且过很长一段时间返回,用户的进度不会丢失。
* 当屏幕在横屏和竖屏之间旋转时,用户的进度不会发生冲突和丢失。
在接下来的课程中我们将学习到在图1中所示的一个activity在不同状态中切换的情况。然而,只有三个状态是静态的。activity可以在这三个状态中存在比较长的时间:
Resumed:该状态下,activity处于前台,用户可以和它交互(有时候也可以理解为“Running”状态)。
Paused:在该状态下,被其他activity部分掩盖,其他activity处于前台,但是是半透明的或者没有覆盖整个屏幕。paused activity不能接受用户的输入也不能执行任何代码。
Stopped:在该状态下,activity被完全隐藏且对用户不可见;它被认为是处于后台。当activity停止时,activity实例和它所有的信息比如成员变量都会保留,但是不能执行任何代码。
其他的回调方法(Created and Started)是瞬间的,系统会通过调用下一个生命周期回调方法快速的从这些状态移动到下一状态。在系统调用onCreated()之后,将会迅速的调用onStarted()方法,然后再迅速调用onResumed()方法。
这就是activity的基本生命周期。

Specify Your App’s Launcher Activity

当用户在主屏幕上选择我们的app图标,系统会调用被声明为”launcher”(or “main”)activity中的onCreated()方法。这个activity被用作app用户界面的主进入点。
我们可以在Android manifest文件,AndroidManifest.xml中定义作为主activity的activity。
我们必须在manifest中使用包括MAIN action和LAUNCHER category的标签来声明,例如:

  <activity android:name=".MainActivity">    
      <intent-filter>        
          <action android:name="android.intent.action.MAIN" />              
          <category android:name="android.intent.category.LAUNCHER" />    
      </intent-filter>
  </activity>

Note:当你使用Android SDK Tools创建一个新的Android project时,这个默认的project文件中就包含声明了这个filter的manifest文件。
如果activity中既没有定义MAIN action 也没有定义LAUNCHER category,那么我们的app图标将不会出现在主屏幕的app列表中。

Create a New Instance

大多数的app包括多个activity,使用户可以执行不同的操作。不论这个activity是当用户点击app图标是创建的main activity还是为了用户操作的其他activity,系统通过调用onCreated()方法创建每个新的Activity实例。
我们必须实现onCreated()方法来执行应用启动的基本逻辑,这个动作在整个activity生命周期中只发生一次。例如,我们实现onCreated()方法需要定义用户界面和实例化类成员变量。
例如,下面的onCreated()例子展示了执行activity创建的基本操作的一些代码,比如定义用户界面(定义一个XML layout 文件),定义成员变量,配置UI等。

  TextView mTextView;//Member variable for text view in the layout

  @Override
  protected void onCreate(Bundle savedInstanceState) {   
      super.onCreate(savedInstanceState);    

      //Set the user interface layout for this activity    
      //The layout file is defined in the project res/layout/main_acttivity.xml file    
      setContentView(R.layout.activity_main);    

      //Initialize member TextView so we can manipulate it later      
      mTextView = (TextView) findViewById(R.id.text_message);    

      //Make sure we're running on Honeycomb or higher to use ActionBar APIs    
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {        
          //For the main activity, make sure the app icon in the action bar         //does not behave as a button        
          ActionBar actionBar = getSupportActionBar();             
          actionBar.setHomeButtonEnabled(false);

Caution:使用SDK_INT可以避免旧版本的系统调用只在Android2.0或更高版本上才有效的API。旧版本系统调用这些方法会抛出一个异常。
一旦onCreated()方法执行完毕,系统会迅速的调用onStart()方法和onResume()方法。我们的activity从来不会驻留在Created和Started状态。严格的来说,当onStart()被调用时,activity是可见的,但是紧接着onResume(()方法迅速被调用,activity保持Resumed状态直到一些因素的发生才会改变这个状态,比如,接收到一个来电,用户切换到另一个应用或者是设备屏幕关闭。
在后面的课程中,我们将看到其他的方法是如何使用的,onStart()和onResume()方法在activity从Paused或Stopped状态恢复时是非常有用的。
Note:onCreated()包含一个参数savedInstanceState,将会在后面的课程–重建activity中提及。
搜狗截图20160903194548.png
Figure 2:上图强调了生命周期结构图中,在创建activity时系统调用的三个主要方法:onCreate(),onStart()和onResume()。一旦这一系列方法执行完毕,activity就会达到Resumed状态,在这个状态用户可以和activity交互,直到用户切换到不同的activity。

Destroy the Activity

activity的第一个生命周期回调方法是onCreate(),它的最后一个回调方法是onDestroy()。当系统接收到需要将activity从系统内存中彻底移除的信号是,系统将会调用此方法。
大多数的app不需要实现该方法,因为局部类的引用将会随着activity的销毁而销毁,并且我们的activity应该在onPause()和onStop()方法中执行许多资源清理的操作。然而,如果activity中包含在调用onCreate()创建的后台线程或可能导致内存泄漏的长时间运行的资源,如果我们没有及时关闭,就应该在onDestroy()方法中杀死。

  @Override
  protected void onDestroy() {    
      super.onDestroy(); //Always call superclass    

      //Stop method tracing that the activity started during onCreate()       
      android.os.Debug.stopMethodTracing();
  }

Note:通常系统在调用了onPause()和onStop()方法后调用onDestroy()方法,除非你在onCreate()中调用了finish()方法。在某些情况下,例如我们的activity做了一个临时的逻辑跳转功能,它只是用来决定跳转到哪个activity上。在这种情况下,系统就会直接调用onDestroy()方法而跳过其他的生命周期方法。

Pausing and Resuming an Activity

在正常使用app时,前台activity被某些可见的组件阻塞了,导致activity进入了pause状态。例如,当打开一个半透明的activity(比如以对话框的形式)时,以前的activity将会pause。只要之前的activity保持部分可见,那么activity就会一直暂停下去。
然而,一旦activity完全阻塞或者不可见,那么它就会stop。
当我们的activity进入pause状态,系统会调用onPause()方法,它允许我们停止在暂停状态不应该执行的操作(比如播放视频),或者保存应该被保存的任何信息,以防止用户退出app。如果用户从pause状态回到activity,系统将会恢复activity并调用onResume()方法。
Note:当我们的activity接收到一个调用onPause()方法的信号,这表明activity将会pause一段时间,并且用户很有可能回到我们的activity。然而,这也是用户离开activity的第一信号。
Activity生命周期图.png
Figure 1.:当一个半透明的activity阻塞了我们的activity,系统将会调用onPause()方法,activity在pause状态中等待。如果用户在pause状态中回到activity,系统将会调用onResumed方法。

Pause Your Activity

当系统调用activity中的onPause()方法时,从技术上来讲,意味着activity仍处在部分可见的状态,但更多时候意味着用户正在离开activity,并且activity会马上进入Stopped状态。我们通常使用onPause()方法来完成以下事项:
* 停止动画或者那些会消耗CPU的正在进行的动作。
* 提交在用户离开时未保存的修改内容,但是只有用户希望永久保存的内容(比如邮件草稿)
* 释放系统资源,比如广播接收器,传感器(比如GPS),或者任何在activity暂停和用户不需要时会影响电池寿命的资源。

例如,我们的应用使用了相机,onPause()方法是一个释放相机资源的好地方。

@override
public void onPause(){
    super.onPause(); //Always call the supeclass method first

    //Release the Camera because we don't need it when paused
    //and other activities might need to use it
    if(mCamera != null) {
        mCamera.release();
        mCamera = null;
     }
}    

通常,我们不应该使用onPause()来将用户改变的数据(比如用户在一个表单中输入的信息)保存到永久存储。仅仅当我们确认用户希望他们改变的数据能够自动保存时(例如正在撰写邮件),我们才把那些数据永久储存。然而,我们应该避免在onPause()中执行CPU-intensive的工作,比如写入数据到database,因为它会导致切换到下一个activity变得缓慢(我们应该把那些heavy-load的操作放到onStop()中)。

如果我们的activity确实要被停止,为了切换的顺畅应该减少在onPause()方法里面的操作。

Note:当我们的activity被暂停,activity实例是驻留在内存中的,并且在activity恢复时重新调用。我们不需要在恢复到Resumed状态的一系列回调方法中重新初始化组件。

Resume Your Activity

当用户从Paused状态中恢复activity,系统调用onResumed()方法。

请注意,每次activity进入前台时,系统都会调用这一方法。包括activity第一次被创建的时候。所以,我们应该实现onResumed()方法去初始化在onPause()中释放的组件以及执行那些activity每次进入Resumed状态都需要初始化的动作(比如开启动画和初始化那些只有在activity获得用户焦点才需要的组件)。

下面的onResumed()例子是和上面的onPause()相对应的的例子,初始化在activity暂停时被释放的相机资源:

@override
public void onResume() {
    super.onResume();  //Always call the superclass method first

    //Get the Camera instance as the activity achieves full user focus
    if(mCamera == null) {
        initializeCamera();  //Local method to handle camera init
    }
}    

Stopping and Restarting an Activity

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值