這篇文章主要介紹了android監(jiān)聽(tīng)?wèi)?yīng)用是否被卸載的方法,具有一定借鑒價(jià)值,需要的朋友可以參考下。如下資料是關(guān)于android實(shí)現(xiàn)監(jiān)聽(tīng)的詳細(xì)步驟內(nèi)容。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名與空間、網(wǎng)絡(luò)空間、營(yíng)銷(xiāo)軟件、網(wǎng)站建設(shè)、潮南網(wǎng)站維護(hù)、網(wǎng)站推廣。
一 效果演示
打開(kāi)應(yīng)用效果圖:
圖1
點(diǎn)擊卸載后提示,如下圖:
圖2
然后退出應(yīng)用,卸載程序,會(huì)發(fā)現(xiàn)當(dāng)應(yīng)用被卸載以后,會(huì)彈出調(diào)用瀏覽器的提示,這里隨便放了一個(gè)搜狐瀏覽頁(yè)面,在自己的應(yīng)用中應(yīng)該調(diào)用的一般都是調(diào)查頁(yè)面。如下圖:
圖3
ok,效果前面已經(jīng)演示了,現(xiàn)在需要討論一下其具體實(shí)現(xiàn)了。
首先,通過(guò)adb shell進(jìn)入手機(jī),然后第一次進(jìn)入應(yīng)用,像圖1一樣,不點(diǎn)擊按鈕,通過(guò) ps | busybox grep ubuntu 看這個(gè)應(yīng)用的進(jìn)程信息,如下圖:
這個(gè)時(shí)候只有
u0_a108 2953 124 490956 47792 ffffffff 40052a40 S com.example.ubuntuforandroid
2953 這一個(gè)進(jìn)程
點(diǎn)擊 卸載后提示 按鈕再次,執(zhí)行剛才執(zhí)行的ps命令,發(fā)現(xiàn)已經(jīng)有兩個(gè)進(jìn)程了如下圖:
其實(shí)新產(chǎn)生的進(jìn)程是通過(guò)程序調(diào)用jni接口
public static native int Reguninstall(String path,String url);
這個(gè)接口fork了一個(gè)進(jìn)程,而新fork的進(jìn)程負(fù)責(zé)監(jiān)聽(tīng)本應(yīng)用是否被卸載了
二 源碼分析
java層的代碼如下,很簡(jiǎn)單,就是調(diào)用一下jni接口
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initInjectFunction("testfile"); test = (TextView)this.findViewById(R.id.testview); test.setText("點(diǎn)擊卸載后提示按鈕,你的應(yīng)用在卸載以后會(huì)調(diào)用瀏覽器,然后調(diào)用你需要的頁(yè)面。"); btn = (Button)this.findViewById(R.id.testbtn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub String directory = MainActivity.this.getFilesDir().getAbsolutePath(); String url = "http://www.sohu.com/"; JniExec.Reguninstall(directory,url); test.setText("現(xiàn)在可以退出應(yīng)用,然后卸載應(yīng)用,看看是否有效果"); } }); }
一目了然,不用多言了
現(xiàn)在就分析
package com.example.ubuntuforandroid; public class JniExec { static { System.loadLibrary("uninstall"); } public static native int Reguninstall(String path,String url); }
Reguninstall 這個(gè)jni接口里面做了什么事情,能夠達(dá)到監(jiān)聽(tīng)本身應(yīng)用卸載的效果。
native代碼分析
jint Java_com_example_ubuntuforandroid_JniExec_Reguninstall(JNIEnv* env, jobject thiz, jstring path, jstring url) { LOGI("Java_com_example_ubuntuforandroid_JniExec_Reguninstall"); char *listenpath = (char*) (*env)->GetStringUTFChars(env,path, 0); char *jumpurl = (char*) (*env)->GetStringUTFChars(env,url, 0); LOGI("notify path is %s",listenpath); LOGI("jumpurl is %s",jumpurl); pid_t pid; pid = fork(); if(pid == 0) { //子進(jìn)程 inotify_main(listenpath,jumpurl); } //父進(jìn)程不阻塞調(diào)用 waitpid ok 子進(jìn)程變成了孤兒進(jìn)程,被init進(jìn)程收養(yǎng)了 pid = waitpid(-1,0,1); LOGI("father bye bye"); return 0; }
這個(gè)接口里面最關(guān)鍵的是調(diào)用了 inotify_main 這個(gè)函數(shù)。如果看這段代碼比較費(fèi)力的話,建議先弄清楚linux 下的fork機(jī)制,搞清楚 孤兒進(jìn)程 僵尸進(jìn)程這些如何產(chǎn)生的情況。
下面看 inotify_main 這個(gè)函數(shù)
void inotify_main(char *path,char *url) { struct pollfd poll_list[2]; poll_list[0].fd = inotify_init(); poll_list[0].events = POLLIN; int wd = inotify_add_watch(poll_list[0].fd, path, IN_DELETE | IN_CREATE); if(wd < 0) { fprintf(stderr, "could not add watch for %s, %s\n", path, strerror(errno)); return ; } int retval; while(1) { retval = poll(poll_list,(unsigned long)1,-1); /* retval 總是大于0或?yàn)?1,因?yàn)槲覀冊(cè)谧枞泄ぷ?*/ LOGI("retval = %d\n",retval); if(retval < 0) { fprintf(stderr,"poll錯(cuò)誤: %s/n",strerror(errno)); return; } 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); }
這個(gè)函數(shù),這里面用到了 inotify_init inotify_add_watch inotify_rm_watch 這幾個(gè)linux接口,這幾個(gè)接口主要的作用就是監(jiān)聽(tīng)指定的目錄,其配合poll函數(shù),能夠監(jiān)聽(tīng)目錄下的任何改動(dòng),當(dāng)要監(jiān)聽(tīng)的目錄有任何改動(dòng)的時(shí)候,會(huì)觸發(fā)poll函數(shù)的 POLLIN
有可讀數(shù)據(jù)到來(lái)事件。
在本應(yīng)用中,監(jiān)聽(tīng)的是 /data/data/com.example.ubuntuforandroid/files/ 這個(gè)目錄,因?yàn)樵谛遁d的時(shí)候卸載程序會(huì)刪除監(jiān)聽(tīng)目錄的,而fork出來(lái)的守護(hù)進(jìn)程當(dāng)發(fā)現(xiàn)自身應(yīng)用的目錄被卸載程序刪除了也就是卸載了,這個(gè)時(shí)候調(diào)用 inotify_handle
這個(gè)函數(shù),然后調(diào)用 am命令啟動(dòng)瀏覽器,調(diào)用自己需要調(diào)用界面。
當(dāng)然,在調(diào)用am指令以后,記得自身守護(hù)進(jìn)程的使命也完成了,需要exit退出一下。
inotify接口的用處很多,擴(kuò)展一下,也可以用于守護(hù)進(jìn)程,比如A進(jìn)程和B進(jìn)程是共生共死的,這里有一種實(shí)現(xiàn)的方式就是 A進(jìn)程用inotify 監(jiān)聽(tīng) /proc/B進(jìn)程id目錄,當(dāng)B進(jìn)程結(jié)束的時(shí)候,A進(jìn)程就能知道B進(jìn)程不在了,從而結(jié)束自己。
上文描述的就是android監(jiān)聽(tīng)?wèi)?yīng)用是否被卸載的方法,具體使用情況還需要大家自己動(dòng)手實(shí)驗(yàn)使用過(guò)才能領(lǐng)會(huì)。如果想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
文章標(biāo)題:android監(jiān)聽(tīng)?wèi)?yīng)用是否被卸載的方法
網(wǎng)頁(yè)鏈接:http://bm7419.com/article0/psciio.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、Google、面包屑導(dǎo)航、動(dòng)態(tài)網(wǎng)站、搜索引擎優(yōu)化、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)