2011-08-31 9 views
30

我創建了一個GalleryView和ImageView,它在圖庫中單擊一個項目時顯示較大的圖像。我用下面的代碼來實現ImageAdapter:TypedArray中recycle()方法的用法

public ImageAdapter(Context c) 
{ 
    context = c; 
    TypedArray a = obtainStyledAttributes(R.styleable.gallery1); 
    itemBackground = a.getResourceId(R.styleable.gallery1_android_galleryItemBackground, 0);  
    a.recycle();  
} 

當我刪除了聲明a.recycle()沒有變化,像以前的應用程序運行正常,但我到處看,這是強制回收的typedArray。當我的應用運行方式沒有改變時,recycle()方法的用法是什麼。

任何人都可以請詳細解釋我。謝謝。

回答

25

這一點類似於用C語言清除指針的想法(如果您熟悉這一點)。它用於使與「a」相關聯的數據準備好進行垃圾收集,因此在不需要時內存/數據不會被低效地綁定到「a」。閱讀更多here。重要的是要注意,除非實際上重複使用「a」,否則這不是必須的。如果對象不再使用,GC應自動清除這些數據。然而,TypedArray的原因不同,因爲TypedArray具有必須返回的其他內部數據(稱爲StyledAttributes)到TypedArray以備後用。閱讀關於here

+2

邊注意:GC代表「垃圾回收」。 – Vinay

+3

我不明白。最後一個鏈接看起來像調用recycle()允許一些內部數組被重用。這是不是意味着它阻止了數組被GCed?你爲什麼說它使與「a」相關的數據準備好用於GC? – gsingh2011

+0

@ gsingh2011它允許它「被以後的調用者重新使用」。無可否認,文檔的措辭有些尷尬,但是他們得到的是與TypedArray相關的內存可以被更高的調用者重用(而不是你自己在程序範圍內理解的實例本身)。這就是爲什麼文檔也說「調用這個函數後,你不能再次觸摸類型數組。」。 – Vinay

5

recycle()導致分配的內存立即返回到可用池,直到垃圾收集時纔會保留。該方法也可用於Bitmap

0

回收基本上是指..自由/清除所有與相應資源相關的數據。 在Android中,我們可以找到Bitmap和TypedArray的回收站。

如果你檢查兩個源文件,那麼你可以找到一個布爾變量「mRecycled」,它是「false」(默認值)。它在調用回收時被分配到「true」。

所以,現在如果你檢查該方法(在這兩個類中的回收方法),那麼你可以觀察到他們正在清除所有的值。

這裏有參考的方法。

Bitmap.java:

public void recycle() { 
    if (!mRecycled && mNativePtr != 0) { 
     if (nativeRecycle(mNativePtr)) { 
      // return value indicates whether native pixel object was actually recycled. 
      // false indicates that it is still in use at the native level and these 
      // objects should not be collected now. They will be collected later when the 
      // Bitmap itself is collected. 
      mBuffer = null; 
      mNinePatchChunk = null; 
     } 
     mRecycled = true; 
    } 
} 

TypedArray.java

public void recycle() { 
    if (mRecycled) { 
     throw new RuntimeException(toString() + " recycled twice!"); 
    } 

    mRecycled = true; 

    // These may have been set by the client. 
    mXml = null; 
    mTheme = null; 
    mAssets = null; 

    mResources.mTypedArrayPool.release(this); 
} 

此行

mResources.mTypedArrayPool.release(this); 

將其默認值是5 所以你SunchronisedPool釋放typedArray不應該再次使用相同的typedArray,因爲它被清除。

一旦TypedArray的「mRecycled」爲true,那麼在獲取其屬性時,它將拋出RuntimeException,說「無法調用回收實例!」。

同樣的行爲也包含在Bitmap中。 希望它有幫助。