android開發與實踐筆記(四)

第十四章 android啓動過程詳解
14.1 系統的啓動過程
        在android中,在Bootloader記載系統映像後,會通過 system\core\rootdir\ 目錄下的 init.rc 腳本進行初始化配置。
        在init.rc中可以配置系統時區,設置日誌等級,設置全局環境變量,掛載文件系統,初始化網絡配置,配置系統屬性,啓動守護進程等,具體過程如下:
              
          啓動過程中的配置是系統正常運行的基本保證。
14.1.1 系統屬性配置
      系統屬性包括多個方面,在開機啓動時,android將進行一系列的配置:
    》配置系統時區。android默認設置系統時區爲GMT 0。設置系統時區的方法如下:   sysclktz 0  //東8區
    》設置日誌等級。在android中,日誌分爲多個等級,設置控制檯輸出的日誌等級,默認爲3,設置方法:  loglevel 3
    》設置全局變量。系統啓動過程中,android需設置全局變量,具體入下:
           
    》初始化網路配置。在android中,網絡配置包括對lo和其他網絡接入點的信息進行配置,配置網絡參數的工具是 ifup, 具體如下:
                  ifup lo
                  hostname  localhost
                  demainname  localdomain
    》配置系統屬性。可在編譯腳本中對其進行設置。ActivityManagerSerivice中用到的一些配置 oom_adj 值的系統屬性如下:     
                  
                  
         oom_adj值通常被android特有的內存管理驅動 Low memory killer使用,它會在系統內存低於設定值時釋放響應的進程,保證系統的穩定運行。 Low memory killer 根據兩個原則(進程的重要性和釋放這個進程可獲取的空閒內存數量)來決定釋放的進程。 oom_adj 值越小,表示該類型的重要性越高。 oom_adj 相同的情況下,佔用內存到的進程有限被撤銷,進程佔用的內存可用 get_mm_rss 進行判斷。
14.1.2 文件系統掛載
        配置好文件系統分區並設置好分區表後,在設備實際啓動前,需要掛載文件系統。
   1.  創建掛載點並設置權限
         完成環境變量設置後,接下來就是創建掛載點並根據安全需要設置相應的權限。對於敏感信息,應避免普通用於對其用於可寫甚至可讀的權限。權限的主要設置方法如下;
                
          以上可看出,android 有兩個比較重要的用戶權限,即 root,  system ,其中root 權限最高,對於系統和讀寫的路徑至少應設置system權限。
    2. 掛載文件系統
          掛載點配置完成後,掛載文件系統。目前android默認的幾個文件系統爲system, data, cache等。掛載方法如下:
               
          默認情況下,android支持的問價系統類型爲 yaffs2 。
 14.1.3 守護進程啓動
        守護進程是運行在後臺的android核心進程,主要包括 servicemanager, vold, netd, debuggerd,  ril-daemon, zygote, drm, drmio, media, bootanim, dbus, bluetoothd, hfag, hsag, opush, pbap, installd,  falsh_recovery, ravonn, mtpd, keystore, dumpstate 等。
    1. 守護進程的配置(在init.rc中完成)
         由於守護進程之間可能存在依賴關係,或守護進程對其他配置存在依賴,在啓動進程時,需要做些配置。 在system\core\init\目錄下的 readme.txt 中介紹了包括守護進程在內的啓動項配置方法,其中守護進程的配置方法如下:
                 service  <name>  <pathname> [<argument>] *
                        <option>
                        ......
         上述代碼中,option有多種情況:
                 
  2. 守護進程的啓動
         下面介紹各守護進程的啓動和配置和作用。
    (1)servicemanager
          系統服務的管理器,通過一個HashMap<String,  IBinder>來管理系統服務,當servicemanager重啓時,會導致zygote和media重啓。 下面是servicemanager的啓動配置:
                 
     (2)vold的配置
           vold主要用來處理熱插拔,其實際上就是負責完成系統的CDROM, USB大容量存儲和MMC卡等擴展存儲的掛載任務的守護進程。vold和linux標準的udev類似,均通過sysfs爲內核和用於層提供通信。下面是vold的啓動配置:
                          
           熱插拔的處理框架:
                           
           和vold相關的代碼主要位於 system/vold目錄下。
   (3)netd
          主要用來監控網絡狀態,進行網絡管理,其實現位於system\netd目錄下,其啓動配置如下:
                        
    (4)debuggerd
          主要用於調試,啓動後會監聽UNIX套接字 android:debuggerd, 其實現位於system\core\debuggerd目錄下, 其啓動配置如下:
                         
    (5)ril-daemon
           RIL守護進程會初始化芯片廠商的RIL, 管理所有來自Android通信服務的通信,通過套件字實現與芯片廠商的RIL的通信,其實現與hardware/ril/rild無關,配置過程如下:
             
