关闭

活动生命周期

标签: androidc#visaul studioXamarin
687人阅读 评论(0) 收藏 举报
分类:

 

 

 

活动(Activity)Android应用的一个基础构建组件,它们可以以若干不同的状态存在。活动的生命周期始于实例化而终于销毁,在实例化和销毁之间包括许多状态。当活动的状态发生变化时,一个适当的生命周期事件方法被调用,将即将发生的状态改变通知这个活动并允许它执行代码来适应这种改变。

活动是Android特有的独特的编程概念。在传统的应用开发中,通常都有一个静态主方法,该方法被执行时应用被启动。Android则不同,Android应用能通过任一已注册到应用中的活动来启动。在实践中,大部分应用只有一个明确的活动被指定为应用的入口点,然而,如果应用崩溃或被操作系统中止后,操作系统会试图通过先前活动栈中的最后打开的活动或其它活动来重启应用。此外,当活动处于非活动状态时,操作系统会暂时中止活动,当内存太小时,则会回收它们。必须周详考虑使得应用能在活动被重启的事件中正确恢复其状态,尤其时当活动依赖于来自先前活动的数据时。

活动的生命周期是作为一组方法来实现,操作系统在该活动的生命周期的开始到结束都在调用这些方法。这些方法使开发者实现满足应用的状态和资源管理需要的必备功能。

分析每一个活动的需求来决定哪些被活动暴露的生命周期的方法需要被实现,对于应用开发者来说是极端重要的。这个工作的失败会导致应用不稳定、崩溃、资源膨胀甚至会引起操作系统不稳定。

 

 

 

活动状态

 

活动的状态可划分为如下4个主要的部分:

活动或运行-当活动在前台也即大家所知的处于活动栈的顶部时,活动被认为是激活和运行的,这在Android中被认为是最高优先级的活动,因此只有极端情况下才会被操作系统终结,例如,如果该活动试图使用比设备上有效内存更多的内存时,因为这会引起用户界面变得没有响应。

暂停-当设备进入休眠状态,或一个活动仍然看得见但部分被一个新的非全屏或透明的活动

所隐藏时,这个活动被认为是暂停的。暂停的活动仍然存活,亦即,它们维持所有状态和成员信息,并保持连接到窗口管理器。这在Android中被认为是第二最高优先级的活动,只有当结束这个活动可满足资源需求的需要来保持激活或运行的活动稳定和可响应时,才会被OS结束。

停止/后台化-被其他活动完全掩盖的活动被认为是停止或在后台。被停止的活动仍然试图尽可能长的保持它们的状态和成员信息,但是停止了的活动被认识是三个状态中优先级最后的,操作系统将首先结束处理这一状态的活动来满足更高优先级的活动的资源需求。

重启-对一个活动来说在生命周期中从暂停到停止的任何地方被从内存中移除都是有可能的。如果用户导航回该活动,它必须被重启,恢复到它先前存储的状态,并显示给用户。

 

配置改变响应中的活动重创建

 

配置改变是快速的活动销毁或重建的周期,当一个活动的配置变化时就会发生。例如当设备被旋转时(这时活动需要进行重建于风景或肖像模式),或当键盘被显示(这时活动的展现可有一个调整自身大小的机会),或当设备在其他设备中被放置于停靠状态时。

 .

正在停止或重启活动期间,配置改变仍然会导致相同的活动状态的改变。然而,为了保证应用在配置改变期间保持良好的响应和顺畅的运行,它们被尽可能快地操作是非常重要。

 

活动生命周期方法

 

 

Android SDK和其延伸的Xamarin.Android框架为管理应用中的活动的状态提供强大的模型。当一个活动的状态发生改变时,OS就会通知该活动,该活动调用指定方法。

 

 

 

作为开发者,可以通过重写活动中的这些方法来操控状态改变。然而,重要的是,所有的生命周期方法都是在UI线程上被调用的,而且这些方法将阻止操作系统执行下一个UI工作片段,比如隐藏当前活动、显示新的活动,等等。如此,这些方法中的代码应该尽可能的简短,以使应用被感觉很流畅的运行。任何长时间运行的任务应该在后台线程中运行。

 

让我们分析每个生命周方法和它们的作用:

OnCreate

 

这是活动被创建时第一个被调用的方法。OnCreate总是被重写来执行活动所需的任何启动初始化操作,比如:

l 创建视图

l 初始化变量

l 静态数据绑定到列表

 

OnCreate带有一个Bundle类参数,这是用来在活动之间存储和传递状态信息和对象的字典,如果这个参数为非空,则表明该活动正在重启,该活动应从先前的实例中恢复其状态。下面的代码说明如何从Bundle类参数中取回状态的值。

 

protected override void OnCreate(Bundle bundle)

{

   base.OnCreate(bundle);

 

   string extraString;

   bool extraBool;

 

   if (bundle != null)

   {

      intentString = bundle.GetString("myString");

      intentBool = bundle.GetBoolean("myBool");

   }

 

   // Set our view from the "main" layout resource

   SetContentView(Resource.Layout.Main);

}

 

