2011-12-30 11 views
0

こんにちは私はここSDCardからアプリケーションに画像を読み込む際のパフォーマンスを向上させる方法は?

次のようなものですすべてのSDカードの画像がサムネイルとしての私のアプリケーションで表示するプログラムを.MY表示すべき表示するために一つの小さなアプリケーションを作っ問題シミュレータで、それは電話として、それは多くの時間がかかるところ、迅速かつ正確にロードしていることです。それは問題を起こさないように30MBのものの一部が読み込まれます。 whareそれはそれの周りの80MBは私の画面上に画像を表示されていません。

注:これは完全にシミュレータで働いているが、未機器 と私のイメージのパスは「ファイル:/// SDカード/画像/」である私のコードがある :

これは私のアプリケーションスタータークラス

です
public class StartUp extends UiApplication{ 

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

これはこれは私のImageThread.java

である私の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; 
    } 
} 

です

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()に新しいbitmapfieldオブジェクトを追加しますか?それは、塗料が – rfsk2010

+0

と呼ばれるたびに新しいオブジェクトを作成します。こんにちは、私はこのクラスをどこでも使用していないので、このクラスを削除します。 –

答えて

3
  1. を高めるためにどのように私を助けてください。例えば、最初の2つの画面を(別のスレッドで)画面の開始時に読み込み、ユーザーが下に移動するときに次に読み込みます。したがって、あなたのマネージャーにScrollListenerを設定し、項目の高さと高さを使用して、画面に表示されているものとすぐに画面に表示されるものを判断します。

  2. イメージの読み込みには、制限されたサイズのスレッドプールとキューも使用してください。残念ながら、javaの同時実行はj2meと同じではありません。しかし、ThreadPoolのような類似のパターン実装がいくつかあります。

  3. また、ユーザーが高速にスクロールする場合も覚えていれば、超過します - スケジュールされた読み込みをキャンセルする必要がない場合はキャンセルしてください。すべての読み込みタスクについて、位置とサイズをBitmapFieldと覚えておいてください。タスクがファイルロードを開始する前に、現在のスクロール位置でBitmapFieldが表示されているかどうかを確認します(表示されるようになります)。

スレッド数についても気をつけてください。カウントが6のときにメインの読み込みスレッドをスリープしようとしているのがわかります。しかし、現在のスレッドの作業を終了するには400ミリ秒では不十分で、さらに多くのスレッドを簡単に作成することができます。

またマイナーなもの - nextImagesthreadsCountのような少し良く名前を使用し、sizeフィールドの周囲に、使用同期(あなたがターゲットにする場合5.0以上である)nextが使用されることはありませんBitmap.scaleIntoを使用するなど

+0

ありがとうございます、私はあなたの提案のために私にあなたの提案を提供してくれてありがとう "私は画面をスクロールするときだけイメージを読み込みます。例えば、画面の最初の2つの画面を別のスレッドに読み込み、限られたサイズのスレッドプールとキューを使用して画像を読み込むことができます。 –

+0

遅れて申し訳ありません。私は行く方向についての詳細を与えるために答えを編集しました。明けましておめでとうございます! –

関連する問題