2011-12-30 59 views
0

嗨,我做一個小的應用程序,以顯示所有SD卡圖像應該在我的應用程序的縮略圖顯示視圖。我的計劃是像下面如何提高從SDCard加載圖像到我的應用程序的性能?

這裏的問題是,在模擬器加載快速,準確的地方爲手機要花大量的時間。它裝載了一些30MB左右的問題。它是80MB左右,它沒有在我的屏幕上顯示圖像。

注:這是在模擬器而不是設備 和我的圖片路徑完美的工作是「文件:/// SD卡/圖片/」 我的代碼是:

這是我的應用程序啓動器類

public class StartUp extends UiApplication{ 

    public static void main(String[] args) { 
     StartUp start=new StartUp(); 
     start.enterEventDispatcher(); 
    } 
    public StartUp() { 
     pushScreen(new ViewerMainScreen()); 
    } 
} 

這是我ViewerMainScreen.java

public class ViewerMainScreen extends MainScreen implements FieldChangeListener{ 

    private ObjectListField fileList; 
    private String currentPath = "file:///"; 
    public VerticalFieldManager vert_manager=null; 
    private BitmapField before[]=null,next[]=null; 
    private int size=0;Border b1,b2; 
    TableLayoutManager colFMgr=null; 
    private Vector img_data=null; 
    private int count=0; 
    public ViewerMainScreen() { 
     super(); 
     setTitle("Browse to image..."); 
     initGUI(); 
    } 

    public void initGUI() { 
     try { 
//   add(getFileList()); 
      img_data=getAllList("file:///SDCard/images"); 
      b1=BorderFactory.createSimpleBorder(new XYEdges(3,3,3,3),new XYEdges(Color.RED, Color.RED, Color.RED, Color.RED),Border.STYLE_SOLID); 
      b2=BorderFactory.createSimpleBorder(new XYEdges(0,0,0,0)); 
      size=img_data.size(); 
      before=new BitmapField[size]; 
      next=new BitmapField[size]; 
      vert_manager=new VerticalFieldManager(VERTICAL_SCROLL|VERTICAL_SCROLLBAR){ 
       protected void sublayout(int maxWidth, int maxHeight) { 
        super.sublayout(Display.getWidth(),Display.getHeight()); 
        setExtent(Display.getWidth(),Display.getHeight()); 
       } 
      }; 
      colFMgr = new TableLayoutManager(new int[] { 

       TableLayoutManager.USE_PREFERRED_SIZE, 
       TableLayoutManager.USE_PREFERRED_SIZE, 
       TableLayoutManager.USE_PREFERRED_SIZE, 
       TableLayoutManager.USE_PREFERRED_SIZE, 

      }, Manager.HORIZONTAL_SCROLL|VERTICAL_SCROLL|VERTICAL_SCROLLBAR); 
      for(int i= 0;i < size;i++) 
      { 
       EncodedImage load_img=EncodedImage.getEncodedImageResource("loading.jpg"); 
        before[i] = new BitmapField(load_img.getBitmap(),Field.FOCUSABLE){ 
         protected boolean navigationClick(int status,int time) { 
          fieldChangeNotify(0); 
          return super.navigationClick(status, time); 
         } 
         protected void onFocus(int direction) 
          { 
           this.setBorder(b1); 
           invalidate(); 
          } 
          protected void onUnfocus() 
          { 
           this.setBorder(b2); 
           invalidate(); 
          } 

        }; 


        colFMgr.add(before[i]); 
      } 
      add(colFMgr); 

      Thread t=new Thread(){ 
       public void run() { 
       try { 
       Thread.sleep(2000); 

       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       } 
       callImageThread(); 
       } 
      }; 
     t.start(); 
     } catch (Exception e) { 
      Dialog.alert(e.getMessage()); 
     } 
    } 

