當前位置:編程學習大全網 - 源碼下載 - Android應用如何監聽自己是否被卸載及卸載反

Android應用如何監聽自己是否被卸載及卸載反

1,註冊BroadcastReceiver,監聽"android.intent.action.PACKAGE_REMOVED"系統廣播

結果:NO。未寫代碼,直接分析,卸載的第壹步就是退出當前應用的主進程,而此廣播是在已經卸載完成後才發出的,此時主進程都沒有了,去哪onReceive()呢?

2,若能收到"將要卸載XX包"的系統廣播,在主進程被退出之前就搶先進行反饋處理就好了,可惜沒有這樣的系統廣播,不過經過調研,倒是發現了壹個辦法,讀取系統log,當日誌中包含"android.intent.action.DELETE"和自己的包名時,意味著自己將要被卸載。

結果:NO。調試時發現此方法有兩個缺陷,(1)點擊設置中的卸載按鈕即發出此Intent,此時用戶尚未在彈框中確認卸載;(2)pm命令卸載不出發此Intent,意味著被諸如手機安全管家,豌豆莢等軟件卸載時,無法提前得知卸載意圖。

3,由於時間點不容易把控,所以幹脆不依賴系統廣播或log,考慮到卸載過程會刪除"/data/data/包名"目錄,我們可以用線程直接輪詢這個目錄是否存在,以此為依據判斷自己是否被卸載。

結果:NO。同方法1,主進程退出,相應的線程必定退出,線程還沒等到判斷目錄是否存在就已經被銷毀了。

4,改用C端進程輪詢"/data/data/包名"目錄是否存在

結果:YES。借助Java端進程fork出來的C端進程在應用被卸載後不會被銷毀。

二 方案

Android自API1就有的壹個類FileObserver,這個類用於監聽某個文件的變化狀態,如果是目錄,這個類還可以監聽其子目錄及子目錄文件的變化狀態,通過閱讀FileObserver源碼,發現其實現利用了Linux內核中壹個重要的機制inotify,它是壹個內核用於通知用戶空間程序文件系統變化的機制,詳情可參考http://en.wikipedia.org/wiki/Inotify,裏面對inotify有比較詳細的說明。

使用inotify的好處就在於不需要每1s的輪詢,這樣就不會無謂地消耗系統資源,使用inotify時會用read()方法阻塞進程,直到收到IN_DELETE通知,此時進程重新被喚醒,執行反饋處理流程。

三方案

阻塞結束後,通過調用exec函數發出am命令調起瀏覽器訪問網頁,在API16(Android 4.1.x)的設備上尚可正常訪問網頁,而API17(Android 4.2.x)的設備上連瀏覽器也不能調起。解決方案:增加處理分支,若API>=17,將userSerialNumber傳遞給C端進程,然後在am命令中帶上參數--user userSerialNumber即可

  • 上一篇:想要卻得不到更難過,還是觸手可及卻不能得到更痛苦?
  • 下一篇:什麽是建築能源管理系統(EMS)?
  • copyright 2024編程學習大全網