MIDle生命周期详解,以及工作原理
当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生命周期详解,以及工作原理的更多相关文章
- ASP.NT运行原理和页面生命周期详解及其应用
ASP.NT运行原理和页面生命周期详解及其应用 1. 下面是我画的一张关于asp.net运行原理和页面生命周期的一张详解图.如果你对具体不太了解,请参照博客园其他帖子.在这里我主要讲解它的实际应用. ...
- Java 详解 JVM 工作原理和流程
Java 详解 JVM 工作原理和流程 作为一名Java使用者,掌握JVM的体系结构也是必须的.说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java ...
- ASP.NET生命周期详解
最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...
- ASP.NET生命周期详解 [转]
最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...
- ASP.NET生命周期详解(转)
看到好文章需要分享. 最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多 ...
- React—组件生命周期详解
React—组件生命周期详解 转自 明明的博客 http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢 ...
- 【转】Java 类的生命周期详解
一. 引 言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大 ...
- activity的生命周期详解
刚在看mars老师的视频,看到activity的生命周期,就看了一下,总结了一下.下面是各函数的调用时机 为了更清楚的看清楚工作的具体过程,举例如下: ,建立两个activity,一个main,一个a ...
- Asp.net页面生命周期详解任我行(3)-服务器处理请求详细过程
前言 百度了一下才知道,传智的邹老师桃李满天下呀,我也是邹老师的粉丝,最开始学习页面生命周期的时候也是看了邹老师的视频. 本人是参考了以下前辈的作品,本文中也参合了本人心得,绝非有意盗版,旨在传播,最 ...
随机推荐
- 4.3、Android Studio突破64K方法限制
当应用代码和库代码代码超过64K限制时,早期版本的构建系统会出现如下提示: Conversion to Dalvik format failed: Unable to execute dex: met ...
- 安装解压版本的MySQL,安装过程中的常见命令,检查windows系统错误日志的方式来检查MySQL启动错误,关于Fatal error: Can't open and lock privilege
以端口 port = 3306 # 设置mysql的安装目录 basedir=D://Installed//mysql-5.6.26-winx64//mysql-5.6.26-winx64 # ...
- C++对象模型的那些事儿之二:对象模型(下)
前言 上一篇博客C++对象模型的那些事儿之一为大家讲解了C++对象模型的一些基本知识,可是C++的继承,多态这些特性如何体现在对象模型上呢?单继承.多重继承和虚继承后内存布局上又有哪些变化呢?多态真正 ...
- 【OpenGL】理解一些基本问题
写在前面 啦啦啦,搞了很久的Unity Shaders,越学越觉得基础知识很重要.学Unity Shader的时候,总会想,shader到底是什么呢?shader的pipeline是什么呢?它们是怎么 ...
- 如何正确的理解和解决 ORA-01843:not a valid month
今天码代码的时候遇到了这个问题,因为oracle用的比较少,所在查询了一下. 顿时傻眼,有很多的贴子说是因为nls_date_language的问题,还要改会话级的NLS_DATE_LANGUAGE设 ...
- 【Linux驱动】字符设备驱动
一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 1.字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面 ...
- Android的DatePicker和TimePicker-android学习之旅(三十八)
DatePicker和TimePicker简介 DatePicker和TimePicker是从FrameLayout继承而来,他们都是比较简单的组件.时间改变时间分别添加OnDateChangeLis ...
- pig的一些实例(我常用的语法)
在pig中, dump和store会分别完成两个MR,不会一起进行 1:加载名用正则表达式: LOAD'/user/wizad/data/wizad/raw/2014-0{6,7-0,7-1,7-2, ...
- 安装Compass时不能访问服务器的问题
今天安装Compass,居然老是提示网络问题,后来根据错误提示,发现带https的域名是访问不了的,是是SSL问题.后来搜了一下,在stackoverflow找到一个人说,将https的去掉就好了.具 ...
- 动态创建VIEW
很多人都应该知道 global temporary table 的用法,这里也提出一个动态VIEW的用法,在实际过程中有着很好的独特之处 具体如下: /***************创建PACKAGE ...