前言
我們的app有的時(shí)候難免會(huì)有很多問題歉铝,導(dǎo)致用戶卸載掉我們的app偷办。而我們作為開發(fā)者需要采集用戶卸載的原因猾昆,來更好的完善我們的app肪凛,所以需要在用戶卸載后彈出我們的反饋頁面态蒂,讓用戶把自己不滿意的地方反饋給我們杭措。
本文為ndk學(xué)習(xí)文章,經(jīng)本人對(duì)4.4钾恢,5.1手素,6.0,7.1的版本測(cè)試瘩蚪,該功能僅適用于低版本的Android設(shè)備泉懦,高版本中子進(jìn)程會(huì)連帶父進(jìn)程一起被殺死,所以僅供學(xué)習(xí)疹瘦。
效果
原理解析
主要是通過主進(jìn)程分叉出子進(jìn)程循環(huán)檢查app是否被卸載崩哩,當(dāng)發(fā)現(xiàn)app被卸載后打開網(wǎng)頁來實(shí)現(xiàn)
這里就有人要問了,為什么當(dāng)app被卸載后子進(jìn)程還能運(yùn)行呢
我們可以在代碼中加入一些log來觀察一下進(jìn)程編號(hào)的關(guān)系與變化
先在代碼中定義一下宏
#define LOG_TAG "unloadingfeedback"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
然后在fork出來的子進(jìn)程循環(huán)中打印出進(jìn)程編號(hào)
//獲取進(jìn)程編號(hào)
pid = getpid();
//獲取父進(jìn)程編號(hào)
ppid = getppid();
LOGD("progress is Running && pid = %d && ppid = %d", pid, ppid);
當(dāng)app運(yùn)行的時(shí)候
讓我們來看下打印出來的日志
進(jìn)程id為2289言沐,父進(jìn)程id為2275
為了驗(yàn)證一下琢锋,我們使用adb shell辕漂,執(zhí)行一下ps命令,來看一下模擬器當(dāng)前所有的進(jìn)程
左邊一列是進(jìn)程id吴超,右邊一列是父進(jìn)程id钉嘹,可以看到2289的父進(jìn)程為2275 包名為com.giftecat.unloadingfeedback
當(dāng)app被殺死的時(shí)候
我們還是先來看下日志是怎么打印的
我們的進(jìn)程id還是2289,但是發(fā)現(xiàn)父進(jìn)程id變成了1鲸阻,我們?cè)儆妹钚衼砜匆幌?/p>
而這個(gè)進(jìn)程id為1的進(jìn)程跋涣,就是我們的系統(tǒng)進(jìn)程
結(jié)論
使用主進(jìn)程分叉出一個(gè)子進(jìn)程后,當(dāng)主進(jìn)程被殺死后鸟悴,子進(jìn)程就會(huì)被系統(tǒng)進(jìn)程托管
可以理解為子進(jìn)程的父親被殺死了陈辱,變成了孤兒后系統(tǒng)進(jìn)程便會(huì)將他領(lǐng)養(yǎng)
判斷app是否被卸載和打開反饋網(wǎng)頁
懂得原理之后事情就變得簡(jiǎn)單了
我們判斷一下ppid是否為1,然后根據(jù)包名輪詢檢查文件是否還在
file = fopen("/data/data/com.giftedcat.unloadingfeedback", "r");
if (file == NULL) {
}
最后使用am命令打開瀏覽器
即am start --user 0 -a android.intent.action.VIEW -d http://www.baidu.com
execlp("am", "am", "start", "--user", "0", "-a", "android.intent.action.VIEW",
"-d", "http://www.baidu.com", NULL);
最后貼一下github的地址
覺得有幫助的話可以給我點(diǎn)個(gè)贊哦细诸,感謝