国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

入門-J2ME學(xué)習(xí)日記之-利用定時(shí)器類模擬MIDlet外部事件

2019-11-18 16:24:55
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
入門-J2ME學(xué)習(xí)日記之-利用定時(shí)器類模擬MIDlet外部事件

作者:Snail


版權(quán)申明:可以轉(zhuǎn)載,請(qǐng)保留作者信息和來(lái)源地址:
作者:Snail
地址:http://www.matrix.org.cn/resource/article/43/43851_J2ME.Html

前面提到MIDlet程序本身可以通過(guò)調(diào)用notifyPaused()請(qǐng)求自己從活動(dòng)狀態(tài)進(jìn)入暫停狀態(tài);調(diào)用notifyDestroyed()請(qǐng)求進(jìn)入銷毀狀態(tài);調(diào)用resumeRequest()請(qǐng)求恢復(fù)到活動(dòng)狀態(tài)。但是具體應(yīng)該怎么使用呢?怎樣通過(guò)程序本身模擬狀態(tài)之間的轉(zhuǎn)換呢?

這些都可以通過(guò)java.util包中的Timer 和TimerTask 類來(lái)實(shí)現(xiàn)。聽(tīng)說(shuō)nokia的模擬器最接近真機(jī),所以這次程序選擇nokia s40 開(kāi)發(fā)環(huán)境(唯一的不足就是不支持中文)。具體看如下演示程序:

import javax.microedition.midlet.MIDlet;
import java.util.*;
/*
* 創(chuàng)建日期 2005-10-8
*
* TODO 要更改此生成的文件的模板,請(qǐng)轉(zhuǎn)至
* 窗口 - 首選項(xiàng) - Java - 代碼樣式 - 代碼模板
*/

/**
* @author Snail
*
* TODO 要更改此生成的類型注釋的模板,請(qǐng)轉(zhuǎn)至
* 窗口 - 首選項(xiàng) - Java - 代碼樣式 - 代碼模板
*/
public class MyTimerTask extends TimerTask {

PRivate MIDlet midlet;

/**
  *
  */
public MyTimerTask(MIDlet midlet) {
  // TODO 自動(dòng)生成構(gòu)造函數(shù)存根
  System.out.println("MyTimerTask contrUCtor");
  this.midlet = midlet;
}
public void run(){
  System.out.println("run() called");
  midlet.resumeRequest();
}


}


import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.*;
import java.util.*;
import javax.microedition.midlet.MIDletStateChangeException;
/*
* 創(chuàng)建日期 2005-10-8
*
* TODO 要更改此生成的文件的模板,請(qǐng)轉(zhuǎn)至
* 窗口 - 首選項(xiàng) - Java - 代碼樣式 - 代碼模板
*/

