冰浪

          哥已不再年輕 - 堅定夢想,畢生追求!
          posts - 85, comments - 90, trackbacks - 0, articles - 3
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
          初次編寫J2ME的聯(lián)網(wǎng)應(yīng)用程序的時候往往會寫出這樣的代碼:
          public void commandAction(Command c, Displayable s) {
              if (c == mExitCommand)
                notifyDestroyed();
              else if (c == mConnectCommand)
                connect();
          }

          private void connect() {
              String url = getAppProperty("NetworkThreading.URL");
             
              try {
               
                HttpConnection hc = (HttpConnection)Connector.open(url);
                InputStream in = hc.openInputStream();
               
                int contentLength = (int)hc.getLength();
                if (contentLength == -1) contentLength = 255;
                byte[] raw = new byte[contentLength];
          ........
          .......
          }
          當(dāng)你運行這樣的程序的時候會出現(xiàn)什么問題呢?wtk會提示你聯(lián)網(wǎng)工作可能會堵塞用戶輸入,讓你到另外一個線程去進行聯(lián)網(wǎng)操作。OK,那么我們按照他的要求新建一個線程來進行聯(lián)網(wǎng),比如這樣寫:
          public void commandAction(Command c, Displayable s) {
          if (c == mExitCommand)
              notifyDestroyed();
          else if (c == mConnectCommand) {
              Thread t = new Thread() {
                public void run() {
                  connect();
                }
              };
              t.start();
          }
          }
          這樣聯(lián)網(wǎng)就可以通過了,那么為什么會這樣呢?明白事物背后的原理顯得非常的重要,下面我做一下介紹,當(dāng)程序運行的時候,Application Management Software(應(yīng)用管理軟件)首先初始化一個MIDlet,然后調(diào)用他的startApp()方法使得MIDlet進入active狀態(tài),這條程序分支就是主線程,他執(zhí)行其他的方法后都會返回到這個分支上來繼續(xù)執(zhí)行。然后聯(lián)網(wǎng)是個可能堵塞的操作,意味著他可能長時間都不返回。我曾經(jīng)寫的聯(lián)網(wǎng)程序在手機上運行,的確比較耗費時間。如果他不返回,那么就不能進行后面的操作,用戶也不能輸入。這樣看上去手機就像死了一樣,這顯然不夠友好。看看下面的原理圖吧:
          Hijacking the system event thread
          當(dāng)我們在應(yīng)用程序中新建一個線程來處理聯(lián)網(wǎng)或者瀏覽大量RMS數(shù)據(jù)的時候就不一樣了。這時候啟動線程后主線程會立刻返回,不會堵塞。
          Using a new thread for network activity
          仔細想想這樣同樣有不好的地方,盡管他可以正常工作,但是每次用戶按下按鈕的時候都會有新的線程產(chǎn)生,這樣顯然不夠高效。幸好java中提供了wait()和notify()/notifyAll()來協(xié)調(diào)這樣的問題,我們啟動線程后讓他進入等待的狀態(tài),當(dāng)用戶按下按鈕的時候才讓他繼續(xù)運行。代碼類似這樣:
          public synchronized void run() {
          while (mTrucking) {
              try { wait(); }
              catch (InterruptedException ie) {}
              if (mTrucking) connect();
          }
          }

          public synchronized void go() {
          notify();
          }
          Using a single worker thread
          這樣效率比較高了!當(dāng)用戶進行聯(lián)網(wǎng)操作的時候我們應(yīng)該做一個提示界面,比如一個動畫告訴用戶正在進行聯(lián)網(wǎng)操作。這樣比較友好。那么當(dāng)用戶選擇聯(lián)網(wǎng)動作的時候,我們讓我提前做好的歡迎界面顯示在屏幕上,聯(lián)網(wǎng)結(jié)束后再把返回的結(jié)果顯示出來。這樣就是一個出色的聯(lián)網(wǎng)應(yīng)用程序了。下面的這個代碼可以在屏幕上描繪一個動畫的效果,當(dāng)然你也可以修改一下做成自己喜歡的樣子。
          import java.util.*;

          import javax.microedition.lcdui.*;

          public class WaitCanvas
              extends Canvas {
          private int mCount, mMaximum;
          private int mInterval;

          private int mWidth, mHeight, mX, mY, mRadius;
          private String mMessage;

          public WaitCanvas() {
              mCount = 0;
              mMaximum = 36;
              mInterval = 100;
             
              mWidth = getWidth();
              mHeight = getHeight();
             
              // Calculate the radius.
              int halfWidth = (mWidth - mRadius) / 2;
              int halfHeight = (mHeight - mRadius) / 2;
              mRadius = Math.min(halfWidth, halfHeight);
             
              // Calculate the location.
              mX = halfWidth - mRadius / 2;
              mY = halfHeight - mRadius / 2;

              // Create a Timer to update the display.
              TimerTask task = new TimerTask() {
                public void run() {
                  mCount = (mCount 1) % mMaximum;
                  repaint();
                }
              };
              Timer timer = new Timer();
              timer.schedule(task, 0, mInterval);
          }

          public void setMessage(String s) {
              mMessage = s;
              repaint();
          }

          public void paint(Graphics g) {
              int theta = -(mCount * 360 / mMaximum);
             
              // Clear the whole screen.
              g.setColor(255, 255, 255);
              g.fillRect(0, 0, mWidth, mHeight);
             
              // Now draw the pinwheel.
              g.setColor(0, 0, 0);
              g.drawArc(mX, mY, mRadius, mRadius, 0, 360);
              g.fillArc(mX, mY, mRadius, mRadius, theta 90, 90);
              g.fillArc(mX, mY, mRadius, mRadius, theta 270, 90);
             
              // Draw the message, if there is a message.
              if (mMessage != null)
                g.drawString(mMessage, mWidth / 2, mHeight,
                    Graphics.BOTTOM | Graphics.HCENTER);
          }
          }

          主站蜘蛛池模板: 逊克县| 安仁县| 保德县| 库车县| 金坛市| 马关县| 泗水县| 万州区| 托克逊县| 罗田县| 霍邱县| 洛宁县| 东至县| 和平县| 上杭县| 湖北省| 岱山县| 济阳县| 辽宁省| 高邑县| 巴中市| 郎溪县| 巩留县| 宁津县| 深泽县| 张家界市| 长宁区| 那曲县| 无锡市| 徐闻县| 吉木萨尔县| 南靖县| 白玉县| 云龙县| 沙河市| 苏尼特左旗| 长沙市| 夹江县| 谢通门县| 莒南县| 常宁市|