当MIDlet被应用程序管理器成功地初始化之后,就开始展开了它的生命周期。MIDlet的生命周期完全由应用程序管理器控制,也就是说,当MIDlet要从一个状态变成另外一个状态时,应用程序管理器会调用对应的回调函数(call back,也就是MIDlet类定义的那三个抽象方法)。基本上,MIDlet有三种状态,分别是停止状态(Paused)、激活状态(Active)以及消灭状态(Destroyed)。MIDlet一开始一定是先进入停止状态,然后应用程序管理器再将它转换成激活状态,然后调用startApp()。

请在心里树立一个概念,那就是:只有当应用程序管理器认为MIDlet的状态必须改变时,才会调用图中的相关函数。以Active状态来说,MIDlet先进入运作状态,然后才调用startApp()。而MIDlet会先调用pauseApp()或destroyApp(),然后再进入停止状态和消灭状态。这就是之所以Active没有被动式(字尾没有加ed),而Paused和Destroyed都是被动式(字尾加ed)的真正涵义。

如果MIDlet自己调用这些函数,通常不会发生错误(除非程序本身有逻辑上的错误),但是也不会造成状态的转换,只能当成一个单纯的函数调用而已。如果MIDlet在状态转换回调函数执行时发生错误,那么就应该抛出MIDletStateChangeException异常,让应用程序管理器知道该如何处理。

startApp()很可能不光只被调用一次而已,而是每次从停止状态重新回到运作状态的时候都会被应用程序管理器调用。所以只需要被初始化一次的动作就不适合放在startApp()之中,请改用构造函数做初始化动作。如果startApp()抛出MIDletStateChangeException或RuntimeException或两者的子类,那么会立刻进入消灭状态,而且系统会自动调用destroyApp(true)。

MIDP规范告诉我们,startApp()的执行时间应该尽可能的短。如果程序在执行时,发生的错误是可以过一阵子就解决的(很可能是系统资源暂时不足),那么程序员就该直接抛出MIDletStateChangeException,拦截之后,再调用notifyPaused(),稍待一会再经由异步事件调用resumeRequest(),重新试试看。如果发生错误即使稍待一会也无法解决,那么程序员就应该直接调用notifyDestroyed()来结束程序。

应用程序管理器会因为某些状况,必须请MIDlet停止运作,例如手机突然来电,或者闹铃响了,或者用户切换到其它程序执行,在这些情况下,为了避免MIDlet占用太多系统资源,所以应用程序管理器就会调用该MIDlet的pauseApp(),这时程序员应该在pauseApp()之中适时释放一些非必需的资源,等到往后回到运作状态时,应用程序管理器会重新调用startApp(),这时我们再将这些之前被pauseApp()释放的资源重新加载。

当MIDlet进入停止状态,不应该使用任何资源,如果应用程序管理器调用pauseApp()时产生异常情形,MIDlet就应该立刻进入消灭状态。

同样的情形也发生在destroyApp(),通常此方法被调用的时候,代表MIDlet要被关闭了,所以程序员应该在这里释放自己所分配的资源。只要MIDlet进入了消灭状态,就无法再回头。如果是系统自己调用destroyApp(),那么在destroyApp()执行时万一发生异常,这些异常将被忽略,MIDlet一样会被关闭。根据规范,我们不能在MIDlet之中直接调用System.exit()或Runtime.exit()来结束程序达到执行,如果这样做的话,会引发java.lang.SecurityException异常。

3 MIDlet自己管理自己的生命周期

除了由应用程序管理器来控制MIDlet的生命周期之外,MIDlet本身也可以软性地决定自己的状态,但不是自己改变自己的状态,而是MIDlet先调用上述相对应的状态改变函数,这些函数会发出信息通知应用程序管理器,请它来帮我们改变MIDlet的状态,但是决定权在于应用程序管理器,不保证一定可行。

假设今天是MIDlet主动要将MIDlet的状态由运作状态变成停止状态,那么我们直接调用pauseApp()函数,只会执行pauseApp()之中的程序代码而已,无法改变MIDlet的状态, MIDlet必须调用notifyPaused()以通知应用程序管理器,应用程序管理器收到通知之后,才会判断是否要让MIDlet进入停止状态。

由MIDlet调用notifyPaused(),与应用程序管理器主动要求停止,两者是有所差别的,主要在于应用程序管理器主动要求停止时,pauseApp()会被调用;由MIDlet调用notifyPaused()时,pauseApp()不会被调用。但是两者都会让MIDlet进入停止状态,所以在MIDlet自己动手调用notifyPaused()之前,最好自己也先调用pauseApp()比较合适。