/**
* @author Snail
*
* TODO 要更改此生成的類型注釋的模板,請(qǐng)轉(zhuǎn)至
* 窗口 - 首選項(xiàng) - Java - 代碼樣式 - 代碼模板
*/
public class MidletTest extends MIDlet implements CommandListener{

private Timer timer;
private MyTimerTask mtk;
private Command exit;
/**
  *
  */
public MidletTest() {
  System.out.println("MidletTest Constructor");
  //初始化Timer對(duì)象
   timer = new Timer();
}

/* (非 Javadoc)
  * @see javax.microedition.midlet.MIDlet#startApp()
  */
protected void startApp() throws MIDletStateChangeException {
  // TODO 自動(dòng)生成方法存根
  System.out.println("startApp Called");
  exit = new Command("EXIT", Command.EXIT, 1);
  Form f = new Form("MidletTest");
  String s = new String("I'll come back soon!");
  f.append(s);
  f.addCommand(exit);
  f.setCommandListener(this);
  Display.getDisplay(this).setCurrent(f);
  try{
   //畫面停留4秒 即活動(dòng)狀態(tài) 時(shí)間為4秒
   Thread.sleep(4000);
  }catch(Exception e){}
  
  System.out.println("Ready to paused");
  try{
   mtk = null;
      //獲得當(dāng)前Midlet基類的引用(向上轉(zhuǎn)型)
      mtk = new MyTimerTask(this);
      //執(zhí)行該任務(wù)等待 2秒
      timer.schedule(mtk, 2000);
      //請(qǐng)求進(jìn)入暫停狀態(tài)
      pauseApp();
      notifyPaused();
  }catch(Exception e){}
  
}

/* (非 Javadoc)
  * @see javax.microedition.midlet.MIDlet#pauseApp()
  */
protected void pauseApp() {
  // TODO 自動(dòng)生成方法存根
  System.out.println("pauseApp Called");

}

/* (非 Javadoc)
  * @see javax.microedition.midlet.MIDlet#destroyApp(boolean)
  */
protected void destroyApp(boolean arg0)throws MIDletStateChangeException {
  // TODO 自動(dòng)生成方法存根
  System.out.println("destroyApp Called:" + arg0);
  //停止Timer ,和TimerTask合同期滿,脫離關(guān)系
  timer.cancel();

}
public void commandAction(Command c, Displayable d){
  if(c == exit){
   try{
   destroyApp(false);
   notifyDestroyed();
   }catch(MIDletStateChangeException e){}
  }
}

}


    通過(guò)上面程序可以看到, Timer必須配合TimerTask才能實(shí)現(xiàn)定時(shí)器功能。
TimerTask是一個(gè)抽象類 ,必須有子類繼承它并重載其run()方法。Timer實(shí)例一個(gè)對(duì)象timer,該對(duì)象通過(guò)調(diào)用schedule方法調(diào)度TimerTask子類對(duì)象執(zhí)行其run()方法,從而達(dá)到使MIDlet 周期性的在暫停狀態(tài)和活動(dòng)狀態(tài)之間不停的切換。

    MyTimerTask類其實(shí)很簡(jiǎn)單,該類內(nèi)部定義了一個(gè)私有數(shù)據(jù) MIDlet 對(duì)象,通過(guò)它可以調(diào)用resumeRequest()方法使MIDlet 程序請(qǐng)求從暫停恢復(fù)到活動(dòng)狀態(tài)。

    MidletTest 類中實(shí)現(xiàn)了CommandListener接口,所以必須要重載其對(duì)應(yīng)的commandAction(Command c, Displayable d)方法。使程序能夠?qū)τ脩舻牟僮髯龀鲰憫?yīng)。類似的在AWT中我們見(jiàn)多了。我們可以執(zhí)行"EXIT",使程序主動(dòng)進(jìn)入銷毀狀態(tài)。具體可以觀察控制臺(tái)信息:

MidletTest Constructor
startApp Called
Ready to paused
MyTimerTask contructor
pauseApp Called
run() called
startApp Called
destroyApp Called:false
Ready to paused
MyTimerTask contructor

便于理解,可以假設(shè)有如下場(chǎng)景:

      上班時(shí)間,老板不在,用手機(jī)玩會(huì)游戲先!游戲ing…… 有電話!接個(gè)電話先,over! 繼續(xù)游戲! 不好 b老板來(lái)了,"EXIT" 退出游戲!!    

      可以看到程序不停的在活動(dòng)和暫停狀態(tài)之間切換。當(dāng)我們"EXIT"程序時(shí) ,看到控制臺(tái)打印信息 , 傳入destroyApp 的是false,即非強(qiáng)制性銷毀。前面已經(jīng)了解,MIDlet主動(dòng)請(qǐng)求狀態(tài)轉(zhuǎn)換需要調(diào)用的方法,并且一般都要先調(diào)用相應(yīng)的pauseApp() destroyApp()方法。這里不在多說(shuō)。現(xiàn)在關(guān)心的是:具體怎么通過(guò)Timer 和TimerTask 實(shí)現(xiàn)的呢?仔細(xì)觀察程序,有這兩句:

