2013-08-13 6 views
6

Sto utilizzando un oggetto handler per continuare il lavoro dell'interfaccia utente dopo aver terminato un'attività che richiede molto tempo in un thread separato. Ho avuto un problema con l'avviso Lint di cui sopra e il mio approccio.Threading Android: questa classe del gestore deve essere statica o potrebbero verificarsi perdite.

[Esempio Handler tipo di oggetto 1] ->

Handler responseHandler = new Handler() 
{ 
    @Override 
    public void handleMessage(Message msg) 
    { 
     super.handleMessage(msg); 
     Toast.makeText(MainActivity.this, "Finished the long running task in seperate thread...", Toast.LENGTH_LONG).show(); 
    }  
}; 

[Esempio Handler tipo di oggetto 2] ->

Handler responseHandler = new Handler(new Handler.Callback() 
{  
    @Override 
    public boolean handleMessage(Message msg) 
    { 
     Toast.makeText(MainActivity.this, "Finished long running task in a seperate thread...", Toast.LENGTH_LONG).show(); 
     return false;  // RETURN VALUE ???? 
    } 
}); 

Nel separata thread (diverso da UI) wh it l'operazione che richiede tempo, viene eseguita la seguente riga per riportare il controllo sul thread dell'interfaccia utente (in pratica verso il gestore obj).

responseHandler.sendEmptyMessage(0); 

Il programma funziona davvero bene con entrambi i tipi di oggetti del gestore, ma con 1 ° tipo sto ottenendo un avvertimento dicendo Lint classe Questo gestore dovrebbe essere statici o perdite potrebbero verificarsi.

Quindi ho iniziato ad utilizzare il secondo tipo di oggetto gestore per evitare l'avviso Lint ma il problema che ho è, non sono sicuro del significato del valore restituito (vero/falso) nel 2o modo anche funziona con entrambi. Ho cercato questo in google per così tanto ma non ho ottenuto una risposta esatta spiegata questo valore di ritorno.

Sì, ho visto questa domanda in molti casi in StackOverflow che ricominciava principalmente con l'avviso Lint, ma la mia domanda riguarda principalmente il tipo di ritorno nel 2o modo e per confermare se va bene il modo in cui risolvo il problema utilizzando il 2 ° tipo di gestore Obj.

Domande ->

1). Qualcuno sa cosa esattamente questo restituisce valore significa (vero/falso)?

2). È la cosa corretta che ho fatto per eliminare l'avviso di lanugine?

Grazie ...

+0

Sì, è possibile controllare il post collegato. –

+0

Ho visto questi collegamenti e la mia domanda riguarda principalmente il valore di ritorno in cui ho trovato la spiegazione. – JibW

+0

http://stackoverflow.com/questions/17899328/this-handler-class-should-be-static-or-leaks-might-occur-com-test-test3-ui-main/17899429#17899429. controlla questo e questo https://groups.google.com/forum/#!topic/android-developers/1aPZXZG6kWk. controlla la discussione sull'argomento e la soluzione di romain guy. – Raghunandan

risposta

1

ho trovato alcune importanti informazioni sulla perdita di memoria da classe interna come conduttore e voglio condividere con voi:

How to Leak a Context: Handlers & Inner Classes e credo che il metodo override di classe Handler non tornerà nulla come è possibile controllare: handleMessage()

Hai ignorato classe Java Handler non Android Handler, si può vedere handleMessage() della classe Java Handler sta avendo dichiarazione di ritorno e si può controllare la ragione anche per istruzione return qui: boolean handleMessage(C context)

5

Ogni gestore è associato allo Looper di una discussione, ogni Message viene inserito in una struttura dati, una coda di messaggi.

Message ha una variabile target che punta a un Handler, una variabile callback che punta a un Runnable.

Quindi, se si utilizza una classe anonima per creare un oggetto Handler (come nel primo esempio), allora sapere che le classi interne anonime/non statiche contengono un riferimento agli oggetti esterni (Attività?). Pertanto, il messaggio inviato in coda potrebbe contenere riferimenti allo Handler come destinazione e lo Handler a sua volta contenente un riferimento alla classe esterna, ad esempio Activity.

Ora, un messaggio può rimanere nella coda messaggi per lunghi intervalli di tempo, a condizione che il thread sia in esecuzione. Nel frattempo, l'attività potrebbe essere stata respinta. Ma non sarà spazzatura raccolta a causa dell'oscuro riferimento indiretto di esso, che il messaggio ha. Si noti che Looper e Coda messaggi restano intorno finché il thread è in esecuzione.

Nel secondo esempio, non si sta creando una classe anonima Handler. Stai utilizzando il gestore handler e passandogli un oggetto anonimo Callback. Questo potrebbe impedire a Lint di lamentarsi, ma dubito che questo sia un buon approccio. Evita solo le classi interne, evita di far passare Attività o riferimenti di contesto a Gestore.

Aggiornamento:

The Handler del dispatchMessage() ottiene i messaggi a causa di essere elaborati, dove si controlla se è stata fornita una richiamata, poi se non viene fornito richiamata, non chiama handleMessage(), se handleMessage() rendimenti di callback vero :

public void dispatchMessage(Message msg) { 
    if (msg.callback != null) { 
     handleCallback(msg); 
    } else { 
     if (mCallback != null) { 
      if (mCallback.handleMessage(msg)) { 
       return; 
      } 
     } 
     handleMessage(msg); //--won't be called if you return true. 
    } 
} 
Problemi correlati