2010-06-30 6 views
1

버튼에 약 100 개의 아이콘 (각 50x50)을 표시해야합니다. 나는 100 개의 아이콘이 모두 들어있는 큰 PNG Image를 다운로드하고, Image.subImage() 메서드를 사용하여 각 아이콘을 만든다.많은 아이콘 또는 하나의 이미지 아이콘이있는 큰 이미지?

그러나 내 응용 프로그램은 OutOfMemoryError이됩니다.

  1. 다운로드 파일 (단일 결합) 타르 100 개 아이콘 :

    나는이 약이 솔루션을 생각하고있다. 그래서 나는 하나씩 아이콘을 만들 수 있습니다. 큰 이미지는 내가 마지막 아이콘을 만들 때까지 메모리에있을 필요가 없습니다.

  2. 큰 이미지를 다운로드하지만 작은 아이콘을 만들지 마십시오. 그러면 버튼이 큰 이미지에서 이미지 (아이콘)를 페인팅합니다.

어떤 솔루션이 가장 좋습니까? 또는이 문제에 대한 다른 해결책이 있습니까?

답변

2

LWUIT는 소형 장치 용으로 설계되었으므로 코드를 설계해야합니다. 따라서 큰 이미지는 좋은 생각이 아닙니다.

정말 별개의 이미지를 사용해야합니다. 당신이 볼 수있는 것을 기억 속에 보관하십시오. 또는 메모리 부족 오류가 계속 발생할 수 있습니다.

나는 이것을 이렇게 처리 할 것이다. cachemap을하십시오. 이미지를 원하면 cachemap에 아직 없는지 확인하십시오. (있는 경우), 이미지를 다운로드하지 않았 으면 cachemap 에서 이미지를 사용하고 이미지를 cachemap에 넣으십시오. 메모리가 부족하면 cachemap에서 마지막 이미지를 제거하고 새 이미지를 다운로드하십시오.

if (imageCache.get(url) != null) { 
     //#debug 
     System.out.println("Get cached image from: " + url); 

     asyncImage.setImage((Image) imageCache.get(url)); 
     asyncImage.setQueued(false); 
    } else { 
     //#debug 
     System.out.println("Start download image from:" + url); 

     map.put(url, asyncImage); 

     ImageDownloadService d = new ImageDownloadService(url, new ActionListener() { 

      public void actionPerformed(ActionEvent evt) { 

       NetworkEvent n = (NetworkEvent) evt; 
       Image image = (Image) n.getMetaData(); 
       String url = n.getConnectionRequest().getUrl(); 
       AsyncImage asyncImage = (AsyncImage) ImageManager.this.map.get(url); 
       map.put(url, asyncImage); 
       asyncImage.setImage(image); 
       map.remove(url); 
       imageCache.put(url, asyncImage.getImage()); 
       asyncImage.setQueued(false); 
       if (Display.getInstance().getCurrent() instanceof AsyncLoadable) { 
        ((AsyncLoadable) Display.getInstance().getCurrent()).asyncLoaded(); 
       } else { 
        Display.getInstance().getCurrent().repaint(); 
       } 
       //#debug 
       System.out.println("Retrieved image from:" + url); 
      } 
     }); 
     d.addResponseCodeListener(new ActionListener() { 

      public void actionPerformed(ActionEvent evt) { 
       NetworkEvent n = (NetworkEvent) evt; 
       String url = n.getConnectionRequest().getUrl(); 
       AsyncImage asyncImage = (AsyncImage) ImageManager.this.map.get(url); 
       asyncImage.setQueued(false); 
       map.remove(n.getConnectionRequest().getUrl()); 
       //#debug 
       System.out.println("Failed image from:" + url); 
      } 
     }); 

     NetworkManager.getInstance().addToQueue(d); 
+1

답변이 정확하므로 투표 해 보았습니다. 그러나 멋진 캐시 맵은 필요하지 않습니다. EncodedImage 클래스는 LWUIT (리소스에서로드 된 이미지에 기본적으로 사용됨)에 있으며 인코딩 된 이미지를 그 안에 저장합니다. 즉, 기본적으로 훨씬 적은 메모리를 차지합니다. RAM에 데이터를 보관하지 않는 List와 결합하면 GC가 모든 비트 맵 이미지 데이터를 즉시 수집 할 수 있습니다. –