    private void callImageThread() { 
     for(int i=0;i<size;i++) 
     { 
      if(count==6){ 
       try { 
        Thread.sleep(400); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
      ImageThread th=new ImageThread(this, "file:///SDCard/images/"+img_data.elementAt(i), i); 
      th.start(); 
      count++; 

     } 

    } 

    public void ReplaceImage(EncodedImage img,int index) 
    { 

     before[index].setBitmap(img.getBitmap()); 
     before[index].setChangeListener(this); 
     count--; 
     System.out.println("Thread count: ========================"+Thread.activeCount()+"============================================="+count); 
    } 
    public void fieldChanged(Field field, int context) { 
     for(int i=0;i<size;i++) 
     { 
      if(field==before[i]) 
      { 
       synchronized (UiApplication.getEventLock()) { 
        EncodedImage img=null; 
        img=loadFile("file:///SDCard/images/"+img_data.elementAt(i)); 
        int displayWidth = Fixed32.toFP(Display.getWidth()-100); 
        int imageWidth = Fixed32.toFP(img.getWidth()); 
        int scalingFactorX = Fixed32.div(imageWidth, displayWidth); 
        int displayHeight = Fixed32.toFP(Display.getHeight()-100); 
        int imageHeight = Fixed32.toFP(img.getHeight()); 
        int scalingFactorY = Fixed32.div(imageHeight, displayHeight); 
        EncodedImage scaledImage = img.scaleImage32(scalingFactorX, scalingFactorY); 
        UiApplication.getUiApplication().pushScreen(new ZoomScreen(scaledImage)); 
       } 

      } 

     } 

    } 
    public void displayMessage(final String message) 
    { 
     UiApplication.getUiApplication().invokeLater(new Runnable() { 
      public void run() { 
       Dialog.inform(message); 
      } 
     }); 
    } 
    private Vector getAllList(String path){ 
     Vector data=new Vector(); 
     FileConnection fileConnection=null; 
     try{ 
      fileConnection = (FileConnection) Connector.open(path); 
      if (fileConnection.isDirectory()) { 
       Enumeration directoryEnumerator = fileConnection.list(); 
       while (directoryEnumerator.hasMoreElements()) { 
        data.addElement(directoryEnumerator.nextElement()); 
       } 

      } 
     }catch (Exception e) { 
      System.out.println(e.getMessage()); 
     } 
     finally 
     { 
      if(fileConnection!=null){ 
       try { 
        fileConnection.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
     return data; 
    } 



    private EncodedImage loadFile(String path) { 

     FileConnection fileConnection =null; 
     InputStream inputStream =null; 
     EncodedImage encodedImage=null; 
     try { 
      fileConnection = (FileConnection) Connector.open(path); 
      if(fileConnection.exists()){ 
       inputStream = fileConnection.openInputStream(); 
       byte[] imageBytes = new byte[(int)fileConnection.fileSize()]; 
       inputStream.read(imageBytes); 
       encodedImage = EncodedImage.createEncodedImage(imageBytes, 0, imageBytes.length); 
       if(fileConnection!=null){ 
        try { 
         fileConnection.close(); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
       if(inputStream!=null){ 
        try { 
         inputStream.close(); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 

      } 
     } catch (IOException e) { 
      Dialog.alert("Insert an SD Card."); 
     } 
     return encodedImage; 
    } 
} 

這是我ImageThread.java

public class ImageThread extends Thread{ 
    private ViewerMainScreen screen; 
    private String path; 
    private int index; 
    private EncodedImage scaledImage=null; 
    public ImageThread(ViewerMainScreen screen,String path,int index) { 
     this.screen=screen; 
     this.path=path; 
     this.index=index; 
    } 
    public void callMainScreen(EncodedImage eimg,int Rindex) { 
     screen.ReplaceImage(eimg, Rindex); 
    } 
    public void run() { 
     FileConnection fileConnection =null; 
     InputStream inputStream =null; 
     EncodedImage encodedImage=null; 
     try { 
      fileConnection = (FileConnection) Connector.open(path); 
      if(fileConnection.exists()){ 
       inputStream = fileConnection.openInputStream(); 
       byte[] imageBytes = new byte[(int)fileConnection.fileSize()]; 
       inputStream.read(imageBytes); 
       encodedImage = EncodedImage.createEncodedImage(imageBytes, 0, imageBytes.length); 

       int displayWidth = Fixed32.toFP(100); 
       int imageWidth = Fixed32.toFP(encodedImage.getWidth()); 
       int scalingFactorX = Fixed32.div(imageWidth, displayWidth); 
       int displayHeight = Fixed32.toFP(100); 
       int imageHeight = Fixed32.toFP(encodedImage.getHeight()); 
       int scalingFactorY = Fixed32.div(imageHeight, displayHeight); 
       scaledImage = encodedImage.scaleImage32(scalingFactorX, scalingFactorY); 
       callMainScreen(scaledImage, index); 
      } 
     } catch (IOException e) { 
      Dialog.alert("Insert an SD Card."); 
     } 
     finally 
     { 
      if(fileConnection!=null){ 
       try { 
        fileConnection.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
      if(inputStream!=null){ 
       try { 
        inputStream.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

} 

請幫助我如何提高我的代碼性能

+0

你爲什麼在ImageDisplayScreen中的paint()中添加一個新的位圖字段對象?它創建一個新的對象,每次調用油漆 – rfsk2010 2011-12-30 07:44:07

+0

嗨,我不使用那個類,所以現在我刪除這個類。 – 2011-12-30 09:07:48

回答

3
  1. 我會加載圖像,只有當用戶滾動屏幕。例如,在屏幕上開始加載前兩個屏幕(在不同的線程中),並在用戶下移時加載下一個屏幕。因此,請給您的經理設置ScrollListener,並使用字段位置和高度來確定屏幕上顯示的內容以及即將顯示在屏幕上的內容。

  2. 還使用有限大小的線程池和隊列進行圖像加載。不幸的是,java併發並不是j2me的標準。但是有幾個類似的模式實現,如ThreadPool

  3. 如果您還記得用戶快速滾動時的情況,那將會超級 - 如果不需要,取消預定的加載。對於每個加載任務,請記住BitmapField的位置和大小。在任務開始文件加載之前,檢查BitmapField在當前滾動位置是否可見(可見)。

另外請注意線程數。我發現當count爲6時你試圖睡主加載線程。但是仍然有很小的可能性,400 ms不足以完成當前線程的工作,並且你可以很容易地開始創建更多的線程。

而且小事 - 使用Bitmap.scaleInto(如果目標5.0以上),使用圍繞size場同步,從未使用過next,用好一點的名字,像nextImagesthreadsCount

+0

非常感謝你能否給我提供你的建議的任何鏈接:「我只會在用戶滾動屏幕時加載圖片,例如在屏幕啓動時加載前兩個屏幕(在不同的線程中)並在用戶下移時加載下一個。使用有限大小的線程池和隊列進行圖像加載,如果您還記得用戶快速滾動時的情況 - 如果不需要,則取消預定加載將會超級。 – 2011-12-30 09:11:11

+0

抱歉,延誤。我已經編輯了答案,以提供更多關於方向的細節。新年快樂! – 2012-01-01 16:52:11

相關問題