L'attività principale non è il garbage raccolto dopo la distruzione perché è indirettamente indirizzato da InputMethodManager

Ho seguito l'articolo "Evitare perdite di memory" da qui .

Tuttavia la soluzione proposta non risolve il problema della perdita. Ho provato questo con emulatore android su Windows XP (SDK 2.3.1). Ho buttato il mucchio e ho controllato che l'attività principale è ancora nel mucchio (ho usato MAT)

  • come avviare l'attività dopo il button widget è premuto?
  • Android invia SMS a più contatti utilizzando ArrayList
  • Immagine non ritagliata
  • Android: Rilevamento delle perdite con Eclipse Memory Analyzer
  • La radice ADB non funziona sull'emulatore
  • Come passare tra i frammenti durante l'onclick?
  • Ecco cosa ho fatto:

    1. creare applicazione HelloWorld con HelloWorldActivity (non ha viste per bambini)
    2. eseguire l'emulatore e lanciare l'applicazione HelloWorld.
    3. chiuderla facendo clic su back-key.
    4. Causa gc in DDMS e dump heap <- Qui ho trovato l'istanza HelloWorldActivity.
    5. "Percorso alle radici di GC" da esso mostra il seguente path.

    HelloWorldActivity <- PhoneWindow $ DecorView <- InputMethodManager

    InputMethodManager è un singleton e tre riferimenti a DecorView che riferiscono HelloWorldActivity.

    Non riesco a capire perché InputMethodManager ancora riport l'istanza di DecorView anche dopo che l'attività viene distrutta.

    C'è un modo per assicurarsi che l'attività principale sia distrutta e GC-capable dopo la chiusura?

  • Aggiungere un effetto di rumore ad un disegno
  • Come giocare a radio live stream .asx video / x-ms-asf?
  • Android triggers gps con AlertDialog: come attendere l'utente per agire?
  • Come get il token di accesso dopo che l'utente è connesso da Gmail in Android?
  • Font Tamil in Android
  • Come utilizzare il componente aggiuntivo SDK di Android?
  • 3 Solutions collect form web for “L'attività principale non è il garbage raccolto dopo la distruzione perché è indirettamente indirizzato da InputMethodManager”

    Sembra che la chiamata di methods InputMethodManager 'windowDismissed' e 'startGettingWindowFocus' fanno la roba.

    Qualcosa come questo:

    @Override protected void onDestroy() { super.onDestroy(); //fix for memory leak: http://code.google.com/p/android/issues/detail?id=34731 fixInputMethodManager(); } private void fixInputMethodManager() { final Object imm = getSystemService(Context.INPUT_METHOD_SERVICE); final Reflector.TypedObject windowToken = new Reflector.TypedObject(getWindow().getDecorView().getWindowToken(), IBinder.class); Reflector.invokeMethodExceptionSafe(imm, "windowDismissed", windowToken); final Reflector.TypedObject view = new Reflector.TypedObject(null, View.class); Reflector.invokeMethodExceptionSafe(imm, "startGettingWindowFocus", view); } 

    Codice riflettore:

     public static final class TypedObject { private final Object object; private final Class type; public TypedObject(final Object object, final Class type) { this.object = object; this.type = type; } Object getObject() { return object; } Class getType() { return type; } } public static void invokeMethodExceptionSafe(final Object methodOwner, final String method, final TypedObject... arguments) { if (null == methodOwner) { return; } try { final Class<?>[] types = null == arguments ? new Class[0] : new Class[arguments.length]; final Object[] objects = null == arguments ? new Object[0] : new Object[arguments.length]; if (null != arguments) { for (int i = 0, limit = types.length; i < limit; i++) { types[i] = arguments[i].getType(); objects[i] = arguments[i].getObject(); } } final Method declaredMethod = methodOwner.getClass().getDeclaredMethod(method, types); declaredMethod.setAccessible(true); declaredMethod.invoke(methodOwner, objects); } catch (final Throwable ignored) { } } 

    Se capisco la tua domanda correttamente, la risposta è: no, non puoi assicurarti che l'attività sia gc'ed. Dovrebbe essere stato chiamato il metodo onDestroy () del tuo attività e chiudere l'attività. Ciò non significa, tuttavia, che il process sia ucciso o che l'attività sia gc'ed; gestito dal sistema.

    Ho notato che alcuni ascoltatori tendono a tenere un riferimento all'attività in alcune circostanze, anche dopo che l'attività è stata finita. Una rotazione dal ritratto al paesaggio può, ad esempio, riavviare la tua attività e, se sei disfatta, la tua prima attività non viene gc-ed correttamente (nel mio caso a causa di alcuni ascoltatori che ancora detengono un riferimento).

    Essendo un ex programmatore C / C ++, l'ho impiantato nella mia spina dorsale per "distriggersre" tutti gli ascoltatori in Activity.onDestroy () ( setXyzListener(null) ).

    EDIT:

    Proprio come ha commentato Ted qui di seguito, bisogna davvero "impostare" e "non impostare" gli ascoltatori in Activity.onResume() e Activity.onPause() rispettivamente.

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.