【移動應(yīng)用開發(fā)技術(shù)】android監(jiān)聽?wèi)?yīng)用是否被卸載的方法_第1頁
【移動應(yīng)用開發(fā)技術(shù)】android監(jiān)聽?wèi)?yīng)用是否被卸載的方法_第2頁
【移動應(yīng)用開發(fā)技術(shù)】android監(jiān)聽?wèi)?yīng)用是否被卸載的方法_第3頁
【移動應(yīng)用開發(fā)技術(shù)】android監(jiān)聽?wèi)?yīng)用是否被卸載的方法_第4頁
【移動應(yīng)用開發(fā)技術(shù)】android監(jiān)聽?wèi)?yīng)用是否被卸載的方法_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】android監(jiān)聽?wèi)?yīng)用是否被卸載的方法

這篇文章主要介紹了android監(jiān)聽?wèi)?yīng)用是否被卸載的方法,具有一定借鑒價值,需要的朋友可以參考下。如下資料是關(guān)于android實現(xiàn)監(jiān)聽的詳細(xì)步驟內(nèi)容。一

效果演示

打開應(yīng)用效果圖:

圖1

點擊卸載后提示,如下圖:

圖2

然后退出應(yīng)用,卸載程序,會發(fā)現(xiàn)當(dāng)應(yīng)用被卸載以后,會彈出調(diào)用瀏覽器的提示,這里隨便放了一個搜狐瀏覽頁面,在自己的應(yīng)用中應(yīng)該調(diào)用的一般都是調(diào)查頁面。如下圖:

圖3

ok,效果前面已經(jīng)演示了,現(xiàn)在需要討論一下其具體實現(xiàn)了。

首先,通過adbshell進入手機,然后第一次進入應(yīng)用,像圖1一樣,不點擊按鈕,通過ps|busyboxgrepubuntu看這個應(yīng)用的進程信息,如下圖:

這個時候只有

u0_a108

2953

124

49095647792ffffffff40052a40Scom.example.ubuntuforandroid

2953這一個進程

點擊卸載后提示按鈕再次,執(zhí)行剛才執(zhí)行的ps命令,發(fā)現(xiàn)已經(jīng)有兩個進程了如下圖:

其實新產(chǎn)生的進程是通過程序調(diào)用jni接口publicstaticnativeintReguninstall(Stringpath,Stringurl);

這個接口fork了一個進程,而新fork的進程負(fù)責(zé)監(jiān)聽本應(yīng)用是否被卸載了二

源碼分析

java層的代碼如下,很簡單,就是調(diào)用一下jni接口protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initInjectFunction("testfile");

test=(TextView)this.findViewById(R.id.testview);

test.setText("點擊卸載后提示按鈕,你的應(yīng)用在卸載以后會調(diào)用瀏覽器,然后調(diào)用你需要的頁面。");

btn=(Button)this.findViewById(R.id.testbtn);

btn.setOnClickListener(newView.OnClickListener(){

@Override

publicvoidonClick(Viewv){

//TODOAuto-generatedmethodstub

Stringdirectory=MainActivity.this.getFilesDir().getAbsolutePath();

Stringurl="/";

JniExec.Reguninstall(directory,url);

test.setText("現(xiàn)在可以退出應(yīng)用,然后卸載應(yīng)用,看看是否有效果");

}

});

}一目了然,不用多言了

現(xiàn)在就分析packagecom.example.ubuntuforandroid;

publicclassJniExec{

static{

System.loadLibrary("uninstall");

}

publicstaticnativeintReguninstall(Stringpath,Stringurl);

}

Reguninstall這個jni接口里面做了什么事情,能夠達(dá)到監(jiān)聽本身應(yīng)用卸載的效果。

native代碼分析jintJava_com_example_ubuntuforandroid_JniExec_Reguninstall(JNIEnv*env,jobjectthiz,jstringpath,

jstringurl)

{

LOGI("Java_com_example_ubuntuforandroid_JniExec_Reguninstall");

char*listenpath=(char*)(*env)->GetStringUTFChars(env,path,0);

char*jumpurl=(char*)(*env)->GetStringUTFChars(env,url,0);

LOGI("notifypathis%s",listenpath);

LOGI("jumpurlis%s",jumpurl);

pid_tpid;

pid=fork();

if(pid==0)

{

//子進程

inotify_main(listenpath,jumpurl);

}

//父進程不阻塞調(diào)用waitpidok子進程變成了孤兒進程,被init進程收養(yǎng)了

pid=waitpid(-1,0,1);

LOGI("fatherbyebye");

return0;

}這個接口里面最關(guān)鍵的是調(diào)用了inotify_main這個函數(shù)。如果看這段代碼比較費力的話,建議先弄清楚linux下的fork機制,搞清楚孤兒進程僵尸進程這些如何產(chǎn)生的情況。下面看

inotify_main這個函數(shù)voidinotify_main(char*path,char*url)

{

structpollfdpoll_list[2];

poll_list[0].fd=inotify_init();

poll_list[0].events=POLLIN;

intwd=inotify_add_watch(poll_list[0].fd,path,IN_DELETE|IN_CREATE);

if(wd<0){

fprintf(stderr,"couldnotaddwatchfor%s,%s\n",path,strerror(errno));

return;

}

intretval;

while(1)

{

retval=poll(poll_list,(unsignedlong)1,-1);

/*retval總是大于0或為-1,因為我們在阻塞中工作*/

LOGI("retval=%d\n",retval);

if(retval<0)

{

fprintf(stderr,"poll錯誤:%s/n",strerror(errno));

return;

}

if((poll_list[0].revents&POLLIN)==POLLIN)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論