Android的RIL位於應用程序框架內核之間,分成了兩個部分,一個部分是rild,它負責socket與應用程序框架進行通信。另外一個部分是Vendor RIL,這個部分負責向下是通過兩種方式與radio進行通信,它們是直接與radio通信的AT指令通道和用於傳輸包數據的通道,數據通道用於手機的上網功能。
對於RIL的java框架部分,也被分成了兩個部分,一個是RIL模塊,這個模塊主要用於與下層的rild進行通信,另外一個是Phone模塊,這個模塊直接暴露電話功能接口給應用開發用戶,供他們調用以進行電話功能的實現。
                          
   (6)zygote
              是android啓動後啓動的第一個linux進程,其他的linux進程,比如各個應用,均是由zygote產生的。關於zygote的實現可參考ZygoteInit.java。zygote服務的重啓會導致media和netd服務的重啓,其啓動配置如下:
                         
   (7)drm
         用於數字版權保護,其啓動配置如下:
                         
   (8)drmio
          同樣用於數字版權保護,配置如上
   (9)media
          提供多媒體服務的守護進程,它會啓動 AudioFlinger,  MediaPlayerSerivce,  CameraService,  AudioPolicySerivce等服務。media服務的入口實現如下:
               
         media服務的啓動配置如下:
                    
   (10)bootanim
          即所謂的開機動畫服務,其具體實現位於BootAnimation.cpp中。 SurfaceFlinger 在完成準備工作後會在reayToRun()方法中,通過 porperty_set("ctl.start", "bootanim") 啓動bootanim服務。在bootanim服務啓動過程中,會加載用戶開機動畫和系統開機動畫,均爲zip格式,所在的位置爲 data\local\bootanimation.zip,  和 \system\media\bootanimation.zip。動畫中圖片的格式應爲RGB565,其實現位於frameworks\base\cmds\bootanimation目錄中,bootanim服務的啓動配置如下:
                     
     (11)dbus
            dbus和OpenBinder一樣都是進程間的通信機制,android進程間通信主要利用的是OpenBinder, dbus僅用於藍牙協議棧Bluez中。啓動配置如下: 
                         
      (12)bluetoothd
              爲bluez的守護進程,默認是不啓動的。啓動配置入下:
                               
       (13)hfag
                也用於Bluez, 作用是啓動藍牙免提音頻網關,默認不啓動。         
       (14) hsag
                  也用於Bluez, 作用是啓動藍牙耳機音頻網關,默認不開啓
       (15)opush 
                 實現 Exchange  ActiveSync服務器協議,同樣也用於Bluez。默認不啓動
        (16)installd
                 安裝守護線程,用於apk的安裝
        (17)flash_recovery
                  用於系統發生故障時的恢復。
        (18)racoon
                  是VPN的守護進程。
