真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

android監(jiān)聽?wèi)?yīng)用是否被卸載的方法

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

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:域名與空間、網(wǎng)絡(luò)空間、營銷軟件、網(wǎng)站建設(shè)、潮南網(wǎng)站維護(hù)、網(wǎng)站推廣。

一  效果演示

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

android監(jiān)聽?wèi)?yīng)用是否被卸載的方法

    圖1

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

android監(jiān)聽?wèi)?yīng)用是否被卸載的方法

    圖2

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

android監(jiān)聽?wèi)?yīng)用是否被卸載的方法

    圖3

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

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

android監(jiān)聽?wèi)?yīng)用是否被卸載的方法

   這個時候只有

   u0_a108   2953  124   490956 47792 ffffffff 40052a40 S com.example.ubuntuforandroid
   2953 這一個進(jìn)程

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

android監(jiān)聽?wèi)?yīng)用是否被卸載的方法

  其實新產(chǎn)生的進(jìn)程是通過程序調(diào)用jni接口

public static native int Reguninstall(String path,String url);

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

二  源碼分析

  java層的代碼如下,很簡單,就是調(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("點擊卸載后提示按鈕,你的應(yīng)用在卸載以后會調(diào)用瀏覽器,然后調(diào)用你需要的頁面。");
                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                     
    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 這個jni接口里面做了什么事情,能夠達(dá)到監(jiān)聽本身應(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;
}

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

下面看   inotify_main 這個函數(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或為-1,因為我們在阻塞中工作 */
        LOGI("retval = %d\n",retval);
        if(retval < 0)
        {
            fprintf(stderr,"poll錯誤: %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);
}

這個函數(shù),這里面用到了  inotify_init  inotify_add_watch  inotify_rm_watch 這幾個linux接口,這幾個接口主要的作用就是監(jiān)聽指定的目錄,其配合poll函數(shù),能夠監(jiān)聽目錄下的任何改動,當(dāng)要監(jiān)聽的目錄有任何改動的時候,會觸發(fā)poll函數(shù)的 POLLIN 有可讀數(shù)據(jù)到來事件。

在本應(yīng)用中,監(jiān)聽的是 /data/data/com.example.ubuntuforandroid/files/ 這個目錄,因為在卸載的時候卸載程序會刪除監(jiān)聽目錄的,而fork出來的守護(hù)進(jìn)程當(dāng)發(fā)現(xiàn)自身應(yīng)用的目錄被卸載程序刪除了也就是卸載了,這個時候調(diào)用 inotify_handle 這個函數(shù),然后調(diào)用 am命令啟動瀏覽器,調(diào)用自己需要調(diào)用界面。

當(dāng)然,在調(diào)用am指令以后,記得自身守護(hù)進(jìn)程的使命也完成了,需要exit退出一下。

inotify接口的用處很多,擴(kuò)展一下,也可以用于守護(hù)進(jìn)程,比如A進(jìn)程和B進(jìn)程是共生共死的,這里有一種實現(xiàn)的方式就是 A進(jìn)程用inotify 監(jiān)聽 /proc/B進(jìn)程id目錄,當(dāng)B進(jìn)程結(jié)束的時候,A進(jìn)程就能知道B進(jìn)程不在了,從而結(jié)束自己。

上文描述的就是android監(jiān)聽?wèi)?yīng)用是否被卸載的方法,具體使用情況還需要大家自己動手實驗使用過才能領(lǐng)會。如果想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


網(wǎng)頁題目:android監(jiān)聽?wèi)?yīng)用是否被卸載的方法
URL網(wǎng)址:http://weahome.cn/article/psciio.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部