方案
- 監聽系統卸載廣播:只能監聽到其他應用的卸載廣播,無法監聽到自己是否被卸載。
- 讀取系統log:第三方軟件卸載無法得知。
- 靜默安裝另一個程序,監聽自己是否被卸載:需要root權限。
- Java線程輪詢,監聽/data/data/{package-name}目錄是否存在:卸載app,進程退出,線程也被銷燬。
- C進程輪詢,監聽/data/data/{package-name}目錄是否存在:目前業界普遍採用的方案。
原理
從前四種方案可以看到,單純的Java層代碼是無法監聽自身卸載的。既然Java層無法實現,我們試着使用C語言在底層實現。藉助Linux進程fork出來的C進程在應用被卸載後不會被銷燬,監聽/data/data/{package-name}目錄是否存在,如果不存在,就證明應用被卸載了。
本程序採用第5種解決方案,對其進行優化,通過linux中的inotify機制來監聽應用的卸載。
實現
- fork()子進程
- 創建監聽文件
- 初始化inotify實例
- 註冊監聽事件
- 調用read函數開始監聽
- 卸載反饋統計
場景
- 正常卸載
- 斷網卸載
- 清除數據(5.0以上不支持)
- kill進程(5.0以上不支持)
- 插拔USB線
- 覆蓋安裝
- 內部存儲移到SD卡
- 開機監聽(官方不推薦)
- 打開瀏覽器(5.0以上部分機型無法開啓)