2010-11-13 29 views
0

朋友,線程重複內存不足?

我正在使用以下代碼在活動中使用線程問題場景顯示單個全屏圖像場景是從每個縮略圖上的自定義圖像庫單擊此屏幕上的顯示大圖像。

現在的問題是用戶點擊圖像和線程加載圖像,並按下返回按鈕轉到上一頁用戶不斷點擊每個縮略圖逐一顯示全屏圖像,並重復這種情況。

最後,應用程序崩潰,出現內存不足的錯誤位圖。 請指導我在做什麼錯誤?

public void Move(final String path) 
{ 
    if (!isConnected()) { 
     Constants.DisplayMessage(getApplicationContext(), 
      Constants.CONNECTION_ERROR_MESSAGE); 
     return; 
    } 

    progressBar = (ProgressBar) findViewById(R.id.progressbar_default); 
    progressBar.setVisibility(View.VISIBLE); 

    myThread = new Thread(new Runnable() { 
     public void run() { 
     while (serviceData == null) { 
      serviceData = DisplayLiveImage(path); 
      callComplete = true; 
     } 

     mHandler.post(MoveNow()); 
     } 
    }); 

    if(myThread.getState() == Thread.State.NEW) 
     myThread.start(); 
} 


private Runnable MoveNow() { 
    return new Runnable() { 
     public void run() { 
      if (callComplete) { 
       try 
       { 
        if (!serviceData.equals("")) 
        { 
         bm = (Bitmap)serviceData; 

         float ImageHeight = bm.getHeight(); 
         float ImageWidth = bm.getWidth(); 

         float totalHeight = (ImageHeight/ImageWidth) * CurrentScreenWidth; 

         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); 
         params.width = LayoutParams.FILL_PARENT; 
         params.height = (int)totalHeight; 
         img.setLayoutParams(params); 
         img.setImageBitmap(bm); 
        } 
        else 
        { 
         // show error 
        } 
       }catch(Exception ex) 
       { 
        // show error 
       }finally 
       { 
        progressBar.setVisibility(View.GONE); 
        serviceData = null; 
        callComplete = false; 
       } 
      } 
     } 
    }; 
} 

public void stopThread() 
{ 
    try 
    { 
     if(myThread != null) 
      myThread.interrupt(); 
    }catch(Exception ex) 
    { } 
} 

@Override 
public void onDestroy() 
{ 
    if(bm != null) 
    { 
     bm.recycle(); 
     bm = null; 
    } 

    stopThread(); 
    super.onDestroy(); 
} 

回答

2

您是否在內存不足錯誤發生時運行調試程序?如果是這樣,那麼調試器可能是問題的根源。如果您在調試器下運行該應用程序,那麼即使已經完成運行,所創建的任何線程仍會被調試器保留。這會導致應用程序在沒有調試器的情況下運行時不會發生的內存錯誤。嘗試在沒有調試器的情況下運行,看看是否仍然存在內存泄漏。

http://code.google.com/p/android/issues/detail?id=7979

https://android.googlesource.com/platform/dalvik/+/master/docs/debugger.html

如果不是這種情況,那麼請嘗試使用Eclipse的內存分析器追查什麼內存問題可能是。 http://www.eclipse.org/mat/

2

位圖是使用Android管理最煩人的事情。

爲了避免最讓我用OOM異常:

//Try to free up some memory 
System.gc(); 
System.runFinalization(); 
System.gc(); 

是的,你沒有看錯2的System.gc ...去圖:■

只是想對它進行解碼之前。所以在你的情況下,它會在我假定的setImageBitmap之前。但看看你的logcats,並把它放在讓你的應用程序崩潰的行之前。

如果仍然發生,則在分配位圖時,嘗試使用bitmapOtions.insamplesize打開較小版本的位圖。

+2

強制'System.gc()'不保證釋放內存,甚至導致意外的錯誤 – 2016-01-08 15:42:59