Red de conocimiento informático - Computadora portátil - Cómo mantener vivos los procesos en Android

Cómo mantener vivos los procesos en Android

Cada aplicación de Android comienza con al menos uno o varios procesos, y una gran proporción de las aplicaciones principales tienen varios procesos

Para cualquier proceso, podemos usar adb shell ps|grep lt;package_namegt para verlo

su información básica

.

Al igual que la sociedad feudal, los procesos en Android se dividen en tres niveles. El sistema Android clasifica los procesos de la siguiente manera

Varios tipos (de mayor a menor importancia), muchos expertos en línea lo han resumido en detalle (Nota: Estrictamente hablando, los procesos se dividen en seis niveles).

Escenario:

1. Un proceso mantiene una actividad que interactúa con el usuario y la actividad está en el estado reanudar

.

2. Un proceso contiene servicios vinculados a actividades con las que interactúa el usuario.

3. Un proceso contiene un servicio, que llama al método startForeground() para ponerlo en primer plano.

4. Un proceso contiene un servicio y el servicio está ejecutando uno de sus métodos de devolución de llamada del ciclo de vida, como onCreate(), onStart() o onDestroy().

5. Un proceso contiene un BroadcastReceiver y el BroadcastReceiver está ejecutando su método onReceive(). Cuando el usuario está utilizando el programa, el sistema generalmente no finalizará el proceso en primer plano a menos que el usuario detenga la aplicación por la fuerza o el sistema se quede sin memoria u otras circunstancias extremas.

Escenarios de aplicación:

1. Hay una actividad que no está en primer plano, pero aún es visible para el usuario (se ha llamado a onPause()).

2. Hay un servicio vinculado a una actividad visible (o en primer plano).

Un proceso que el usuario está utilizando, puede ver pero no tocar, no cubre toda la pantalla, y solo una parte de la pantalla es visible

No contiene ningún componente en primer plano Generalmente, el sistema no finalizará el proceso visible a menos que esté bajo restricciones de recursos

Lo visible. El proceso debe mantenerse.

Para mantener vivos uno o más procesos en primer plano

1. Uno de los procesos ejecuta un servicio iniciado por startService(), que no tiene relación directa con la interfaz vista por el usuario. .

Si no hay suficiente memoria para que todos los procesos visibles y en primer plano se ejecuten al mismo tiempo, el proceso de servicio finalizará

Escenario:

El usuario presiona "atrás" o Programas que son invisibles pero que aún se ejecutan después de la tecla "inicio",

como actividades que llaman a pausa,

el sistema puede finalizarlos en cualquier momento para recuperarlos memoria

Escenario:

Si un proceso no contiene ningún componente activo, se configurará como vacío y será completamente inútil, por lo que solo le conviene eliminarlo. ¡Sé el primero en hacerlo!

Lo anterior es la clasificación de procesos, entonces, ¿cómo se eliminan? Por motivos de experiencia y rendimiento, cuando se realiza una copia de seguridad de una aplicación en segundo plano, el sistema en realidad no finaliza el proceso, sino que lo almacena en caché. Cuantas más aplicaciones tengas abiertas, más procesos se almacenarán en caché en segundo plano. Cuando la memoria del sistema se agota, el sistema comenzará a utilizar su propio mecanismo de reciclaje de procesos para decidir qué procesos eliminar para liberar memoria para las aplicaciones que la necesitan. Este es el llamado asesino de memoria baja.

Este mecanismo se llama umbral de memoria y se puede utilizar

cat /s /s /s /s /s /s /s /s /s /s /s /s/ para definirlo.

De hecho, el sistema tiene una política estricta para el reciclaje de procesos, que es similar al reciclaje de memoria. Puedes

descubrir por ti mismo que es más o menos así: cuanto más grande es. oom_adj, cuanto más espacio ocupe, más memoria física habrá, más se eliminará primero.

¿Cómo puedo minimizar el uso de memoria de mi aplicación?

Algunas personas dicen que este es un proceso manual. La idea básica es que el sistema generalmente no finaliza el proceso en primer plano. Entonces, para

hacer que el proceso sea permanente, solo necesitamos abrir una Actividad cuando el proceso está bloqueado. Para engañar al usuario,

haga que el tamaño de esta Actividad sea 1. píxel y transparente No hay animación de cambio Cuando la pantalla está encendida, la Actividad

se cierra, por lo que esto requiere monitorear la transmisión de la pantalla de bloqueo del sistema. Lo he probado. Lo probé y funcionó de la siguiente manera.

Si iniciamos una Actividad directamente, cuando presionamos la tecla de retorno para regresar al escritorio, el valor de oom_adj es 8.

Como se mencionó anteriormente, en el caso de recursos insuficientes , este proceso se recicla muy fácilmente.

