JNI基础(九)android如何监控到应用被卸载?

本文介绍了一种通过C进程监控应用程序是否被卸载的方法,并提供了一个具体的实现案例,该方法能够确保即使应用程序被卸载,也能执行相应的清理工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们经常会有一些需求,当应用被卸载的时候,发起一个问卷调查,或者清楚推送标识,避免应用都被卸载了还能收到推送(我们公司的项目就这样。。当初可郁闷了)

网上流行的答案: 注册一个receiver.....监听应用被卸载。 我对这个回答的看法与实践:纯属扯淡!

难道就没人去验证一下。。?网上都抄来抄去的。。。应用都被卸载了,你的java代码都被清除了,你些的java代码还能起作用吗。?再见

思路:开启C进程,监控应用包是否存在,如果不存在了,说明应用被卸载了。

原理:我们都知道,应用时以包名来区分唯一的,而应用包会装载/data/data目录下,而C进程是独立于java进程的,说明java程序被卸载了,它也还是会执行(除非被ROM杀死)

不知道如何开启C进程的童鞋,请看上一篇文章: JNI基础(八)开辟C进程

java代码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final JNI jni = new JNI();
        ((Button) findViewById(R.id.bt_fuck)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                new Thread(
//                        new Runnable() {
//                            @Override
//                            public void run() {
//                                jni.uninstallListener();
//                            }
//                        }
//                ).start();
                jni.uninstallListener();
            }
        });
    }
}

在这里经过我的测试。。在主线程中调用C开辟新进程的C代码,C代码中有死循环,竟然会阻塞主线程。。我很茫然,都开辟了新进程去执行了为什么还会阻塞主线程,不应该有这种的情况的,但确实现象是这样的,所以上述代码中,有一段开子线程启动jni的代码(执不执行都无所谓,懂原理就行了)。

public class JNI {

    /**
     * 加载动态链接库
     * 也就是c代码编译好的so文件
     */
    static {
        System.loadLibrary("app");
    }
    public native void uninstallListener();

}

C代码:

JNIEXPORT void JNICALL
Java_com_example_jnidemo_JNI_uninstallListener(JNIEnv *env, jobject instance) {
    //开辟C进程
    int pid = fork();
    //如果大于等于0,说明进程开辟成功
    if(pid >= 0){
        int flag = 1;

        while (flag){
            //这个1就代表1秒,与C语言的Sleep函数有区别的,请区分清楚,这个函数首字母不大写
            sleep(1);
            /**
             * C语言读取文件....
             * 第一个参数:路径
             * 第二个参数:文件mode,分为rwx : linux系统的文件权限,r代表读,w代表写,x代表可执行
             */
            FILE *file = fopen("/data/data/com.example.jnidemo","r");
            if(file == NULL){
                LOGI("软件不在了,被卸载了T T....");
//                //跳出循环,退出进程。
//                flag = 0;
            } else{
                LOGI("软件运行良好→_→.");
            }
        }
    }
}

使用FILE指针,需要导入头文件

#include <stdio.h>

结果:

 
这样就可以监听到了。有了这样的思路,类似的业务场景都可以解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值