14.2  應用的啓動過程
       AAPT允許開發者查看,創建,更新與ZIP箭筒的壓縮文件(ZIP, JAR, APK),同時還將資源編譯到斷言(asset)中。
       APK包中,通常可以看到res,  AndroidManifest.xml, classes.dex,  resource.arsc, META-INF 和libs等幾項。其中 META-INF 中存放的是Android的數字簽名證書。
       需要說明的是,在android中,採用的java混淆器爲開源的ProGuard4.4。ProGuard可以在一定程度上防止別人的窺視,但對於需要保護的敏感信息,其安全性是無法保證的。
       android生成的java字節碼爲DEX字節碼,而非傳統的CLASS字節碼,但編譯過程中,是先將java 文件編譯爲 CLASS字節碼,然後將 CLASS字節碼轉化爲 DEX字節碼。
14.2.1 應用的啓動配置
       android應用由一個繼承了ContextWrapper的Application構成,其中Application由 Activity, Service, Receiver, Provider, uses-library等組件構成。組件之間的關係:
         
         需要注意的是,應用程序並非必須具有activity,如果僅是後臺程序,僅有application也是可以的。
         如果不希望應用在系統低內存時被系統銷燬,需將application標籤的 android:persistent 屬性設置爲 true.
14.2.2 應用的啓動過程
        要啓動一個應用,首先要創建一個進程,然後啓動UI主線程,接着打開Activity,具體流程如下:
                    
        android進程分爲zygote進程和普通進程。當啓動一個應用時,Dalvik虛擬機會先通過 NativeStart 接口初始化JNI,爲通過 zygote進程創建新進程做好準備。原生代碼的啓動位於:  app_main.app中


  第十五章  深入解析android系統管理
15.1 內存管理
      在創建進程時,Dalvik虛擬機會爲每個進程分配一定量的堆內存。佔用內存較多的程序很容易引起OutOfMemoryError等異常。
      在數據交換比較頻繁的場景中,多用SQLite來進行緩存。
 15.1.1 對應引用
          java對象的引用被分爲 強引用(HardReference), 弱引用(WeakReference), 軟引用(SoftReference)和 虛引用(PhantomReference)等4個級別。
         強引用表示 即使虛擬機內存“喫緊”拋出了 OutOfMemoryError 異常,該類型的對象也不會被回收; 
         軟引用表示 在虛擬機內存“喫緊”拋出了 OutOfMemoryError 異常前,該類型對象會被回收;
         弱引用 更適合那些數量不多,但體積較龐大的對象,弱引用對象最容易被回收
         虛引用一般沒有實際意義,僅觀察GC的活動狀態,對於 測試比較實用,必須和引用隊列(ReferenceQueue)一起使用。
         弱引用,軟引用,虛引用均可與引用隊列聯合使用,當引用的對象被回收時,Dalvik會把該引用對象加入到與之關聯的引用隊列。
         默認情況下,創建的java對象均爲強引用。創建引用隊列的方法如下:
                   ReferenceQueue<String> rq = new ReferenceQueue<String>()
         創建一個弱引用,並將對象和引用對象關聯的方法如下:
                   WeakReference<String> wf = new WeakReference<String>( str, rq );
15.1.2 垃圾回收策略
         android中,每個應用佔據一個虛擬機,所以android的垃圾回收是基於應用進行的。
         在應用層,通過調用 System.gc() 可以調用垃圾回收器回收垃圾
         事實上,在android的原生代碼層,通過引入引用計數機制,Android 同樣實現了自動垃圾回收機制,相關的實現位於 \frameworks\base\include\utils\RefBase.h 中。幾乎所有的原生類均繼承了 RefBase類,RefBase類會維護對象的強引用和弱引用計數,一旦強引用計數爲0, 對象自動釋放自己。原生代碼的垃圾回收機制如下圖所示:
                 
            其中維護強引用的指針爲 sp, 維護弱引用的指針爲 wp(weak pointer), sp 和 wp 均依賴於 RefBase類,因此繼承與RefBase類的原生類才具有自動垃圾回收的能力。
   1.  sp 的實現



待完善

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章