mtk = new MyTimerTask(this);
timer.schedule(mtk, 2000);


      首先實(shí)例MyTimerTask對(duì)象,并將this作為參數(shù)傳遞給構(gòu)造方法。this指向的是當(dāng)前Midlet。觀察其構(gòu)造方法,參數(shù)類型是MIDlet ,而MidletTest 只是其導(dǎo)出類。這里隱藏了向上轉(zhuǎn)型。(具體可以參考j2se中繼承與多態(tài)部分。)獲得了MIDlet的引用 ,就象手里拿著遙控器一樣 ,timer就可以控制MIDlet了。timer通過(guò)schedule方法設(shè)置周期,執(zhí)行該任務(wù) 等待兩秒。接下來(lái)的兩句 ,就是程序主動(dòng)請(qǐng)求進(jìn)入暫停。另外,還注意到 timer 在構(gòu)造方法中,所以只被調(diào)用一次,而mtk卻每次調(diào)用startApp時(shí)都會(huì)被重新new一次。這是因?yàn)橹挥姓{(diào)用cancel() Timer和TimerTask脫離關(guān)系時(shí) ,TimerTask才能被安排其他任務(wù)。

    如果把Thread.sleep(4000); 這個(gè)try{}catch(){}塊注釋掉,我們發(fā)現(xiàn) MIDlet從暫停進(jìn)入活動(dòng)狀態(tài)后 屏幕只是很快的一閃 就又進(jìn)入暫停狀態(tài)了。所以這段代碼 就是讓活動(dòng)狀態(tài)多停留一會(huì) 讓他sleep 4秒。

    再看看這段代碼:

try{
   mtk = null;
      //獲得當(dāng)前Midlet基類的引用(向上轉(zhuǎn)型)
      mtk = new MyTimerTask(this);
      //執(zhí)行該任務(wù)等待 2秒
      timer.schedule(mtk, 2000);
      //請(qǐng)求進(jìn)入暫停狀態(tài)
      pauseApp();
      notifyPaused();
  }catch(Exception e){}  


現(xiàn)在把其中的try 和catch 注釋掉 其他的保留。當(dāng)再次運(yùn)行程序,"EXIT",看看控制臺(tái)打印的信息:

MidletTest Constructor
startApp Called
destroyApp Called:false
Ready to paused
MyTimerTask contructor
startApp threw an Exception
java.lang.IllegalStateException: Timer already cancelled.

    在startApp()中有異常被拋出。分析控制臺(tái)信息,應(yīng)該是發(fā)生在destroyApp已經(jīng)被調(diào)用但notifyDestroyed()方法還沒(méi)執(zhí)行時(shí)。此時(shí)cancel()方法已經(jīng)執(zhí)行完畢,Timer和TimerTask 的合作關(guān)系也被迫解除。startApp()繼續(xù)執(zhí)行,當(dāng)程序執(zhí)行到

timer.schedule(mtk, 2000);

這句時(shí) ,因?yàn)殛P(guān)系已經(jīng)解除,startApp()無(wú)法繼續(xù), 所以拋出了上面的異常。


       Timer類還有其他的方法,具體可以參考api中java.util包。

       到此,就暫告一段落!旅行還將繼續(xù)……

(出處:http://m.survivalescaperooms.com)



發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 乳山市| 泸西县| 扎鲁特旗| 连云港市| 毕节市| 应城市| 荃湾区| 临高县| 扎囊县| 辛集市| 鄂尔多斯市| 广灵县| 巴马| 禄丰县| 长春市| 屏边| 修文县| 肥东县| 新绛县| 丹凤县| 德安县| 汉阴县| 原平市| 呼和浩特市| 兴和县| 开封县| 通化市| 伊宁市| 永济市| 蒲江县| 丹棱县| 连平县| 丹阳市| 博乐市| 海伦市| 新安县| 南部县| 曲阜市| 易门县| 武胜县| 阳春市|