導讀:我們以如何搶先開機啟動為例,來說明接收無序廣播的靜態廣播接收器的接收順序
(注意,文本只是陳述結果,所以叫結果篇,之後的文章再給出源碼分析)
首先先說一下android中的廣播和廣播接收器
廣播可以分為有序、無序和sticky共三種
廣播接收器可以分為靜態和動態兩種
首先我們要明確兩個問題
1.接收無序廣播的接收器接收到廣播的順序是有序的
2.接收無序廣播的接收器也一樣可以設定優先權的
這裡主要說一下多個應用中的靜態廣播接收器(優先順序都相同的情況下)接收無序廣播時的接收順序
注意:這裡主要描述結論,具體原理後續給出
注意:本文在提及的同時出現在同一裝置的靜態接收器預設具有相同的優先順序,這點很重要
我們以開機時候發出的廣播android.intent.action.BOOT_COMPLETED為例,這是個無序廣播
如果應用想要開啟自啟動,那麼就要監聽這個廣播,程式啟動之前,動態廣播接收器肯定是無法使用的,我相信大家對此沒有什麼疑問
如果先接收到,那麼程式就會先啟動,至於先啟動的優勢,我想那些迫不及待的人比誰都清楚
接收順序到底與什麼有關,說實話,我也不清楚,不過先別急著拍我,我也不是完全不知道……
順序與解析應用的順序是一致的,但是解析應用的順序是怎樣的呢?
首先要告訴大家的是,這和你apk的檔案名稱沒有關係!
比如a.apk、b.apk兩個應用,結果並不能保證a能比b先接收到,或者b能比a先接收到
然後告訴大家,這和apk的檔案名稱有關係!
沒錯,但是為什麼這麼說?
使用者安裝一個應用有這麼幾個步驟
1下載一款應用,假設下載下來的時候這個應用叫new.apk
2安裝。一般情況下,使用者會在手機中操作,點擊檔案,然後系統會安裝頁面……然後大家都知道。另一種情況程式猿可能喜歡使用adb install -r new.apk
大家都知道,第三方應用會存放在/data/app目錄下
當安裝完畢之後,我們去這裡看看,發現一個嚴峻的問題,那就是,你找不到一個叫new.apk的檔案!
那你會找到什嗎?你會找到一個檔案,他的名字是以與new.apk這個應用程式套件名開始的,然後可能會跟著"-數字.apk",比如:com.android.test-1.apk
接收的順序與這個名字是有關的!那麼關係是怎樣的呢?
系統在開機的時候,會按著一個順序解析apk
1.首先,會解析手機中的/system/framework這個目錄,原生系統中,這下面就一個apk - framework-res.apk
當然各個廠商也會加入自己的內容,比如我的這個目錄下就有com.htc.resources.apk
2.然後受到重視的檔案夾按順序分別為:
/system/app
/vendor/app
/data/app
/drm/app-private
(程式碼分析在下一篇部落格給出)
那麼每個檔案夾下解析的順序是怎樣的呢
我們先只看/data/app,也就是使用者安裝的第三方應用的存放位置
這與下面代碼返回結果的順序是一致的
File file = new File("/data/app/");String[] files = file.list();
也就是說,我們按順序列印這個數組,就能知道哪個接收器會先接收到這個廣播,哪個會後接收到(為什麼與這個結果一致,下篇文章分析)
(記住:本文預設說的這些接收器假設具有相同的優先順序,如果優先順序不同,當然是高優先順序的先接收到)
現在大家可能有這麼幾個疑問:
1.String[] java.io.File.list(),這個函數的返回結果是怎樣的順序呢?
2.如何執行上面那段代碼呢?
首先回答問題1
我不知道!
我們來看看javadoc給出的說明
javadoc 寫道There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.
說的很清楚,人家不給你任何保證
聽說在windows下執行的時候,結果會按著字母順序排列,可惜,android是linux
但是我們可以耍賴,列印一下上面結果,如果自己的應用拍在後面,就改包名,直到你能排到前面,當然這不是什麼好辦法,但我也沒有什麼更好的辦法了
現在回答問題2
執行這段代碼需要root許可權,因為一般應用是沒有這個目錄的讀取許可權的
如果手機沒有root怎麼辦?你不會找一個root過的來查看結果嗎……
我做了一個實驗,我寫了幾個只有receiver的應用,把他們的包名分別設定為大家常用的、關係的應用程式套件名
飛信:cn.com.fetion
LBE隱私衛士:com.lbe.security.lite
Handsent:com.handsent.nextsms
金山手機衛士:com.ijinshan.mguard
360手機衛士:com.qihoo360.mobilesafe
QQ手機管家:com.tencent.qqpimsecure
一個測試應用:com.example.boottest
File file = new File("/data/app/");String[] files = file.list();for (int i = 0; i < files.length; i++) {System.out.println("/data/app/:files["+(i+1)+"]:" + files[i]);}
結果為:
/data/app/:files[8]:com.tencent.qqpimsecure-1.apk
/data/app/:files[9]:com.qihoo360.mobilesafe-1.apk
/data/app/:files[10]:com.ijinshan.mguard-1.apk
/data/app/:files[11]:cn.com.fetion-1.apk
/data/app/:files[12]:com.lbe.security.lite-1.apk
/data/app/:files[13]:com.handsent.nextsms-1.apk
/data/app/:files[14]:com.example.boottest-1.apk
實際接收順序為:
12-06 15:19:58.187: I/System.out(1880): getPackageName:com.tencent.qqpimsecure
12-06 15:19:58.288: I/System.out(1893): getPackageName:com.qihoo360.mobilesafe
12-06 15:19:58.378: I/System.out(1906): getPackageName:com.ijinshan.mguard
12-06 15:19:58.488: I/System.out(1920): getPackageName:cn.com.fetion
12-06 15:19:58.608: I/System.out(1933): getPackageName:com.lbe.security.lite
12-06 15:19:58.718: I/System.out(1946): getPackageName:com.handsent.nextsms
12-06 15:19:58.908: I/System.out(1959): getPackageName:com.example.boottest
如果其中一個優先順序較高,比如cn.com.fetion,那麼實際的接收順序為
getPackageName:cn.com.fetion
getPackageName:com.tencent.qqpimsecure
getPackageName:com.qihoo360.mobilesafe
getPackageName:com.ijinshan.mguard
getPackageName:com.lbe.security.lite
getPackageName:com.handsent.nextsms
getPackageName:com.example.boottest
最後注意:
上面只是一個簡單測試,並不是這些應用就是按著這個順序,因為他們優先順序也許不一致,也許在/data/app下的檔案名稱不一致,導致順序不一致
不過,看到這裡,你應該知道如何去先於他們開機啟動了
對於ROOT後的機器
留給大家一個問題,如果我是病毒,那我應該怎樣去做呢?
顯然,最理想的方式就是找個殼子應用,把實體病毒apk放到/system/framework目錄中去,當然別忘了把自己的優先順序設定成最高,不然也是白費
android手機root後的安全問題 (一)
android手機root後的安全問題 (二)
android手機root後的安全問題 (三)
android手機root後的安全問題 (四)
android安全問題(一) 靜音拍照與被拍
android安全問題(二) 程式鎖
android安全問題(三) 釣魚程式
android安全問題(四) 搶先開機啟動 - 結果篇
android安全問題(五) 搶先攔截簡訊 - 結果篇
請大家不要用root的手機隨意下載軟體,更不要以任何借口製造任何病毒!
轉貼請保留以下連結
本人blog地址
http://su1216.iteye.com/
http://blog.csdn.net/su1216/