Esta clase de controlador debe ser estática o pueden producirse fugas: AsyncQueryHandler

Fugas de referencia del manejador Dado que este Handler se declara como una clase interna, puede impedir que la clase externa sea recolectada. Si el controlador utiliza un Looper o MessageQueue para un subproceso distinto del subproceso principal, no hay ningún problema. Si el controlador utiliza el Looper o MessageQueue del subproceso principal, debe corregir su declaración de controlador, de la siguiente manera: Declare el controlador como una clase estática; En la clase externa, instanciar una WeakReference a la clase externa y pasar este objeto a su Handler cuando instancie el Handler; Haga todas las referencias a miembros de la clase externa utilizando el objeto WeakReference.

¡Necesito una solución !!!!!

public class EMG_Activity extends AppCompatActivity { // An object that manages Messages in a Thread public static Handler HandlerMessager; private static AsyncQueryHandler queryHandler; private static final String EMG = "EMG"; private ManageConnectedSocket manageConnectedSocket; private Thread manageThread; private Button button_start_pause; private int id = 0; private int xValue = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_emg); queryHandler = new AsyncQueryHandler(getContentResolver()) { @Override protected void onInsertComplete(int token, Object cookie, Uri uri) { if(cookie != null) id = (int) ContentUris.parseId(uri); } }; ........... button_start_pause = (Button) findViewById(R.id.button_start_pause); button_start_pause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { .................. manageConnectedSocket = new ManageConnectedSocket(MainActivity.bluetoothDevice, MainActivity.samplingFrequency, new int[]{0}, new int[]{1, 0, 1, 1}); manageThread = new Thread(manageConnectedSocket); manageThread.start(); ContentValues values = getContentValuesExam (EMG, AlsrmSchema.PROGRESS, Utils.getCurrentDate()); queryHandler.startInsert(1, id, AlsrmContract.Exam.CONTENT_URI, values); ...... } }); } @Override public void onDestroy() { super.onDestroy(); ..... ContentValues values = getContentValuesExam (EMG, AlsrmSchema.CORRUPTED, Utils.getCurrentDate()); queryHandler.startUpdate(1, null, AlsrmContract.Exam.CONTENT_URI, values, AlsrmSchema.id + " = ? ", new String[]{"" + id}); } } } 

Considere el siguiente código:

 public class SampleActivity extends Activity { private final Handler mLeakyHandler = new Handler() { @Override public void handleMessage(Message msg) { // ... } } } 

Aunque no es obvio, este código puede causar una pérdida masiva de memoria. Android Lint dará la siguiente advertencia:

 In Android, Handler classes should be static or leaks might occur. 

Pero, ¿dónde está exactamente la fuga y cómo podría suceder? Determinemos la fuente del problema documentando primero lo que sabemos:

  1. Cuando se inicia una aplicación de Android, el framework crea un objeto Looper para el subproceso principal de la aplicación. Un Looper implementa una cola de mensajes simple, procesando objetos de mensaje en un bucle uno tras otro. Todos los principales eventos del marco de aplicación (como las llamadas al método del ciclo de vida de la actividad, los clics de botón, etc.) están contenidos dentro de los objetos de mensaje, que se agregan a la cola de mensajes del Looper y se procesan uno a uno. El Looper del hilo principal existe en todo el ciclo de vida de la aplicación.
  2. Cuando un Handler se instancia en el subproceso principal, se asocia con la cola de mensajes del Looper. Los mensajes enviados a la cola de mensajes contendrán una referencia al Handler para que el framework pueda llamar a Handler # handleMessage (Message) cuando el Looper eventualmente procese el mensaje.
  3. En Java, las clases no-estáticas internas y anónimas contienen una referencia implícita a su clase externa. Las clases internas estáticas, por el contrario, no.

Entonces, ¿dónde está exactamente la pérdida de memoria? Es muy sutil, pero considere el código siguiente como un ejemplo:

 public class SampleActivity extends Activity { private final Handler mLeakyHandler = new Handler() { @Override public void handleMessage(Message msg) { // ... } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Post a message and delay its execution for 10 minutes. mLeakyHandler.postDelayed(new Runnable() { @Override public void run() { /* ... */ } }, 1000 * 60 * 10); // Go back to the previous Activity. finish(); } } 

Cuando se termina la actividad, el mensaje retrasado continuará viviendo en la cola de mensajes del subproceso principal durante 10 minutos antes de ser procesado. El mensaje contiene una referencia al controlador de la actividad y el controlador contiene una referencia implícita a su clase externa (la SampleActivity, en este caso). Esta referencia se mantendrá hasta que se procese el mensaje, evitando así que el contexto de actividad se recolecte de basura y se filtre todos los recursos de la aplicación. Tenga en cuenta que lo mismo ocurre con la clase Runnable anónima en la línea 15. Las instancias no estáticas de clases anónimas contienen una referencia implícita a su clase externa, por lo que el contexto se filtrará.

Para solucionar el problema, subclase el controlador en un archivo nuevo o utilice una clase interna estática en su lugar. Las clases internas estáticas no tienen una referencia implícita a su clase externa, por lo que la actividad no se filtrará. Si necesita invocar los métodos de la actividad externa desde dentro del Handler, haga que el manejador mantenga una WeakReference a la actividad para que no se filtre accidentalmente un contexto. Para corregir la pérdida de memoria que se produce cuando instanciamos la clase Runnable anónima, hacemos que la variable sea un campo estático de la clase (ya que las instancias estáticas de clases anónimas no contienen una referencia implícita a su clase externa):

 public class SampleActivity extends Activity { /** * Instances of static inner classes do not hold an implicit * reference to their outer class. */ private static class MyHandler extends Handler { private final WeakReference<SampleActivity> mActivity; public MyHandler(SampleActivity activity) { mActivity = new WeakReference<SampleActivity>(activity); } @Override public void handleMessage(Message msg) { SampleActivity activity = mActivity.get(); if (activity != null) { // ... } } } private final MyHandler mHandler = new MyHandler(this); /** * Instances of anonymous classes do not hold an implicit * reference to their outer class when they are "static". */ private static final Runnable sRunnable = new Runnable() { @Override public void run() { /* ... */ } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Post a message and delay its execution for 10 minutes. mHandler.postDelayed(sRunnable, 1000 * 60 * 10); // Go back to the previous Activity. finish(); } } 

La diferencia entre las clases internas estáticas y no estáticas es sutil, pero es algo que todos los desarrolladores de Android deben entender. ¿Cuál es la línea de fondo? Evite utilizar clases internas no estáticas en una actividad si las instancias de la clase interna podrían sobrevivir al ciclo de vida de la actividad. En su lugar, prefieren las clases internas estáticas y mantener una referencia débil a la actividad dentro.

  • kotlin suprime la advertencia despreciada para android
  • ¿Por qué establecer una forma extraíble en el fondo de diseño será advertir?
  • IInAppBillingService mostrar una advertencia - método getInterfaceDescriptor nunca se utiliza localmente - ¿Cómo eliminar?
  • Advertencia de File.mkdirs desde Android Studio
  • ¿Cómo deshabilito una advertencia de eclipse en el archivo derivado IMarketBillingService.java?
  • Android - nuevo BitmapDrawable obsoleto; Alternativa Bitmap.createBitmap tiene que tener w / h> 0
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.