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

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

教你一招:優(yōu)化J2ME程序大小的方法

2019-11-18 12:45:33
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  要把J2ME程序與J2SE程序區(qū)分開(kāi)來(lái),其依據(jù)就是J2ME運(yùn)行所處的受限環(huán)境。多數(shù)J2ME系統(tǒng)的主要受限條件就是可以存儲(chǔ)和運(yùn)行程序所需內(nèi)存的大小。例如,許多MIDP設(shè)備限制應(yīng)用程序的尺寸不大于50K,這遠(yuǎn)遠(yuǎn)不及Server端J2SE運(yùn)行環(huán)境下那些成兆的程序。實(shí)際應(yīng)用中,程序會(huì)很輕易超出這些限制條件。通過(guò)本篇您將學(xué)到一些減小程序尺寸大小的技巧,并在下面的例子中實(shí)踐這些技術(shù)。這個(gè)例子MIDlet僅僅顯示一個(gè)文本框并在其內(nèi)容改變時(shí)發(fā)聲。
  package com.j2medeveloper.techtips;
  import javax.microedition.lcdui.*;
  public class BeforeSizeOptimization extends
  BasicMIDlet {
  public static final Command exitCommand =
  new Command( "Exit",
  Command.EXIT, 1 );
  public BeforeSizeOptimization(){
  }
  PRotected void initMIDlet(){
  getDisplay().setCurrent( new Mainform() );
  }
  public class Mainform extends form {
  public Mainform(){
  super( "Mainform" );
  addCommand( exitCommand );
  append( textf );
  setCommandListener( new CommandListener(){
  public void commandAction( Command c,
  Displayable d ){
  if( c == exitCommand ){
  exitMIDlet();
  }
  }
  }
  );
  setItemStateListener(
  new ItemStateListener() {
  public void itemStateChanged(
  Item item ){
  if( item == textf ){
  AlertType.INFO.playSound(
  getDisplay() );
  }
  }
  }
  );
  }
  
  private TextField textf =
  new TextField( "Type anything", null,
  20, 0 );
  }
  }
  雖然這個(gè)MIDlet在此僅作為一個(gè)例子,但使用的尺寸優(yōu)化技巧可以適用于任一J2ME的profile上。
  注重,上面的MIDlet類需要下面的輔助類:
  package com.j2medeveloper.techtips;
  import javax.microedition.lcdui.*;
  import javax.microedition.midlet.*;
  public abstract class BasicMIDlet extends MIDlet {
  private Display display;
  public BasicMIDlet(){
  }
  protected void destroyApp( boolean unconditional )
  throws MIDletStateChangeException {
  exitMIDlet();
  }
  public void exitMIDlet(){
  notifyDestroyed();
  }
  public Display getDisplay(){ return display; }
  protected abstract void initMIDlet();
  protected void pauseApp(){
  }
  protected void startApp()
  throws MIDletStateChangeException {
  if( display == null ){
  display = Display.getDisplay( this );
  initMIDlet();
  }
  }
  }
  用J2ME WTK打包時(shí),本例子MIDlet占用4K空間。
  
  減小尺寸的首要步驟就是通過(guò)修正程序的功能實(shí)現(xiàn)來(lái)去掉多余的類。程序的所有功能確實(shí)必須都實(shí)現(xiàn)嗎?用戶可以不需要這些“附屬功能”嗎?要設(shè)計(jì)盡可能小的程序,這里的MIDlet例子已經(jīng)相當(dāng)小了。
  
  第二步就是深入考察程序定義的內(nèi)部類,非凡是匿名類。記住,每個(gè)類文件都有一定量的與之相關(guān)的系統(tǒng)開(kāi)銷。即便最普通的類也有系統(tǒng)開(kāi)銷。
  public class foo {
  // nothing here
  }
  編譯上邊的類,生成的類文件大約200byte大小。比如實(shí)現(xiàn)一個(gè)事件監(jiān)聽(tīng)器,就是對(duì)匿名類的常見(jiàn)使用。在例子MIDlet中就定義了兩個(gè)此類的監(jiān)聽(tīng)器。接下來(lái)進(jìn)行的最簡(jiǎn)單的優(yōu)化就是,讓主MIDlet類實(shí)現(xiàn)CommandListener和ItemStateListener接口,并把監(jiān)聽(tīng)器代碼移至此處。記住,多個(gè)對(duì)象可以使用同樣的監(jiān)聽(tīng)器。必要時(shí),可以使用傳遞至commandAction和itemStateChanged方法的參變量來(lái)區(qū)分它們。
  
  內(nèi)部類也可使代碼過(guò)大,因?yàn)榫幾g器必須生成非凡的變量和方法,以便內(nèi)部類可以訪問(wèn)包含它們的類的私有內(nèi)容。請(qǐng)參考內(nèi)部類的規(guī)范以獲取更多信息。
  
  第三步,盡量使用現(xiàn)有的類。例如,基于CLDC的profile沒(méi)有構(gòu)造集合類,所以我們可以用內(nèi)建的Hashtable和Vector類來(lái)實(shí)現(xiàn)之。構(gòu)造MIDP程序時(shí)也可采用此法。例子MIDlet中定義了一個(gè)form字類來(lái)生成主表,可以輕易的如下直接生成:
  
  mainform = new form( "Mainform" );
  mainform.addCommand( okCommand );
  mainform.setCommandListener( listener );
  
  這里沒(méi)有正確或者錯(cuò)誤的答案,只是要推敲。
  
  第四步就是破壞程序的繼續(xù)關(guān)系。你也許把相關(guān)的代碼放到一個(gè)或多個(gè)抽象類中,這是OOD中為提高程序間代碼重用的推薦做法。雖然破壞繼續(xù)關(guān)系與你所學(xué)知識(shí)相違反,但簡(jiǎn)化的繼續(xù)關(guān)系更有意義。非凡的,當(dāng)你的的抽象類?D?D可能來(lái)自其他項(xiàng)目?D?D僅僅被繼續(xù)一次時(shí),破壞繼續(xù)關(guān)系的結(jié)果不言而喻。例如,例子MIDlet繼續(xù)了BasicMIDlet類,但兩者合并為一個(gè)類。
  
  第五步就是要縮短名字長(zhǎng)度,如包名、類名、方法名和數(shù)據(jù)元素名。看起來(lái)有些蠢,但一個(gè)類文件確實(shí)包含太多的符號(hào)信息。縮短各量的名字可以縮小生成的類文件尺寸。這種節(jié)省不會(huì)非凡明顯,但多個(gè)類中進(jìn)行總加的結(jié)果還是可觀的。包名對(duì)減小尺寸來(lái)講非凡合適。MIDP程序是完全自我包容的,完全可以不使用包名,因?yàn)樵谑殖衷O(shè)備上包名根本不可能與其他類名沖突。例子MIDlet中,可以把com.j2medeveloper.tchtips包名去掉。
  
  注重,一般來(lái)講,縮短名字不需要手工去做,要用一個(gè)“混淆器”去做。“混淆器”的主要功能是“隱藏”程序代碼,使之不能通過(guò)反編譯讀出。它的副作用是減小了程序的尺寸。因?yàn)殡[藏過(guò)程主要通過(guò)更改方法和數(shù)據(jù)成員的名字來(lái)完成。有一個(gè)開(kāi)源的混淆器稱為RetroGuard,可以免費(fèi)從http://www.retrologic.com得到。也有一些商業(yè)包可用。(當(dāng)為基于CLDC的profile混淆時(shí),記得在預(yù)校驗(yàn)之前混淆,否則混淆器將使類文件中的預(yù)校驗(yàn)數(shù)據(jù)失效。)
  
  最后,深入數(shù)組的初始化。(例子MIDlet沒(méi)有做數(shù)組初始化,但對(duì)程序來(lái)說(shuō)初始化是重要的一步) 在編譯時(shí),一個(gè)數(shù)組初始化聲明如下所示:
  
  int arr[] = { 0, 1, 2, 3 };
  而實(shí)際生成代碼的過(guò)程如下所示:
  arr[0] = 0;
  arr[1] = 1;
  arr[2] = 2;
  arr[3] = 3;
  
  這個(gè)過(guò)程可以通過(guò)使用Java 2 SDK中附帶的javap工具把二進(jìn)制代碼反編譯成類文件去看(使用-c選項(xiàng))。也許你會(huì)詫異于看到的內(nèi)容,非凡當(dāng)你希望看到的是一排排二進(jìn)制常數(shù)時(shí)。有兩種方法可以讓你看不到反編譯的程序代碼,(1)把數(shù)據(jù)編碼為字符串,運(yùn)行時(shí)解碼之,或者(2)把數(shù)據(jù)存為二進(jìn)制文件并與程序打包,用類裝載器的getResourceAsStream方法在運(yùn)行時(shí)存取之。
  
  以上只是一些指導(dǎo)性的方法,對(duì)每個(gè)J2ME程序而言,這里沒(méi)有具體到步驟。但是多數(shù)方法可以應(yīng)用的本例。優(yōu)化后的MIDlet如下所示:
  
  import javax.microedition.lcdui.*;
  import javax.microedition.midlet.*;
  public class ASO extends MIDlet
  implements CommandListener,
  ItemStateListener {
  private Display display;
  private form mainform;
  private TextField mainformTF =
  new TextField( "Type anything", null,
  20, 0 );
  public static final Command exitCommand =
  new Command( "Exit",
  Command.EXIT, 1 );
  public ASO(){
  }
  public void commandAction( Command c,
  Displayable d ){
  if( c == exitCommand ){
  exitMIDlet();
  }
  }
  protected void destroyApp( boolean unconditional )
  throws MIDletStateChangeException {
  exitMIDlet();
  }
  public void exitMIDlet(){
  notifyDestroyed();
  }
  public Display getDisplay(){ return display; }
  protected void initMIDlet(){
  mainform = new form( "Mainform" );
  mainform.addCommand( exitCommand );
  mainform.setCommandListener( this );
  mainform.setItemStateListener( this );
  mainform.append( mainformTF );
  getDisplay().setCurrent( mainform );
  }
  public void itemStateChanged( Item item ){
  if( item == mainformTF ){
  AlertType.INFO.playSound( getDisplay() );
  }
  }
  protected void pauseApp(){
  }
  protected void startApp()
  throws MIDletStateChangeException {
  if( display == null ){
  display = Display.getDisplay( this );
  initMIDlet();
  }
  }
  }

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 双流县| 蒲城县| 青海省| 丰台区| 鄱阳县| 江西省| 宜州市| 平昌县| 嫩江县| 辰溪县| 山丹县| 丽江市| 松滋市| 台安县| 化德县| 金沙县| 阜康市| 普格县| 化德县| 茶陵县| 崇文区| 绥滨县| 封丘县| 华容县| 闻喜县| 德化县| 鸡西市| 霸州市| 平定县| 连南| 称多县| 澄江县| 郓城县| 游戏| 织金县| 方山县| 石泉县| 新巴尔虎右旗| 汉源县| 镇坪县| 增城市|