麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

J2ME 進度條與線程化模型實例解析

2019-11-18 12:45:26
字體:
來源:轉載
供稿:網友

  在J2ME的UI體系中,UI操作是在一個獨立的線程中運行的。往往在API中要求程序員對接口方法立即返回。也就是說非阻塞的。你必須開啟一個獨立的線程來完成你自定義的復雜的工作,比如聯網等可能發生阻塞的io操作。新的線程假如不和用戶交流,告訴用戶線程正在工作的話,將會顯現的非常不友好。用戶可能執行別的操作而擾亂程序的正常運行。一個簡單的方法是提供一個進度條,這樣用戶就會愿意等待上一會,直到程序運行出結果。為了將程序員從前臺進度條與后臺線程的通信中解脫出來,專心于后臺線程的開發,有必要設計一個進度條線程模型。
  
  應該注重到進度條有多種的形式:
  動畫形式進度條,僅表示程序正在運行(自維護的)
  可交互增量形式的進度條,后臺線程通過調用進度條的相應方法在程序運行中不斷的改變進度條的狀態
  進度條的表現形式應該靈活,不要固定其實現
  進度條對象要重復利用
   J2ME 進度條與線程化模型實例解析
  進度調和后臺線程的交流也有好幾種情況:
  
  僅僅將進度條繪畫在屏幕上,并等后臺任務完成后,由后臺線程跳轉到成功畫面。
  
  對于可取消的任務,用戶可以通過點擊進度條的按鈕來試圖cancel任務,后臺任務應該盡快取消,并跳轉到失敗的畫面。
  
  對于不可跳轉的任務,用戶只有耐心等待。
  
  假如背景線程運行失敗,應自行跳轉到失敗的屏幕。
  
  進度條的設計(前臺)為了實現進度條的表現的多樣性,首先抽象一個接口:
  
  PRogressObserver.java
  package com.favo.ui;
  import javax.microedition.lcdui.Display;
  
  /**
  * @author Favo
  *
  * 這是仿照Smart Ticket制作的進度條觀察者,這個模型的優點是
  * 1,低耦合度。你可以通過Form,Canvas等來實現這個接口
  * 2,支持可中斷的任務,因為背景線程是無法強制性中斷的,
  * 所以就 沒有了在觀察者中回調背景線程相應方法的必要,
  * 假如支持可中斷的話,可以讓背景線程來查詢觀察者的isStopped()
  * 3,可以說進度條僅僅將自己繪畫在屏幕上,他對后臺線程毫不關心
  */
  public interface ProgressObserver {
  /**
  * 將進度條復位
  */
  public void reset();
  
  /**
  * 將進度條設置最大
  */
  public void setMax();
  
  /*
  * 將自己繪制在屏幕上,假如進度條要開啟自身的線程用于自動更新畫面,
  * 也在這里構造并開啟繪畫線程(常用于動畫滾動條)
  */
  public void show(Display display);
  
  /**
  * 滾動條退出命令,假如進度條曾經開啟自身的線程用于自動更新畫面,
  * (常用于動畫滾動條),在這里關閉動畫線程
  */
  public void exit();
  
  /**
  * 更新進度條
  */
  public void updateProgress(Object param1);
  
  public boolean isStoppable();
  
  public void setStoppable(boolean stoppable);
  
  public boolean isStopped();
  
  public void setStopped(boolean stopped);
  
  public void setTitle(String title);
  
  public void setPrompt(String prompt);
  }
  
  每個方法都很一幕了然,我解釋兩點:
  1)“2,支持可中斷的任務,因為背景線程是無法強制性中斷的,所以就沒有了在觀察者中回調背景線程相應方法的必要, 假如支持可中斷的話,可以讓背景線程來查詢觀察者的isStopped()”
  
  假如要支持可中斷線程的話,想當然的,我們希望用戶按下按鈕后回調后臺線程的某個方法來停止線程,并且這個方法要立即返回(前面提過UI的用戶響應不能夠阻塞)。但是細細想想,線程是無法被強制停止的,而且即使能夠被強制停止也很不安全。所以這個方法也只能夠是通過設置某個flag,然后立即返回。這樣的話線程就和前臺的UI緊密的耦合在一起了。與其這樣,倒不如讓后臺線程去查詢UI的狀態。這樣UI并不關心到底是誰在后臺維護他狀態。
  
  2)假如要實現一個不交互動畫UI,那么顯然這個UI是自維護的(也就是說UI單獨有自己的繪畫線程)。為了能夠實現這種情況,可以在show中開啟線程,在exit中結束線程。對于交互UI,可以簡單的忽略exit方法。
  
  下面給一個利用Form和Gauge實現的交互式UI(非自維護的),讀者可以看看其中的細節,參照他可以設計自己的用Canvas實現的,或者自維護的等等不同的實現。
  
  ProgressGaugeUI.java
  package com.favo.ui;
  
  import javax.microedition.lcdui.Command;
  import javax.microedition.lcdui.CommandListener;
  import javax.microedition.lcdui.Display;
  import javax.microedition.lcdui.Displayable;
  import javax.microedition.lcdui.Form;
  import javax.microedition.lcdui.Gauge;
  
  /**
  * @author Favo
  * Preferences - Java - Code Style - Code Templates
  */
  public class ProgressGaugeUI implements ProgressObserver,
  CommandListener {
  
  private static final int GAUGE_MAX = 8;
  
  private static final int GAUGE_LEVELS = 4;
  
  private static ProgressGaugeUI pgUI;
  
  private Form f;
  
  private Gauge gauge;
  
  private Command stopCMD;
  
  boolean stopped;
  
  boolean stoppable;
  
  int current;
  
  protected ProgressGaugeUI() {
  f = new Form("");
  gauge = new Gauge("", false, GAUGE_MAX, 0);
  stopCMD = new Command("Cancel", Command.STOP, 10);
  f.append(gauge);
  f.setCommandListener(this);
  }
  
  public static ProgressGaugeUI getInstance() {
  if (pgUI == null) {
  return new ProgressGaugeUI();
  }
  return pgUI;
  }
  
  public void reset() {
  current=0;
  gauge.setValue(0);
  stopped=false;
  setStoppable(false);
  setTitle("");
  setPrompt("");
  }
  
  public void updateProgress(Object param1)
  {
  //這里的參數設計為提示語
  current=(current+1)%GAUGE_LEVELS;
  gauge.setValue(current * GAUGE_MAX/GAUGE_LEVELS);
  if(param1!=null && param1 instanceof String){
  setPrompt((String)param1);
  }
  }
  
  public boolean isStoppable() {
  return stoppable;
  }
  
  public void setStoppable(boolean stoppable) {
  this.stoppable = stoppable;
  if(stoppable){
  f.addCommand(stopCMD);
  }else{
  f.removeCommand(stopCMD);
  }
  }
  
  public boolean isStopped() {
  return stopped;
  }
  
  public void setStopped(boolean stopped) {
  this.stopped=stopped;
  }
  
  public void setTitle(String title) {
  f.setTitle(title);
  }
  
  public void setPrompt(String prompt) {
  gauge.setLabel(prompt);
  }
  
  public void commandAction(Command arg0, Displayable arg1)
  {
  if(arg0==stopCMD){
  if(isStoppable())
  stopped=true;
  else{
  setPrompt("can't stop!");
  }
  }
  }
  
  public void show(Display display) {
  display.setCurrent(f);
  }
  public void exit() {
  // 忽略
  }
  public void setMax() {
  gauge.setValue(GAUGE_MAX);
  }
  }
  
  后臺線程的設計
  后臺線程替我們作以下的內容:
  
  1)執行我們的任務runTask()
  2)假如用戶中斷線程,那么runTask()運行完后,將會跳轉到我們指定的失敗屏幕
  3)在最后替我們調用UI.exit()
  
  我們需要做的:
  
  1)提供一個前臺的UI,提供失敗后跳轉的畫面,提供Display的實例
  2)在runTask()中,假如任務完成,手工跳轉失敗畫面
  3)在runTask()中,假如任務失敗,手工跳轉失敗畫面
  4)在runTask()中改變進度欄的狀態。
  5)在runTask()中查詢用戶是否取消,假如用戶取消,應該盡快退出runTask()
  這種模型職責清楚,便于使用。但也有一個缺點:假如用戶取消了任務,但是此時任務接近完成,或者已經完成。后臺線程依然會顯示用戶取消了任務,并將會跳轉到我們指定的失敗屏幕。這時候會產生不一致的情況。為了解決整個問題,程序員可以在runTask()中調用taskComplete()來強制完成任務。這樣即使用戶取消了任務,依然回顯示任務成功。當然你也可以不掉用taskComplete()遵循默認的行為特點。
  
  BackgroundTask.java
  package com.favo.ui;
  
  import javax.microedition.lcdui.AlertType;
  import javax.microedition.lcdui.Displayable;
  import javax.microedition.lcdui.Display;
  import javax.microedition.lcdui.Alert;
  
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久久免费精品视频 | 成人免费av在线播放 | 天天碰天天操 | 在线影院av | 一级电影在线免费观看 | 国产盼盼私拍福利视频99 | 精品一区二区三区日本 | 色悠悠久久久久 | 宅男噜噜噜66国产免费观看 | 成人免费精品视频 | 国产99久久精品一区二区300 | 欧美77 | 在线免费av观看 | h网站在线观看 | 国产超碰人人做人人爱ⅴa 国产精品久久久久久久hd | 成人在线精品视频 | 久久久久久久黄色片 | 日韩黄色一级视频 | 国产精品久久久久一区二区 | 91在线视频在线观看 | 欧美在线观看视频网站 | 欧美福利视频一区二区三区 | 本站只有精品 | 日韩毛片一区二区三区 | 亚洲第一页视频 | 草莓福利视频在线观看 | 欧美精品一区二区久久 | 中文字幕综合在线观看 | 成年毛片 | 一级毛片在线免费播放 | 91短视频在线 | 欧美一级片网站 | 夜间福利网站 | 亚洲性在线视频 | 午夜视频在线免费播放 | 一区二区三区国产在线 | 黄色大片网站在线观看 | 国产精品视频一区二区三区四 | 2023av在线视频 | 一区二区三区日韩在线观看 | 久久免费视频5 |