站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2ME 专题J2ME Timer 使用指南

J2ME Timer 使用指南

摘要: J2ME Timer 使用指南
内容: <table class=tf width="98%" align=center border=0>

<tr>
<td class=bw width="100%">出处&nbsp;http://wireless.java.sun.com/midp/ttips/timers/

J2SE&nbsp;1.3&nbsp;里有一项新的改进,那就是提供了一个可以更简单的实现多任务调度执行的定时器类,调度由一个后台线程完成。&nbsp;MIDP&nbsp;同样也包含了这一改进,使得&nbsp;J2ME&nbsp;开发人员从中受益。

J2ME&nbsp;提示了两个类用来定义和调试任务,&nbsp;他们分别是&nbsp;TimerTask&nbsp;和&nbsp;Timer。TimerTask&nbsp;是用户定义的需要被调度的所有任务的抽象基类。Timer&nbsp;类在任务执行的时候负责创建和管理执行线程。

要定义一个任务,定义一个&nbsp;TimerTask&nbsp;的子类,并实现&nbsp;run&nbsp;方法。例如
</td></tr></table>
<table style="TABLE-LAYOUT: fixed" cellSpacing=0 borderColorDark=#ffffff cellPadding=4 width="98%" align=center bgColor=#e6e6e6 borderColorLight=#009ace border=1>

<tr>
<td style="WORD-WRAP: break-word">import&nbsp;java.util.*;

public&nbsp;class&nbsp;MyTask&nbsp;extends&nbsp;TimerTask
{
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;run()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;"Running&nbsp;the&nbsp;task"&nbsp;);
&nbsp;&nbsp;&nbsp;&nbsp;}
}.
</td></tr></table>

&nbsp; 是不是觉得&nbsp;run&nbsp;方法很熟悉呢?那是因为&nbsp;TimerTask&nbsp;实现了&nbsp;java.lang.Runnable&nbsp;接口。&nbsp;Timer&nbsp;类调用这个&nbsp;run&nbsp;方法来执行各个任务。此外还有一点必须注意到,那就是每个&nbsp;run&nbsp;方法所执行的任务必须能够尽快的终止,因为每个&nbsp;Timer&nbsp;对象在同一时间只能执行一个任务。

&nbsp; 定义好一个任务以后,你可以生成一个&nbsp;Timer&nbsp;对象并调用&nbsp;schedule&nbsp;方法来调度它,就像下面的代码演示的那样:


<table style="TABLE-LAYOUT: fixed" cellSpacing=0 borderColorDark=#ffffff cellPadding=4 width="98%" align=center bgColor=#e6e6e6 borderColorLight=#009ace border=1>

<tr>
<td style="WORD-WRAP: break-word">import&nbsp;java.util.*;

Timer&nbsp;timer&nbsp;=&nbsp;new&nbsp;Timer();
TimerTask&nbsp;task&nbsp;=&nbsp;new&nbsp;MyTask();

//&nbsp;在执行这个任务前等待十秒...
timer.schedule(&nbsp;task,&nbsp;10000&nbsp;);

//&nbsp;在执行任务前等待十秒,然后每过十秒再执行一次
timer.schedule(&nbsp;task,&nbsp;5000,&nbsp;10000&nbsp;);
</td></tr></table>

schedule&nbsp;方法被重载了四次;每一个任务都可以在一个特定的时间点(使用一个&nbsp;Date&nbsp;对象指定)或者延时特定的时间段(以毫秒为单位)之后执行。你可以安排这个任务只执行一次或者在一段特定的时间段里反复执行。Timer&nbsp;还提供了一个&nbsp;scheduleAtFixedRate&nbsp;方法来根据该任务第一次执行的时间来指定反复执行时延长的时间段。如果一个任务被延时了,被安排在后面执行的任务就被相应的缩短等待时间以“接上”被延时的任务。

每个&nbsp;Timer&nbsp;对象都会创建和管理一个后台线程。一般情况下,一个程序创建一个&nbsp;Timer&nbsp;就够了,当然也可以根据需要创建任意多个。你还可以在任何时候停止一个&nbsp;Timer&nbsp;并终止后台线程,方法是调用&nbsp;cancel&nbsp;方法。但要注意的是,一旦&nbsp;Timer&nbsp;并终止了,就不可能再恢复执行,除非你重新生成一个&nbsp;Timer&nbsp;对象并重新安排你想要执行的任务。Timer&nbsp;对象是线程安全的,你可以在多线程的环境下直接访问&nbsp;Timer&nbsp;对象,而不用任何显式的同步处理。

另外,每个任务提供了一个&nbsp;cancel&nbsp;方法(继承自&nbsp;TimerTask&nbsp;基类),你可以在任务执行的过程当中调用该方法来终止该任务。一旦你终止了该任务,那么它将退出任务调度。你可以在任何时间调用每个任务的&nbsp;cancel&nbsp;方法来终止该任务的执行,哪怕该任务还一次都没有执行过。