同样的情况也发生在notifyDestroyed()与destroyApp()。除非是系统强制关闭MIDlet,否则最好MIDlet先调用destroyApp(),然后再调用notifyDestroyed(),请应用程序管理器帮我们将MIDlet转换到消灭状态,最后结束MIDlet的运作。单单MIDlet自己调用destroyApp()是没有用的。

destroyApp()有个布尔值作为参数,根据MIDP的规范,如果传入true,那么MIDlet不管如何应该无条件释放所有资源,然后让应用程序管理器结束MIDlet的运作,这属于系统或硬件强制关闭MIDlet的情形。如果用户调用notifyDestroyed()来结束MIDlet,那么在调用destroyApp()时,最好传入false,代表这并非系统或硬件强制关闭,这时如果MIDlet不希望结束执行,它可以通过抛出MIDletStateChangeException异常告知调用它的人:“我还不想被消灭”,请待会儿再试试。

从这里我们可以看出startApp()、pauseApp()以及destroyApp()并非控制MIDlet生命周期的函数,它们只是一个提供我们初始化资源、释放资源的地方而已。

MIDle生命周期详解,以及工作原理的更多相关文章

  1. ASP.NT运行原理和页面生命周期详解及其应用

    ASP.NT运行原理和页面生命周期详解及其应用 1. 下面是我画的一张关于asp.net运行原理和页面生命周期的一张详解图.如果你对具体不太了解,请参照博客园其他帖子.在这里我主要讲解它的实际应用.  ...

  2. Java 详解 JVM 工作原理和流程

    Java 详解 JVM 工作原理和流程 作为一名Java使用者,掌握JVM的体系结构也是必须的.说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java ...

  3. ASP.NET生命周期详解

    最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...

  4. ASP.NET生命周期详解 [转]

    最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...

  5. ASP.NET生命周期详解(转)

    看到好文章需要分享. 最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多 ...

  6. React—组件生命周期详解

    React—组件生命周期详解 转自 明明的博客  http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢 ...

  7. 【转】Java 类的生命周期详解

    一. 引 言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大 ...

  8. activity的生命周期详解

    刚在看mars老师的视频,看到activity的生命周期,就看了一下,总结了一下.下面是各函数的调用时机 为了更清楚的看清楚工作的具体过程,举例如下: ,建立两个activity,一个main,一个a ...

  9. Asp.net页面生命周期详解任我行(3)-服务器处理请求详细过程

    前言 百度了一下才知道,传智的邹老师桃李满天下呀,我也是邹老师的粉丝,最开始学习页面生命周期的时候也是看了邹老师的视频. 本人是参考了以下前辈的作品,本文中也参合了本人心得,绝非有意盗版,旨在传播,最 ...

随机推荐

  1. JDK的安装以及配置

    JDK的安装以及配置 JDK(Java Development Kit),顾名思义,是 Java 语言的软件开发工具包(SDK). Android发开使用Java语言,所以装JDK是Android开发 ...

  2. Map俩种遍历方式

    Map本身没有迭代器因而在遍历其中元素时需要采取新的措施,在JDK中提供了俩种方法 keySet Set<K> keySet() 返回此映射中包含的键的 Set 视图.该 set 受映射支 ...

  3. FFmpeg的H.264解码器源代码简单分析:解码器主干部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  4. Dynamics CRM Import Solution Attribute Display Name description is null or empty

    在做解决方案导入的时候遇到错误,下载错误xml信息后查询报错如下:"Attribute Display Name description is null or empty",字面意 ...

  5. linu下C语言之BMP图片操作编程(中)

    http://blog.csdn.net/morixinguan/article/details/50719472 关于BMP图的介绍之前已经说过了,最近要用到,又要重新开始学习. 现在实现一个让bm ...

  6. 压力测试工具Ab简介

    Apache安装包中自带的压力测试工具 Apache Benchmark(简称ab) 简单易用,这里就采用 ab作为压力测试工具了. 1.独立安装 通过 yum-utils中的yumdownload  ...

  7. Android初级教程调用手机拍照与摄像功能

    这个小案例建议在手机上运行. package com.example.camera; import java.io.File; import android.net.Uri; import andro ...

  8. Android的ANR详解(原因和方案)

    ANR的定义 在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框 ...

  9. Swift基础之闭包Closure学习

    首先Swift语言中没有了Block内容,但是你可以通过调用OC文件使用,也可以使用Closure(闭包),实现Block或者Delegae同样反向传值或回调函数的效果,也可以解决函数指针的问题,两者 ...

  10. J2EE进阶(十二)SSH框架整合常见问题汇总(三)

    在挂失用户时,发现userid值为空,但是在前台输入处理账号22时,通过后台输出可以看出,后台根据前端输入在数据库中查询到结果对象并输出该对象的userid,而且Guashi对象也获取到了其值. 解决 ...