2011-03-29 84 views
5

我有一個服務器/客戶端應用程序,我從服務器通過Hessian/hessdroid檢索數據。數據非常複雜,包含其他HashMaps和圖像存儲在字節數組中的HashMaps。我可以完美地顯示數據。HashMap反序列化

爲了不總是查詢服務器,我使用數據結構作爲緩存。此數據對象在關閉應用程序時使用ObjectOutputStream保存到SD卡。當我重新啓動它時,我用ObjectInputStream將其讀回內存。

我只有在從SD卡讀取數據後纔會遇到應用程序問題。 logcat的給我下面的輸出(100次):

DEBUG/dalvikvm(4150): GetFieldID: unable to find field Ljava/util/HashMap;.loadFactor:F 

,這在其他消息之間:

INFO/dalvikvm-heap(4150): Grow heap (frag case) to 10.775MB for 281173-byte allocation 

當堆增長時〜17 MB應用程序崩潰。

我讀了幾個有關HashMap序列化的線程,並且在架構之間序列化時似乎存在一個錯誤,但對於我來說,通過Hessian完成的數據傳輸完美,並且只有在從磁盤讀取HashMaps時纔會遇到上述問題。

任何想法?

+0

請你可以發佈你加載和反序列化數據的代碼嗎? – 2011-04-06 23:03:34

+0

請添加完整的日誌貓轉儲和Earl先生提到的源代碼。從你在這裏陳述的內容來看,它更像是一個內存不足的問題(也許這將有助於http://code.google.com/p/android/issues/detail?id=14869)。 – 2011-05-25 16:14:53

回答

2

這個問題與HashMap反序列化沒有直接關係,正如網絡和尚評論的那樣。 Android中確實存在某種錯誤或者它的HashMap實現,但我不認爲它是應用程序崩潰的原因。

現在我解決了這個問題,在應用程序中使用較少的圖像。例如,我有一個畫廊,您可以在一個畫布上從一個圖像滑動到另一個圖像,並一次加載所有圖像。在一定數量的圖像中,沒有足夠的堆空間。

我的解決方案是,不要一次保留所有解碼圖像。

It's這樣完成的:

1)在存儲器中保持的二值圖像數據(只要圖像是沒有那麼大不是問題)

2)鴕鳥政策裝載二進制在創建鰭狀肢的視圖時將圖像數據輸入到ImageView中。

3)將二進制圖像數據設置到顯示的ImageView中。接下來的和更好的用戶體驗最後的ImageView)

5)「卸載」的ImageViews的不是由它的資源設置透明色顯示

4)保持二進制圖像數據。

Here's一些代碼:

// initialize the viewFlipper by creating blank views 
for (ComponentImageDto listElement : images) { 
    LinearLayout view = renderView(); 
    flipper.addView(view); 
} 
showImage(flipper.getCurrentView()); 

的RenderView()只返回含有ImageView的

然後寫一些方法中,以顯示下一個/前一個圖像,其中我設置二進制數據的LinearLayout到ImageView的:

private void showNextElement() { 
    // show next flipper view 
    flipper.showNext(); 

    // get current view 
    int displayedChild = flipper.getDisplayedChild(); 
    View currentView = flipper.getCurrentView(); 

    // load the binary data 
    showImage(currentView); 

    // get the next to last view index (if keeping max. 3 images at a time in memory) 
    int otherChild = (displayedChild - 2); 
    if (otherChild < 0) { 
     otherChild = otherChild + flipper.getChildCount(); 
    } 

    // .. and remove it 
    removeImage(flipper.getChildAt(otherChild)); 
} 

private void showPreviousElement() { 
    flipper.showPrevious(); 
    int displayedChild = flipper.getDisplayedChild(); 
    View currentView = flipper.getCurrentView(); 
    showImage(currentView); 
    setTitle((CharSequence) currentView.getTag()); 
    int otherChild = (displayedChild + 2) % flipper.getChildCount(); 
    removeImage(flipper.getChildAt(otherChild)); 
} 

private void removeImage(View view) { 
    ImageView imageView = (ImageView) view.findViewById(R.id.gallery_image); 
    if (imageView != null) { 
     imageView.setImageResource(R.color.transparent); 
     System.gc(); 
    } 
} 

private void showImage(View view) { 
    ImageView imageView = (ImageView) view.findViewById(R.id.gallery_image); 
    if (imageView != null) { 
     bm = BitmapHelper.decodeByteArray(images.get(flipper.getDisplayedChild()).getImage().getBinaryObject()); 
     imageView.setImageBitmap(bm); 
    } 
} 

要furtherly提高使用I'm在BitmapHelper類一些代碼,我計算器上找到的內存處理,這有助於節省內存通過減小圖像尺寸來獲得圖像。