Android 下 JNI 开发
12.C代码打印出日志
04_卸载之后打开Android浏览器问卷调查-26
fork分叉函数
fork分叉(分裂)函数可以创建一个新进程, 并且新创建出来的进程(子进程)拥有创建它的那个进程(父进程)的数据空间, 堆栈资源等的拷贝. 并且相互不影响. (跟fork炸弹原理一样)
返回值会返回两次, 但有三种情况:
在父进程中, fork返回新创建子进程的进程ID.大于0
在子进程中, fork返回0.
如果出现错误, fork返回一个负值.
该功能原理简介
在程序没有卸载之前,调用C代码,去fork分叉出一个子进程;当程序被卸载时,这个子进程没有被立即关闭。这个子进程需要做的工作是:每一秒去查看/data/data/下是否有当前应用的包名,如果没有,被卸载了,打开浏览器,弹出一个页面,问卷调查用户卸载的原因。
实现思路归纳
1.声明native方法
2.在C语言中实现,里面去做fork分叉出一个子进程
3.子进程每隔1秒钟监听/data/data/当前包是否卸载
4.如果卸载了,调用Android浏览器
声明native方法
直接在压力值项目中做。
public native void uninstallListener();
4.在C语言中实现,里面去做fork分叉出一个子进程,并演示
//此方法会创建一个进程,父进程会返回一个值,子进程也会返回一次值.
int state = fork();
if(state > 0){
//当前是父进程
LOGD("parent process=%d",state);
}else if(state == 0){
//当前是子进程
LOGD("sup process=%d",state);
}else{
LOGD("Error");
}
5.子进程每隔1秒钟监听/data/data/当前包是否卸载
//此方法会创建一个进程,父进程会返回一个值,子进程也会返回一次值.
int state = fork();
if(state > 0){
//当前是父进程
LOGD("parent process=%d",state);
}else if(state == 0){
//当前是子进程
LOGD("sup process=%d",state);
//监听当前应用是否卸载
int isStop = 1;
while(isStop){
//每隔1秒钟判断应用目录是否存在
sleep(1);
//FILE *fopen(const char *, const char *);
FILE* file = fopen("/data/data/ com.atguigu.pressuredemo","r");
if(file == NULL){
//当文件夹没有了,就是被卸载了
LOGD("uninstalled ....");
isStop = 0;
}
}
}else{
LOGD("Error");
}
6.C代码调用Android浏览器
Dos命令行中打开浏览器:
adb shell am start -a android.intent.action.VIEW -d http://www.atguigu.com
adb shell am start -a android.intent.action.VIEW -d http://192.168.30.165:8080/uninstall.html
C语言中通过execlp方法打开浏览器:
execlp("am", "am", "start", "-a", "android.intent.action.VIEW", "-d", "http://www.atguigu.com", NULL);
命令:
# am start -a android.intent.action.VIEW -d http://10.0.2.2:8080
am start -a android.intent.action.VIEW -d http://10.0.2.2:8080/uninstall.html
全命令:
execlp("am", "am", "start", "-a", "android.intent.action.VIEW", "-d", "http://www.atguigu.com", NULL);
execlp("am", "am", "start", "-a", "android.intent.action.VIEW", "-d", "http://10.0.2.2:8080/uninstall.html", NULL);
C端完整代码:
/**
* 监听当应用卸载
*/
JNIEXPORT void JNICALL Java_com_atguigu_pressuredemo_MainActivity_uninstallListener
(JNIEnv *env, jobject obj){
//此方法会创建一个进程,父进程会返回一个值,子进程也会返回一次值.
int state = fork();
if(state > 0){
//当前是父进程
LOGD("parent process=%d",state);
}else if(state == 0){
//当前是子进程
LOGD("sup process=%d",state);
//监听当前应用是否卸载
int isStop = 1;
FILE* file;
while(isStop){
//每隔1秒钟判断应用目录是否存在
sleep(1);
//FILE *fopen(const char *, const char *);
file = fopen("/data/data/com.atguigu.pressuredemo","r");
if(file == NULL){
//当文件夹没有了,就是被卸载了
LOGD("uninstalled ....");
execlp("am", "am", "start", "-a", "android.intent.action.VIEW", "-d", "http://10.0.2.2:8080/uninstall.html", NULL);
isStop = 0;
}
}
}else{
LOGD("Error");
}
}
本教程由尚硅谷教育大数据研究院出品,如需转载请注明来源,欢迎大家关注尚硅谷公众号(atguigu)了解更多。