以下是另外一个例子。

 

 protected override void OnCreate(Bundle bundle)

        {

            base.OnCreate(bundle);

 

            // Set our view from the "main" layout resource

            SetContentView(Resource.Layout.Main);

 

            // Get our button from the layout resource,

            // and attach an event to it

            EditText phoneNumberText = FindViewById<EditText>(Resource.Id.PhoneNumberText);

            Button translateButton = FindViewById<Button>(Resource.Id.TranslateButton);

            Button callButton = FindViewById<Button>(Resource.Id.CallButton);

 

            

 

            callButton.Enabled = false;

                       if (bundle != null)

            {

//translateNumber是类成员级变量,它在OnSaveInstanceState被存储

//这与Winform是不同的,在Winform中,窗体被遮盖时不会调用OnPauseOnStop方法,也不会存在Configuration Change时,窗体会被销毁后重新生成,在安卓中,当Configuration Change时,活动(相当于窗体)将会被销毁后再重建,为了保持前后数据的一致性,应在OnSaveInstanceState对需要的数据进行保存,并在OnCreate中予以恢复//

                translateNumber = bundle.GetString("translateNumber");

                callButton.Text = "Call " + translateNumber;

 

            }

 

            translateButton.Click += (object sender, EventArgs e) =>

              {

                  translateNumber = Core.PhonewordTranslator.ToNumber(phoneNumberText.Text);

                  if (String.IsNullOrWhiteSpace(translateNumber))

                  {

                      callButton.Text = "Call";

                      callButton.Enabled = false;

                  }

                  else

                  {

                      callButton.Text = "Call " + translateNumber;

                      callButton.Enabled = true;

                  }

              };

            callButton.Click += (object sender, EventArgs e) =>

              {

                  var callDialog = new AlertDialog.Builder(this);

                  callDialog.SetMessage("Call " + translateNumber + "?");

                  callDialog.SetNeutralButton("Call", delegate {

                      var callIntent = new Intent(Intent.ActionCall);

                      callIntent.SetData(Android.Net.Uri.Parse("tel:" + translateNumber));

                      StartActivity(callIntent);

                  });

                  callDialog.SetNegativeButton("Cancel", delegate { });

              };

         

        }

 

Once OnCreate has finished, Android will call OnStart.

一旦OnCreate已经完成,Android将调用OnStart方法。

 

OnStart

 

这个方法总是在OnCreate方法结束之后被调用,如果活动需要在变得可见前立即执行诸如刷新视图的当前值等任何指定的任务时,活动可以重写这个方法。在此之后,Android将立即调用OnResume方法。

 

OnResume

当活动准备开始与用户互动时,系统调用这个方法。

活动应用重写这个方法来执行诸如下面的这些任务:

l 加大帧率(游戏生成中的普通任务)

l 开始动画

l 侦听GPS更新

l 显示任何相关警告或对话框

l 接通外部事件操作者

 

 

以下代码片段是显示如何初始化摄像头的例子

public void OnResume()

{

    base.OnResume(); // Always call the superclass first.

 

    if (_camera==null)

    {

        // Do camera initializations here

    }

}

 

OnResume非常重要,任何在OnPause中完成的操作应该在OnResume中被复原,这是由于它是唯一保证在OnPause之后执行以将活动带回运行状态的生命周期方法。

 

OnPause

当系统即将把活动置于后台或活动被部分遮盖时,该方法被调用,如果活动有如下需要,则应该重写这个方法:

l 提交未被存储的变化给持续的数据

l 销毁或清理其它消耗资源的对象

l 降低帧率或暂停动画

l 注销外部事件操作者或通知操作者(也就是那些被连接到一个服务的)。这必须完成来防止活动内存泄漏。

l 同样的,如果活动已经显示任何对话框或警示框,它们必须被Dismissed()方法清除。

 

 

作为一个例子,下面的代码片段将释放摄像头,因为活动在被暂停时不能利用摄像头:

public void OnPause()

{

    base.OnPause(); // Always call the superclass first

 

    // Release the camera as other activities might need it

    if (_camera != null)

    {

        _camera.Release();

        _camera = null;

    }

}

 

有两种生命周期方法可能在OnPause方法后被调用:

1.OnResume将会在活动被返回到前台时被调用。

2.OnStop将会在活动被置于后台时被调用。

 

 

 

 

 

 

OnStop

 

当活动对用户不再可见时该方法被调用,这发生在下列情形之一出现时:

l 一个新的活动正被启动并正遮盖本活动。

l 一个现有的活动正被带到前台。

l 本活动正在被销毁。

 

在低内存时,OnStop不一定总会被调用,比如当Android急需资源而又不能正确地后台化该活动时。由于这个原因,当准备销毁一个活动时,最好不要依赖于OnStop的调用。在调用此方法后,如果活动将退出,则下一个可被调用的生命周期方法将是OnDestroy,如果活动将回到与用户交互,则是OnRestar

 

OnDestroy

 

这是活动实例在被销毁并彻底从内存中移除之前最后调用的方法。在极端情况下Android会结束导致OnDestroy不被调用的活动的宿主应用进程。大部分活动将不会实现这个方法,因为大部分清除和关闭已经在OnPauseOnStop方法中完成了。OnDestroy方法典型地被重写来清除长时间运行的资源,这些资源可能会外泄资源,比如在OnCreate中被启动的一个后台线程。

一个活动已经被销毁之后将没有生命周期方法被调用。

 

OnRestart

 

 

这个方法将在你的活动结束后被再次开始之前被调用,一个很好的例子是用户在应用的一个活动中时按了返回按钮,此后OnPauseOnStop方法被调用,活动被移到后台,但不会被销毁,如果用户接着通过使用任务管理器或类似的应用恢复这个应用,Android将调用这个活动的OnRestart方法。

 

 

对于什么类型的逻辑应该在OnRestart中被实现,没有总的指导原则。这是因为不管活动是正在被创建或正在被重启,OnStart总是会被调用,所以活动所需的任何资源应该在OnStart中被初始化,而不是在OnRestart中。

接下来被调用的方法将是OnStart

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:200863次
    • 积分:2798
    • 等级:
    • 排名:第12798名
    • 原创:71篇
    • 转载:17篇
    • 译文:24篇
    • 评论:9条
    最新评论