程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> J2ME Timer 使用指南

J2ME Timer 使用指南

編輯:J2ME
J2SE 1.3 裡有一項新的改進,那就是提供了一個可以更簡單的實現多任務調度執行的定時器類,調度由一個後台線程完成。 MIDP 同樣也包含了這一改進,使得 J2ME 開發人員從中受益。

J2ME 提示了兩個類用來定義和調試任務, 他們分別是 TimerTask 和 Timer。TimerTask 是用戶定義的需要被調度的所有任務的抽象基類。Timer 類在任務執行的時候負責創建和管理執行線程。

要定義一個任務,定義一個 TimerTask 的子類,並實現 run 方法。例如

import Java.util.*;

public class MyTask extends TimerTask
{
public void run()
{
System.out.println( "Running the task" );
}
}



是不是覺得 run 方法很熟悉呢?那是因為 TimerTask 實現了 Java.lang.Runnable 接口。 Timer 類調用這個 run 方法來執行各個任務。此外還有一點必須注意到,那就是每個 run 方法所執行的任務必須能夠盡快的終止,因為每個 Timer 對象在同一時間只能執行一個任務。

定義好一個任務以後,你可以生成一個 Timer 對象並調用 schedule 方法來調度它,就像下面的代碼演示的那樣:

import Java.util.*;

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

// 在執行這個任務前等待十秒...
timer.schedule( task, 10000 );

// 在執行任務前等待十秒,然後每過十秒再執行一次
timer.schedule( task, 5000, 10000 );



schedule 方法被重載了四次;每一個任務都可以在一個特定的時間點(使用一個 Date 對象指定)或者延時特定的時間段(以毫秒為單位)之後執行。你可以安排這個任務只執行一次或者在一段特定的時間段裡反復執行。Timer 還提供了一個 scheduleAtFixedRate 方法來根據該任務第一次執行的時間來指定反復執行時延長的時間段。如果一個任務被延時了,被安排在後面執行的任務就被相應的縮短等待時間以“接上”被延時的任務。

每個 Timer 對象都會創建和管理一個後台線程。一般情況下,一個程序創建一個 Timer 就夠了,當然也可以根據需要創建任意多個。你還可以在任何時候停止一個 Timer 並終止後台線程,方法是調用 cancel 方法。但要注意的是,一旦 Timer 並終止了,就不可能再恢復執行,除非你重新生成一個 Timer 對象並重新安排你想要執行的任務。Timer 對象是線程安全的,你可以在多線程的環境下直接訪問 Timer 對象,而不用任何顯式的同步處理。

另外,每個任務提供了一個 cancel 方法(繼承自 TimerTask 基類),你可以在任務執行的過程當中調用該方法來終止該任務。一旦你終止了該任務,那麼它將退出任務調度。你可以在任何時間調用每個任務的 cancel 方法來終止該任務的執行,哪怕該任務還一次都沒有執行過。

下面提供了一個簡示的 MIDlet 示例來演示 Timer 的使用,我們將利用定時器來模擬一個星空移動的效果。星星用一個點來表示,這使用到了低界圖形 API。關於低界圖形 API 更詳細的介紹,請參考我的另一篇文章《使用 MIDP 的低界用戶界面 API》。

import Javax.microedition.midlet.*;
import Javax.microedition.lcdui.*;
import Java.util.*;

public class TimerDemo extends MIDlet {

Display display;
StarField field = new StarFIEld();
FieldMover mover = new FIEldMover();
Timer timer = new Timer();

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

protected void destroyApp( boolean unconditional ) {
}

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

protected void pauseApp() {
}

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

class FIEldMover extends TimerTask {
public void run(){
fIEld.scroll();
}
}

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

public StarFIEld(){
height = getHeight();
width = getWidth();
stars = new int[ height ];

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

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

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

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

repaint();
}

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

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

g.setColor( 255, 255, 255 );

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

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

painting = false;
}

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



TimerDemo MIDlet 使用了一個 Timer 對象 timer 來調度執行一個 TimerTask 任務 FieldMover,時間間隙 100 毫秒。FIEldMover 處理星空的更新並重繪任務,使得整個星空不斷得往屏幕下方“延伸”。這樣就生成了一個簡單的星空移動的效果。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved