Cómo monitorear la desinstalación de tu propia aplicación
1. Demostración del efecto
Abra la representación de la aplicación:
Figura 1
Haga clic en el mensaje de desinstalación, como se muestra a continuación:
Figura 2
Luego salga de la aplicación y desinstale el programa. Encontrará que después de desinstalar la aplicación, aparecerá un mensaje para llamar al navegador. Aquí hay una página de navegación de Sohu. en su propia aplicación. Lo que debería llamarse es la página de encuesta general. Como se muestra en la siguiente figura:
Figura 3
Bueno, el efecto anterior ha quedado demostrado y ahora necesitamos discutir su implementación específica.
Primero, ingrese al teléfono a través de adb shell y luego ingrese a la aplicación por primera vez, como se muestra en la Figura 1. No haga clic en el botón y vea la información del proceso de esta aplicación a través de ps | grep ubuntu, como se muestra a continuación:
p>
Solo esta vez
u0_a108 2953 124 490956 47792 ffffffffff 40052a40 S com.example.ubuntuforandroid
2953 este proceso
Haga clic en Desinstalar nuevamente en el botón Solicitar, ejecute el comando ps que acaba de ejecutar y busque los dos procesos siguientes:
De hecho, el proceso recién creado se llama a través del programa
p>
public static nativo int Reguninstall(String path, String url);
Esta interfaz bifurcará un proceso y el proceso recién bifurcado es responsable de monitorear si la aplicación se ha desinstalado
Análisis del código fuente
El código de la capa Java es el siguiente.
El código de la capa java es el siguiente, es muy simple y es una llamada a la interfaz jni
protected void onCreate(Bundle saveInstanceState) { super.onCreate(savedInstanceState); setContentView (R.layout.activity_main) ; initInjectFunction("testfile "); test = (TextView)this.findViewById(R.id.testview); test.setText("haga clic en el botón Alerta después de desinstalar su aplicación, llamará al navegador después de la desinstalación y luego llamará a la página que desea necesita."); btn = (Button)this.findViewById(R.id.testbtn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Código auxiliar de método generado automáticamente Directorio de cadenas = MainActivity. this.getFilesDir().getAbsolutePath(); String url = "/"; JniExec.Reguninstall(directory, url); "); } } }); }
Claro de un vistazo, no hace falta decir más
Analizar inmediatamente
paquete com.example. ubuntuforandroid; public class JniExec { static { System.loadLibrary(" uninstall"); public static native int Reguninstall(String path, String url }
¿Qué trabajo hace Reguninstall en esta interfaz jni para lograr el efecto de? monitorear la desinstalación de su propia aplicación.
Análisis de código local
jint Java_com_example_ubuntuforandroid_JniExec_Reguninstall(JNIEnv* env, job ject thiz, jstring path, jstring url) { LOGI("Java_com_example_ubuntuforandroid_JniExec_Reguninstall"); char *listenpath = (char*) ( *env)-gt; GetStringUTFChars(env, ruta, 0); char *jumpurl = (char*) (*env)-gt; GetStringUTFChars(env, url, 0); ) ; LOGI("jumpurl es s", jumpurl); pid_t pid; pid = fork(); if(pid == 0) { //proceso secundario inotify_main(listenpath, jumpurl); //El proceso padre no se bloquea y llama a waitpid ok. El proceso hijo se vuelve huérfano y es adoptado por el proceso init. pid = waitpid(-1, 0, 1); ; }
Esta La clave de la interfaz reside en la llamada a inotify_main. Si tiene problemas para leer este código, vale la pena aprender sobre el mecanismo de bifurcación en Linux y cómo se crean procesos huérfanos y zombies.
Ver función inotify_main
void inotify_main(char *path, char *url) { struct pollfd poll_list[2]; poll_list[0].fd = inotify_init(); ].events = inotify_init(); poll_list[0].events = POLLIN; int wd = inotify_add_watch(poll_list[0].fd, ruta, IN_DELETE | IN_CREATE); no se pudo agregar watch for s, s\n", ruta, strerror(errno)); return; } int retval; while(1) { retval = poll(poll_list, (unsigned long)1, -1); /* LOGI ("retval = d\n", retval); if(retval lt; 0) { fprintf(stderr, "error de encuesta: s/n", strerror(errno) } if((poll_list[0]. revents & POLLIN) == POLLIN) { LOGI("poll_list[0].revents & POLLIN\n"); inotify_handle(poll_list[0].fd, url); } inotify_rm_watch(poll_list[0]. .fd, wd);