前面在DcTracker初始化過程中註冊了大量監聽器,其中有兩個監聽器可以觸發APN的創建過程:1、SIM載入完畢;2、APN改變。其中SIM載入完畢的註冊是EVENT_RECORDS_LOADED事件,APN改變是註冊了一個ApnChangeObserver類來監聽。
當SIM載入完畢時,將會觸發onRecordsLoaded()
private void onRecordsLoaded() {
logi("onRecordsLoaded: createAllApnList");
mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
.getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
createAllApnList();
setInitialAttachApn();
if (mPhone.mCi.getRadioState().isOn()) {
if (DBG) log("onRecordsLoaded: notifying data availability");
notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
}
setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
}
當APN改變時,用戶指定APN,將會觸發onApnChanged()
/**
* Handles changes to the APN database.
*/
private void onApnChanged() {
DctConstants.State overallState = getOverallState();
boolean isDisconnected = (overallState == DctConstants.State.IDLE ||
overallState == DctConstants.State.FAILED);
createAllApnList();
setInitialAttachApn();
cleanUpConnectionsOnUpdatedApns(!isDisconnected);
// FIXME: See bug 17426028 maybe no conditional is needed.
if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubId()) {
setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
}
}
兩個事件都會調用createAllApnList()和setInitialAttachApn(),分別是初始化當前卡可用的所有APN和設置默認聯網用的APN,首先看createAllApnList()
private void createAllApnList() {
mAllApnSettings = new ArrayList<ApnSetting>();
IccRecords r = mIccRecords.get();
String operator = (r != null) ? r.getOperatorNumeric() : "";
if (operator != null) {
String selection = "numeric = '" + operator + "'";
Cursor cursor = mPhone.getContext().getContentResolver().query(
Telephony.Carriers.CONTENT_URI, null, selection, null, null);
if (cursor != null) {
if (cursor.getCount() > 0) {
mAllApnSettings = createApnList(cursor);
}
cursor.close();
}
}
addEmergencyApnSetting(); // 添加emergencyApnSettings
dedupeApnSettings(); // 去除重複的APN
if (mAllApnSettings.isEmpty()) {
mPreferredApn = null;
} else {
mPreferredApn = getPreferredApn();
if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
mPreferredApn = null;
setPreferredApn(-1);
}
}
setDataProfilesAsNeeded();
}
這裏面主要做了三件事
1、創建一個APN的列表,其中包含:當前SIM對應的APN、緊急APN;
APN的來源是telephony.db數據庫中表carries,數據庫的的參數是更新於apns-conf.xml文件
2、合併相同的APN;
在apns-conf.xml中的APN有可能又重複的
3、尋找一個當前Prefer的APN參數;
用戶使用一張卡時,可能手動選擇過使用的APN,因此,當用戶再次插拔卡後,getPreferredApn用於找出用戶之前選擇的APN
這個mPreferredApn會在buildWaitingApns中被檢查
如果mPreferredApn滿足用戶數據鏈接的需求,那麼buildWaitingApns就直接會返回mPreferredApn用於聯網使用的APN
如果mPreferredApn已經不能滿足用戶數據鏈接的需求時,纔會從mAllApnSettings(createAllApnList)中去找合適的APN用於聯網
這就是爲什麼setupData中getNextWaitingApn要去拿list的第0個APN聯網,因爲當mPreferredApn有效時,只會有一個APN存在apnContext中
以上就是APN的初始化和設置默認值