viral trata que moto hoy android android-studio-2.2

android - trata - video viral de la moto



Advertencia: no coloque clases de contexto de Android en campos estáticos; Esta es una pérdida de memoria(y también rompe la ejecución instantánea) (6)

Android Studio:

No coloque clases de contexto de Android en campos estáticos; Esta es una pérdida de memoria (y también rompe la ejecución instantánea)

Entonces 2 preguntas:

# 1 ¿Cómo se llama a startService desde un método estático sin una variable estática para el contexto?
# 2 ¿Cómo se envía un LocalBroadcast desde un método estático (igual)?

Ejemplos:

public static void log(int iLogLevel, String sRequest, String sData) { if(iLogLevel > 0) { Intent intent = new Intent(mContext, LogService.class); intent.putExtra("UPDATE_MAIN_ACTIVITY_VIEW", "UPDATE_MAIN_ACTIVITY_VIEW"); mContext.startService(intent); } }

o

Intent intent = new Intent(MAIN_ACTIVITY_RECEIVER_INTENT); intent.putExtra(MAIN_ACTIVITY_REQUEST_FOR_UPDATE, sRequest)); intent.putExtra(MAIN_ACTIVITY_DATA_FOR_VIEW, sData); intent.putExtra(MAIN_ACTIVITY_LOG_LEVEL, iLogLevel); LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);

¿Cuál sería la forma correcta de hacer esto sin usar mContext ?

NOTA: Creo que mi pregunta principal podría ser cómo pasar el contexto a una clase de la que vive el método de llamada.


En general, evite tener campos de contexto definidos como estáticos. La advertencia en sí explica por qué: es una pérdida de memoria. Sin embargo, romper la ejecución instantánea puede no ser el mayor problema en el planeta.

Ahora, hay dos escenarios donde obtendría esta advertencia. Para una instancia (la más obvia):

public static Context ctx;

Y luego está el más complicado, donde el contexto está envuelto en una clase:

public class Example{ public Context ctx; //Constructor omitted for brievety }

Y esa clase se define como estática en alguna parte:

public static Example example;

Y recibirás la advertencia.

La solución en sí es bastante simple: no coloque campos de contexto en instancias estáticas , ya sea de una clase de ajuste o declarándola estática directamente.

Y la solución a la advertencia es simple: no coloque el campo estáticamente. En su caso, pase el contexto como una instancia al método. Para las clases donde se realizan múltiples llamadas de contexto, use un constructor para pasar el contexto (o una actividad para el caso) a la clase.

Tenga en cuenta que es una advertencia, no un error. Si por alguna razón necesita un contexto estático, puede hacerlo. Aunque crea una pérdida de memoria cuando lo hace.


En su caso, no tiene mucho sentido tenerlo como campo estático, pero no creo que sea malo en todos los casos. Si ahora qué está haciendo, puede tener un campo estático que tiene contexto y luego anularlo. Estoy creando una instancia estática para mi clase de modelo principal que tiene contexto dentro, su contexto de aplicación no contexto de actividad y también tengo un campo de clase estática de clase que contiene Actividad que anulo en destruir. No veo que tenga pérdida de memoria. Entonces, si algún tipo inteligente piensa que estoy equivocado, siéntase libre de comentar ...

También Instant Run funciona bien aquí ...


Es solo una advertencia. No te preocupes Si desea utilizar un contexto de aplicación, puede guardarlo en una clase "singleton", que se utiliza para guardar toda la clase singleton en su proyecto.


Si se asegura de que sea un contexto de aplicación. Es importante. Agrega esto

@SuppressLint("StaticFieldLeak")


Simplemente páselo como parámetro a su método. No tiene sentido crear una instancia estática de Context único fin de iniciar un Intent .

Así es como debería verse su método:

public static void log(int iLogLevel, String sRequest, String sData, Context ctx) { if(iLogLevel > 0) { Intent intent = new Intent(ctx, LogService.class); intent1.putExtra("UPDATE_MAIN_ACTIVITY_VIEW", "UPDATE_MAIN_ACTIVITY_VIEW"); ctx.startService(intent); } }

Actualización de los comentarios sobre la pregunta: conecte en cascada el contexto desde la actividad de inicio (a través de los parámetros del constructor o los parámetros del método) hasta el punto que lo necesite.


Solo asegúrese de pasar context.getApplicationContext () o llamar a getApplicationContext () en cualquier contexto que se pase a través de métodos / constructor a su singleton si decide almacenarlo en cualquier campo miembro.

ejemplo de prueba idiota (incluso si alguien pasara una actividad, tomará el contexto de la aplicación y la usará para crear una instancia del singleton):

public static synchronized RestClient getInstance(Context context) { if (mInstance == null) { mInstance = new RestClient(context.getApplicationContext()); } return mInstance; }

getApplicationContext () de acuerdo con los documentos: "Devuelve el contexto del único objeto de aplicación global del proceso actual".

Significa que el contexto devuelto por "getApplicationContext ()" vivirá durante todo el proceso y, por lo tanto, no importa si almacena una referencia estática en cualquier lugar, ya que siempre estará allí durante el tiempo de ejecución de su aplicación (y sobrevivirá a cualquier objeto / singletons instanciados por él).

Compare eso con el contexto dentro de las vistas / actividades que contienen grandes cantidades de datos, si pierde un contexto en una actividad, el sistema no podrá liberar ese recurso que obviamente no es bueno.

Una referencia a una actividad por su contexto debe vivir el mismo ciclo de vida que la actividad misma, de lo contrario mantendrá al contexto como rehén causando una pérdida de memoria (que es la razón detrás de la advertencia de pelusa).

EDITAR: Para el tipo que critica el ejemplo de los documentos anteriores, incluso hay una sección de comentarios en el código sobre lo que acabo de escribir:

// getApplicationContext() is key, it keeps you from leaking the // Activity or BroadcastReceiver if someone passes one in.