vacia samsung nada memoria llena liberar interno interna esta espacio como celular borrar aplicaciones almacenamiento android handler

samsung - Controladores y fugas de memoria en Android



memoria interna llena android sin aplicaciones (6)

Por favor, eche un vistazo al siguiente código:

public class MyGridFragment extends Fragment{ Handler myhandler = new Handler() { @Override public void handleMessage(Message message) { switch (message.what) { case 2: { ArrayList<HashMap<String,String>> theurls = (ArrayList<HashMap<String,String>>) message.obj; urls.addAll(theurls); theimageAdapter.notifyDataSetChanged(); dismissBusyDialog(); break; }}}}; }

Cuando uso un controlador como este, aparece una advertencia: "el controlador debe ser estático, de lo contrario es propenso a las fugas de memoria". ¿Puede alguien decirme cuál es la mejor manera de hacer esto?


Aquí hay una pequeña clase algo útil que hice que puedes usar. Lamentablemente todavía es bastante detallado porque no puedes tener clases internas estáticas anónimas.

import java.lang.ref.WeakReference; import android.os.Handler; import android.os.Message; /** A handler which keeps a weak reference to a fragment. According to * Android''s lint, references to Handlers can be kept around for a long * time - longer than Fragments for example. So we should use handlers * that don''t have strong references to the things they are handling for. * * You can use this class to more or less forget about that requirement. * Unfortunately you can have anonymous static inner classes, so it is a * little more verbose. * * Example use: * * private static class MsgHandler extends WeakReferenceHandler<MyFragment> * { * public MsgHandler(MyFragment fragment) { super(fragment); } * * @Override * public void handleMessage(MyFragment fragment, Message msg) * { * fragment.doStuff(msg.arg1); * } * } * * // ... * MsgHandler handler = new MsgHandler(this); */ public abstract class WeakReferenceHandler<T> extends Handler { private WeakReference<T> mReference; public WeakReferenceHandler(T reference) { mReference = new WeakReference<T>(reference); } @Override public void handleMessage(Message msg) { if (mReference.get() == null) return; handleMessage(mReference.get(), msg); } protected abstract void handleMessage(T reference, Message msg); }


De acuerdo con los cambios de ADT 20 , parece que deberías hacerlo estático.

Nuevos controles de pelusa:

Asegúrate de que las clases de Fragmentos sean instantáneas. Si accidentalmente convierte un fragmento en no clase estático, u olvida tener un constructor predeterminado, puede golpear los errores de tiempo de ejecución cuando el sistema intente restablecer su fragmento después de un cambio de configuración.

Busque fugas en el manejador: esta verificación garantiza que una clase interna del manejador no tenga una referencia implícita a su clase externa.


Me encuentro con el mismo problema y me parece que es uno de estos temas con muchas preguntas y pocas respuestas. Mi solución es simple y espero que pueda ayudar a alguien:

/* BEFORE */ private Handler mHandler= new Handler() { @Override public void handleMessage(Message msg) { this.doSomething(); }; };

Podemos crear una subclase de Handler estática que simplemente ejecuta un Runnable. La instancia del controlador real sabrá qué hacer a través del ejecutable que tendrá acceso a las variables de la instancia.

/* AFTER */ static class RunnableHandler extends Handler { private Runnable mRunnable; public RunnableHandler(Runnable runnable) { mRunnable = runnable; } @Override public void handleMessage(Message msg) { mRunnable.run(); }; } private RunnableHandler mHandler = new RunnableHandler(new Runnable() { @Override public void run() { this.doSomething(); } });

La advertencia se ha ido mientras que la funcionalidad es la misma.


Recientemente he actualizado algo similar en mi propio código. Acabo de hacer de la clase Handler anónima una clase interna protegida y la advertencia de Lint desapareció. Vea si algo como el siguiente código le funcionará:

public class MyGridFragment extends Fragment{ static class MyInnerHandler extends Handler{ WeakReference<MyGridFragment> mFrag; MyInnerHandler(MyGridFragment aFragment) { mFrag = new WeakReference<MyGridFragment>(aFragment); } @Override public void handleMessage(Message message) { MyGridFragment theFrag = mFrag.get(); switch (message.what) { case 2: ArrayList<HashMap<String,String>> theurls = (ArrayList<HashMap<String,String>>) message.obj; theFrag.urls.addAll(theurls); theFrag.theimageAdapter.notifyDataSetChanged(); theFrag.dismissBusyDialog(); break; }//end switch } } MyInnerHandler myHandler = new MyInnerHandler(this); }

Puede que tengas que cambiar donde pongo "theFrag". Como solo pude adivinar en cuanto a lo que hacen referencia.


Si lees documentos sobre AccountManager o PendingIntent, verás que algunos métodos toman Handler como uno de los argumentos.

Por ejemplo :

  • onFinished: el objeto para devolver la llamada cuando el envío se ha completado, o nulo para no devolver la llamada.
  • handler: controlador que identifica el subproceso en el que debe producirse la devolución de llamada . Si es nulo, la devolución de llamada se realizará desde el grupo de subprocesos del proceso.

Imagina la situación. Algunas actividades llaman a PendingIntent.send (...) y ponen la subclase interna no estática de Handler. Y entonces se destruye la actividad. Pero la clase interior vive.

La clase interna todavía tiene un enlace a la actividad destruida, no puede ser recogida de basura.

Si no planea enviar su controlador a tales métodos, no tiene nada de qué preocuparse.


Una solución simple para este caso podría ser:

Handler handler=new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message message) { //do your stuff here return false; } });