Monitorizar bloqueos del sistema.

Para escuchar la transmisión de la pantalla de bloqueo del sistema, notifique a MainActivity en forma de interfaz para iniciar o cerrar LiveActivity.

Ahora, MainActivity queda de la siguiente manera

Después de presionar la tecla de retorno, bloqueará la pantalla, ahora pruebe el valor de oom_adj

Efectivamente, mejora la prioridad de la clase de proceso.

Se ha incrementado la prioridad del proceso.

Pero hay otro problema. La memoria también es una consideración. Cuanto mayor sea la memoria, más fácil será eliminarla primero, así que coloque

la lógica de negocios anterior en otro proceso. . service e inicie el

servicio en MainActivity, para que el proceso sea más liviano.

Bien, con las operaciones anteriores, nuestra aplicación siempre tiene la misma prioridad que el proceso en primer plano. Para ahorrar energía,

el sistema la cerrará después de detectar el evento de la pantalla de bloqueo. . Proceso en segundo plano durante algún tiempo; si adopta esta solución, puede evitar

este problema. Pero todavía existe la posibilidad de que nos maten, por lo que todavía necesitamos crear un demonio de proceso dual. En cuanto al demonio de proceso dual,

El método más adecuado es Aidl, pero este método no es completamente confiable. El principio es que si el proceso A muere,

B sigue vivo y B puede activar el proceso A. Por el contrario, si el proceso B muere, pero A sigue vivo, A puede activar el proceso.

. Por lo tanto, la premisa de la protección de proceso dual es que el sistema solo puede eliminar los procesos uno por uno. Si dos procesos se eliminan al mismo tiempo,

Este método no funcionará.

De hecho,

Entonces, echemos un vistazo al código fuente de Android 5.0 y versiones anteriores para ver cómo ActivityManagerService cierra y limpia la memoria después de que la aplicación sale.

Después de que se cierra la aplicación, ActivityManagerService no solo eliminará el proceso principal, sino que también eliminará el proceso al que pertenece el proceso principal. Una vez que se cierra la aplicación, ActivityManagerService no solo eliminará el proceso principal, sino que también eliminará el grupo de procesos al que pertenece el proceso principal. Por lo tanto, las operaciones en curso del proceso secundario también se detendrán, porque el proceso secundario. El proceso hijo se encuentra en la misma ubicación que el proceso principal. En el mismo grupo de procesos

.

Es por eso que las aplicaciones móviles en Android 5.0 y superiores deben usar opciones adicionales cuando se finaliza un proceso.

La mayoría de la gente lo sabe. Se dice que WeChat también utiliza una solución de supervivencia de procesos.

Cliente WeChat para Android

Compartir experiencias sobre la capacidad de supervivencia del back-end en realidad explota las vulnerabilidades en los servicios front-end de Android.

El principio es el siguiente

Para el nivel de API lt 18: llame a startForeground(ID, new Notification()), envíe una notificación

vacía y el icono no se mostrará.

Para el nivel de API gt; = 18: inicie un InnerService en el servicio A que debe procesarse primero, y ambos servicios

inician Foreground al mismo tiempo y se vinculan al mismo ID. detenga InnerService, se eliminará el icono de la barra de notificaciones

.

