天天看點

android 系統資料業務---phone程序啟動1, Phone服務程序

前言:

電話管理是Android 系統支援的重要的業務之一,提供接聽電話,收發短信、電話薄、網絡事件監聽、

讀取使用者資訊、2G/3G/4G信号切換等功能。由上到下分為4層, PHONE應用層,Telephony架構實作層,

RIL層。本文基于android 5.1,架構圖如下,

整個架構的調用流程圖如下,

android 系統資料業務---phone程式啟動1, Phone服務程式

整個網絡雖然涉及到的程序也比較多,但是仔細分析起來關鍵點沒有多少。本文的關鍵點在于Framework的幾個程序,

上層的應用以及第三方有關phone的應用都是通過TelephonyManager這個API接口和phone程序進行binder通信,

當然手機中有部分操作本身就運作于phone程序中。

Phone程序一方面通過RIL.java檔案利用socket和hardware中的rild守護程序進行通信;另外一方面通過

NetworkAgent利用AsyncChannel和systemerver程序的ConnectivityService服務進行通信,管理網絡連接配接等等。

與此同時, systemerver程序還通過socket機制和netd守護程序完成網絡的相關操作等等。

在整個android系統中,phone子產品需要處理很多事務,例如電話的接聽/來去電,短信的收發等等,但是本文主要論述

Framework層的Phone服務程序有關2G/3G/4G信号切換流程。

1, Phone服務程序

Phone服務程序 (包名com.android.phone,以下簡稱phone程序)主要代碼位于以下目錄中,

packages/services/Telephony/

frameworks/opt/telephony/

frameworks/base/telephony/

1.1 phone程序啟動

Phone程序并不是在點選Luncher上的圖示啟動的,而是在系統開機啟動時,又ActivityManagerService啟動的。

Phone的AndroidManifest.xml檔案配置了如下屬性:

<application android:name="PhoneApp"  
android:persistent="true"  
android:label="@string/dialerIconLabel"  
android:icon="@drawable/ic_launcher_phone">  
           

對于android:persistent="true" 的應用是在Android開機時啟動的, 在android啟動完成時通過調用systemReady

方法來完成并通知服務啟動。ActivityManagerService服務的systemReady有關啟動android:persistent="true" 

應用的代碼如下,

//通過PackageManager查詢到所有android:persistent屬性為true的應用
List apps = AppGlobals.getPackageManager().getPersistentApplications(STOCK_PM_FLAGS);
if (apps != null) {
    int N = apps.size();
int i;
//周遊所有應用,并啟動
for (i=0; i<N; i++) {
    //得到每個應用的相關資訊
       ApplicationInfo info= (ApplicationInfo)apps.get(i);
       if (info != null &&!info.packageName.equals("android")) {
             //啟動應用
            addAppLocked(info, false, null /* ABI override */);
           

首先查詢apk檔案中android:persistent="true"的應用;

然後調用addAppLocked方法(最後調用startProcessLocked方法)啟動應用。

1.2 初始化

PhoneApp繼承自Application,是以,phone程序的入口方法為PhoneApp的onCreate方法,方法的調用流程圖如下,

android 系統資料業務---phone程式啟動1, Phone服務程式

初始化主要步驟如下,

1, RIL 初始化,

 開啟發送消息的線程:

mSenderThread = new HandlerThread("RILSender" + mInstanceId);
mSenderThread.start();
           

利用mSenderThread 建構RILSender 對象,這樣就可以向底層發送套接字消息了。

Looper looper = mSenderThread.getLooper();
mSender = new RILSender(looper);
           

同樣, 建構一個RILReceiver對象,接收底層發送的套接字消息

mReceiver = new RILReceiver();
mReceiverThread = new Thread(mReceiver, "RILReceiver" + mInstanceId);
mReceiverThread.start();
           

2,狀态/消息的注冊,這樣,底層傳輸上來的消息才可以分發處理。

例如,在GsmCallTracker的構造函數中注冊電話狀态,

mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
           

3, PhoneProxy相關代理類的初始化、NotificationMgr的初始化等等。