下面提供了一个简示的&nbsp;MIDlet&nbsp;示例来演示&nbsp;Timer&nbsp;的使用,我们将利用定时器来模拟一个星空移动的效果。星星用一个点来表示,这使用到了低界图形&nbsp;API。关于低界图形&nbsp;API&nbsp;更详细的介绍,请参考我的另一篇文章《使用&nbsp;MIDP&nbsp;的低界用户界面&nbsp;API》。



<table style="TABLE-LAYOUT: fixed" cellSpacing=0 borderColorDark=#ffffff cellPadding=4 width="98%" align=center bgColor=#e6e6e6 borderColorLight=#009ace border=1>

<tr>
<td style="WORD-WRAP: break-word">import&nbsp;javax.microedition.midlet.*;
import&nbsp;javax.microedition.lcdui.*;
import&nbsp;java.util.*;

public&nbsp;class&nbsp;TimerDemo&nbsp;extends&nbsp;MIDlet&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;Display&nbsp;&nbsp;&nbsp;&nbsp;display;
&nbsp;&nbsp;&nbsp;&nbsp;StarField&nbsp;&nbsp;field&nbsp;=&nbsp;new&nbsp;StarField();
&nbsp;&nbsp;&nbsp;&nbsp;FieldMover&nbsp;mover&nbsp;=&nbsp;new&nbsp;FieldMover();
&nbsp;&nbsp;&nbsp;&nbsp;Timer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer&nbsp;=&nbsp;new&nbsp;Timer();

&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;TimerDemo()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display&nbsp;=&nbsp;Display.getDisplay(&nbsp;this&nbsp;);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;destroyApp(&nbsp;boolean&nbsp;unconditional&nbsp;)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;startApp()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display.setCurrent(&nbsp;field&nbsp;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer.schedule(&nbsp;mover,&nbsp;100,&nbsp;100&nbsp;);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;pauseApp()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;exit(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer.cancel();&nbsp;//&nbsp;stop&nbsp;scrolling
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destroyApp(&nbsp;true&nbsp;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;notifyDestroyed();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;FieldMover&nbsp;extends&nbsp;TimerTask&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;run(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;field.scroll();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;StarField&nbsp;extends&nbsp;Canvas&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stars;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Random&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;generator&nbsp;=&nbsp;new&nbsp;Random();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean&nbsp;&nbsp;&nbsp;&nbsp;painting&nbsp;=&nbsp;false;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;StarField(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;getHeight();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;getWidth();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stars&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;new&nbsp;int[&nbsp;height&nbsp;];

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(&nbsp;int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;height;&nbsp;++i&nbsp;){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stars[i]&nbsp;=&nbsp;-1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;scroll()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;painting&nbsp;)&nbsp;return;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(&nbsp;int&nbsp;i&nbsp;=&nbsp;height-1;&nbsp;i&nbsp;&gt;&nbsp;0;&nbsp;--i&nbsp;){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stars[i]&nbsp;=&nbsp;stars[i-1];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stars[0]&nbsp;=&nbsp;(&nbsp;generator.nextInt()&nbsp;%
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&nbsp;3&nbsp;*&nbsp;width&nbsp;)&nbsp;)&nbsp;/&nbsp;2;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;stars[0]&nbsp;&gt;=&nbsp;width&nbsp;){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stars[0]&nbsp;=&nbsp;-1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repaint();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;paint(&nbsp;Graphics&nbsp;g&nbsp;){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;painting&nbsp;=&nbsp;true;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.setColor(&nbsp;0,&nbsp;0,&nbsp;0&nbsp;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(&nbsp;0,&nbsp;0,&nbsp;width,&nbsp;height&nbsp;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.setColor(&nbsp;255,&nbsp;255,&nbsp;255&nbsp;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(&nbsp;int&nbsp;y&nbsp;=&nbsp;0;&nbsp;y&nbsp;&lt;&nbsp;height;&nbsp;++y&nbsp;){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;x&nbsp;=&nbsp;stars[y];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;x&nbsp;==&nbsp;-1&nbsp;)&nbsp;continue;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawline(&nbsp;x,&nbsp;y,&nbsp;x,&nbsp;y&nbsp;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;painting&nbsp;=&nbsp;false;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;keypressed(&nbsp;int&nbsp;keycode&nbsp;){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}

</td></tr></table>


TimerDemo&nbsp;MIDlet&nbsp;使用了一个&nbsp;Timer&nbsp;对象&nbsp;timer&nbsp;来调度执行一个&nbsp;TimerTask&nbsp;任务&nbsp;FieldMover,时间间隙&nbsp;100&nbsp;毫秒。FieldMover&nbsp;处理星空的更新并重绘任务,使得整个星空不断得往屏幕下方“延伸”。这样就生成了一个简单的星空移动的效果。

关于翻译作者


<table style="TABLE-LAYOUT: fixed" cellSpacing=0 borderColorDark=#ffffff cellPadding=4 width="98%" align=center bgColor=#e6e6e6 borderColorLight=#009ace border=1>

<tr>
<td style="WORD-WRAP: break-word">稀饭,Java&nbsp;爱好者.点击http://www.matrix.org.cn/article.asp查看更多翻译文章</td></tr></table>
↑返回目录
前一篇: J2ME (Java 2 Micro Edition) 简介
后一篇: 高可靠性移动应用程序-移动数据库和J2ME工具(三)