2012-08-02 9 views
5

Ho una vista personalizzata, che disegna un sacco di cose incluse le bitmap. Voglio mettere in cache questo disegno su una bitmap, così ho solo bisogno di disegnare una singola bitmap dentro onDraw, piuttosto che ripetere queste attività di disegno e calcolo.Dove allocare correttamente la bitmap su Android View?

Le bitmap devono essere riciclate dopo che non la utilizziamo più. Non vedo onDestroy() o nulla di simile nella classe View. Esiste un metodo di callback che posso eseguire l'override per raggiungere questo obiettivo?

public void <insert_callback_here>() { 
    cachedBitmap.recycle(); 
} 

Non c'è animazione. Questa è un'immagine statica. Ci sono un sacco di calcoli fatti per disegnare l'immagine, quindi preferirei farlo una volta su onMeasure().

risposta

7

Ho intenzione di rispondere al mio qui. I metodi appropriati per eseguire l'override sono onDetachedFromWindow. Ho deallocato la mia bitmap all'interno di onDetachedFromWindow e la riallociamo all'interno di onMeasure se la larghezza o l'altezza sono cambiate.

@Override 
protected void onDetachedFromWindow() { 
    super.onDetachedFromWindow(); 
    if (cachedBitmap != null && !cachedBitmap.isRecycled()) { 
     cachedBitmap.recycle(); 
     cachedBitmap = null; 
     cachedBitmapWidth = -1; 
     cachedBitmapHeight = -1; 
    } 
} 

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int viewWidth = MeasureSpec.getSize(widthMeasureSpec);; 
    int viewHeight = MeasureSpec.getSize(heightMeasureSpec);; 

    if (cachedBitmapWidth != viewWidth || cachedBitmapHeight != viewHeight) { 
     if (cachedBitmap != null) { 
      cachedBitmap.recycle(); 
     } 
     cachedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
     cachedBitmapWidth = viewWidth; 
     cachedBitmapHeight = viewHeight; 
     Canvas canvas = new Canvas(cachedBitmap); 
     // do drawings here.. 
    } 

    setMeasuredDimension(viewWidth, viewHeight); 
} 
+0

Questo è esattamente ciò di cui avevo bisogno. Solo per aggiungere, ho anche eseguito un System.gc() dopo aver riciclato le bitmap, perché avevo problemi con la memoria sufficiente. –

+0

Bello, ma fai attenzione alle app in cui chiami finish() da onCreate(): può creare una perdita di memoria in questo modo (vedi https://medium.com/square-corner-blog/android-leak-pattern-subscriptions -in-vista-18f0860aa74c). – RhetoricalRuvim

+0

Importante: è una cattiva pratica allocare qualsiasi cosa all'interno di onMeasure() e onDraw(). Ad esempio, a seconda della gerarchia del layout, onMeasure() viene chiamato 2 o 3 volte prima che venga determinata la dimensione finale della vista. Riallocare all'interno di onSizeChanged() sarebbe meglio. – RhetoricalRuvim

Problemi correlati