clase pública KeepLiveService extiende el servicio{

public static final int NOTIFICATION_ID=0x11;?

public KeepLiveService() {

}

@Override

public IBinder onBind(Intent intent){

throw new UnsupportedOperationException("Aún no implementado");

?}

?

public void onCreate() {

?super.onCreate(); //En API 18, envíe la notificación directamente y colóquela en primer plano.

if(Build.VERSION.SDK_INTlt Build.VERSION_CODES.JELLY_BEAN_MR2){

startForeground(NOTIFICATION_ID, new Notification());?

} else { / /API 18, inicie InnerService y colóquelo en primer plano después de enviar la notificación

Notification.Builder builder=new Notification.Builder(this);

builder.

setSmallIcon(R.mipmap.ic_launcher);

startForeground(NOTIFICATION_ID, builder.build());

?startService(new Intent(this, InnerService.class)); p>

?}

?}

?public class InnerService extiende el servicio{

?@Override public IBinder onBind(Intent intent) {

?}?

@Override public void onCreate() {

?super.onCreate() //Envía la notificación con el mismo ID que el KeepLiveService y luego Cancelar esta notificación y cancelar su propia visualización en primer plano

?Notification.Builder builder = new Notification.Builder(this);

builder.setSmallIcon(R.mipmap.ic_launcher ); startForeground ( NOTIFICATION_ID,

builder.build()

new Handler().postDelayed(new Runnable() {?

@Override public void run() {?

stopForeground(true);

administrador de NotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

manager.cancel(NOTIFICATION_ID); ?

stopSelf();

?}

?}

100);

?}

?}

?}

Cuando la aplicación se inicia antes de activar el servicio en primer plano, el valor de om_adj es 0. Después de presionar la tecla Enter, el el valor de om_adj se convierte en 9 (diferente La ROM puede ser diferente)

La importancia del despertar mutuamente excluyente es que si tiene Alipay, Taobao, Tmall, UC.NET y otras aplicaciones de Alibaba en su teléfono, luego, al activar el servicio en primer plano, el valor de om_adj es 0, y otras aplicaciones de Alibaba,

Cuando abre cualquier aplicación de Alibaba, es posible que se le despierte con el mismo valor, y cuando abre cualquier aplicación de Alibaba , Puede que te despiertes con el mismo valor.

El valor de oom_adj es 0 y al presionar la tecla Retorno cambiará a 9.

Por lo tanto, si abre cualquier aplicación de Alibaba, es posible activar otras aplicaciones de Alibaba.

Esto es totalmente posible.

También es posible utilizar retransmisiones generadas por el sistema

para activar aplicaciones cuando enciendes el teléfono, cambias de red, haces fotos o grabas vídeos, pero Android N elimina los tres.

Si una aplicación quiere seguir sobreviviendo, siempre que QQ y WeChat estén dispuestos a guardarla, ¿cuántos teléfonos móviles no tienen QQ y WeChat?

O

Los SDK Push como AU y Pigeon también tienen la función de activar la aplicación.

JobSheduler es un método de resurrección después de que el proceso muere

La mayor desventaja del método de proceso nativo es el consumo de energía, y la razón por la cual el nativo

El proceso consume energía. Esto se debe a que tiene dos métodos de implementación. En el proceso nativo, puede detectar si el proceso principal está activo a través de un bucle infinito

o un temporizador, y luego se turna para determinar si el proceso está activo. El proceso principal está vivo. En el proceso local, se utiliza un bucle infinito o un temporizador para determinar si el proceso principal está vivo a su vez y luego llevar el proceso principal al estado vivo cuando no está vivo. Esto no es compatible con sistemas superiores a 5.0

. Sin embargo, JobSheduler puede reemplazar el método de proceso nativo en Android 5.0 y superior y puede iniciar el proceso incluso si el usuario fuerza su cierre.

JobSheduler@TargetApi(Build.VERSION_CODES.LOLLIPOP)?

public class MyJobService extiende JobService {

?@Override

public void onCreate() {

super.onCreate();

startJobSheduler();

?}

public void startJobSheduler() {

prueba {

?JobInfo.Builder builder = new JobInfo.Builder(1, new ComponentName(getPackageName(), MyJobService.class.getName());

builder.setPeriodic(5); builder.setPersisted(true);

?setPersisted(true); JobScheduler jobScheduler = (JobScheduler)

this.getSystemService(Context .JOB_SCHEDULER_SERVICE

jobScheduler.schedule(builder.build()

}

catch

(Excepción ex)

{ ej. printStackTrace(); }

?}

?@Override

public boolean onStartJob(JobParameters jobParameters) {

?

}@Override public boolean onStopJob(JobParameters jobParameters) {?

Devuelve falso ?

}

? }

El método onStartCommand debe tener un valor de retorno entero para indicarle al sistema qué hacer cuando el servicio finaliza después de iniciarlo. Creo que se puede adoptar una solución más conservadora.

1.START_STICKY

Si el sistema se destruye después de que onStartCommand regresa, el sistema recreará el servicio y llamará a onCreate y onStartCommand en secuencia (Nota: según la prueba, Android 2.3.3 y versiones anteriores solo llaman a

onCreate).

onCreate no llama a onStartCommand en absoluto, mientras que Android 4.0 sí lo hace), lo que equivale a reiniciar el servicio

a su estado anterior).

2.START_NOT_STICKY

Si el sistema se destruye después de que onStartCommand regresa, y si se devuelve este valor, entonces si el servicio se cierra después de ejecutar

onStartCommand método, el servicio no se reiniciará

3._REDELIVER_INTENT

Una versión compatible de START_STICKY, pero no garantiza que el servicio se reiniciará después de ser eliminado.

4. En comparación con los servicios fijos, las funciones incluidas con los servicios del sistema son más poderosas. Esto proviene de la investigación sobre Brother Ai. Los servicios del sistema mencionados aquí son muy fáciles de entender. >, como NotificationListenerService, NotificationListenerService es un oyente

NotificationListenerService es un servicio que escucha notificaciones. Cada vez que el teléfono recibe una notificación, NotificationListenerService la escucha y puede reiniciarla incluso si el usuario

interrumpe el proceso.

Entonces, si tu aplicación tiene funcionalidad de mensajería push, puedes usarla para engañar a los usuarios.