MIDle生命周期详解,以及工作原理

简介: <p style="color:rgb(51,51,51)"> 当MIDlet被应用程序管理器成功地初始化之后,就开始展开了它的生命周期。MIDlet的生命周期完全由应用程序管理器控制,也就是说,当MIDlet要从一个状态变成另外一个状态时,应用程序管理器会调用对应的回调函数(call back,也就是MIDlet类定义的那三个抽象方法)。基本上,MIDlet有三种状态,分别是停止状态(P

 当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生命周期的函数,它们只是一个提供我们初始化资源、释放资源的地方而已。

目录
相关文章
|
6月前
|
Java
Java线程通信的精髓:解析通知等待机制的工作原理
Java线程通信的精髓:解析通知等待机制的工作原理
71 3
Java线程通信的精髓:解析通知等待机制的工作原理
|
6月前
|
搜索推荐 编译器 开发者
应用程序的运行:原理、过程与代码实践
应用程序的运行:原理、过程与代码实践
202 1
|
6月前
|
存储 安全 Java
JVM工作原理与实战(六):类的生命周期-连接阶段
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了类的生命周期、类的连接阶段等内容。
59 4
|
6月前
|
监控 安全 Java
JVM工作原理与实战(七):类的生命周期-初始化阶段
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了类的生命周期、类的初始化阶段等内容。
52 5
|
6月前
|
存储 监控 安全
JVM工作原理与实战(五):类的生命周期-加载阶段
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了类的生命周期、类的加载阶段等内容。
78 5
|
6月前
useffect 模拟生命周期
useffect 模拟生命周期
36 0
|
6月前
|
缓存 JavaScript 前端开发
简述一下组件的生命周期
在进行组件化项目开发的时候都会存在一个组件的生命周期概念,像Vue、React、小程序等等,无一例外,而通常情况组件的生命周期主要分成三个阶段,包括:创建、更新以及销毁阶段。
88 0
|
编译器
Stemciljs学习之组件生命周期
Stencil 是一个生成 Web Components(更确切地说,是自定义元素)的编译器。Stencil 将最流行的框架的最佳概念结合到一个简单的构建时工具中。 现在让我们一起学习其中的组件生命周期部分。
71 0
|
存储 安全 Java
|
安全 C++ Windows
C++调用外部应用程序的方法的整理总结(常用)
一、三个SDK函数:  WinExec,ShellExecute ,CreateProcess可以实现调用其他程序的要求,其中以WinExec最为简单,ShellExecute比WinExec灵活一些,CreateProcess最为复杂。
3020 0
下一篇
无影云桌面