Android 2.3 拨号上网流程从源码角度进行分析

最亮的亮星

最亮的亮星

2016-02-19 10:53

想不想get新技能酷炫一下,今天图老师小编就跟大家分享个简单的Android 2.3 拨号上网流程从源码角度进行分析教程,一起来看看吧!超容易上手~
通常,如果我们想使用SIM卡拨号上网功能,我们要在设置中进行简单的配置,步骤如下
设置 -》无线和网络 -》移动网络 -》(已启用数据/数据漫游/接入点名称/仅使用2G网络/网络运营商)
我们必须选中其中的“已启用数据”选项,然后配置接入点名称后就可以上网了,当然有的设置中已经根据你的SIM卡类型默认设置了接入点,这时候你只选择“已启用数据”项后就可以完成上网功能设置。
这些设置步骤究竟做了哪些事情呢?我们现在就从源码的角度进行分析。

1. 首先,我们找到“移动网络”的设置UI-------Settings.java(/packages/apps/Phone/src/com/android/phone/Settings.java)
Settings.java:
"已启用数据"选项的相关代码如下:
代码如下:

......
else if (preference == mButtonDataEnabled) {
if (DBG) log("onPreferenceTreeClick: preference == mButtonDataEnabled.");
ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
cm.setMobileDataEnabled(mButtonDataEnabled.isChecked());
return true;
}
......

代码中,我们得到一个ConnectivityManager对象,并调用该对象的setMobileDataEnable(boolean b)方法,根据传入的参数进行设置,我们看一下ConnectivityManager类。

2. ConnectivityManager.java(/frameworks/base/core/java/android/net/ConnectivityManager.java)
这个时候,数据已经进入frameworks层。
setMobileDataEnable()方法代码如下:
代码如下:

IConnectivityManager mService;
......
 public ConnectivityManager(IConnectivityManager service) {
        if (service == null) {
            throw new IllegalArgumentException(
                "ConnectivityManager() cannot be constructed with null service");
        }
        mService = service;
    }
......
public void setMobileDataEnabled(boolean enabled) {
try {
mService.setMobileDataEnabled(enabled);
} catch (RemoteException e) {
}
}

这里我们要知道IConnectivityManager类,是根据IConnectivityManager.aidl接口自动生成的一个java类,而我们自己有一个Service则继承了该类的内部类:Stub,在我们自己为拨号上网实现的这个Service就是ConnectivityService,所以根据AIDL只是,我们知道,代码中的mService其实就是ConnectivityService类的对象,所以代码在这里实际上是调用了ConnectivityService对象的setMobileDataEnable()方法。

3. ConnectivityService.java(/frameworks/./base/services/java/com/android/server/ConnectivityService.java)
setMobileDataEnable()方法代码如下:
代码如下:

public void setMobileDataEnabled(boolean enabled) {
enforceChangePermission();
if (DBG) Slog.d(TAG, "setMobileDataEnabled(" + enabled + ")");
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA,
(enabled ? ENABLED : DISABLED), 0));
}

这里发送了一个消息出去,mHandler收到该消息以后:
代码如下:

case EVENT_SET_MOBILE_DATA:
{
boolean enabled = (msg.arg1 == ENABLED);
handleSetMobileData(enabled);
break;
}

收到该消息后,调用handleSetMobileData()方法:
代码如下:

private NetworkStateTracker mNetTrackers[];
......
private void handleSetMobileData(boolean enabled) {
        ......
if (enabled) {
if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) {
if (DBG) {
Slog.d(TAG, "starting up " + mNetTrackers[ConnectivityManager.TYPE_MOBILE]);
}
mNetTrackers[ConnectivityManager.TYPE_MOBILE].reconnect();
}
            ......
}
 }

如果“已启用数据”选项已经选择,那这个时候传进来的参数“enabled”应该是“true”,所以会处理代码中if语句块,即执行:
代码如下:

mNetTrackers[ConnectivityManager.TYPE_MOBILE].reconnect();

而在ConnectivityManager中,TYPE_MOBILE 为 0,所以这里相当于调用了
代码如下:

mNetTracker[0].reconnect()

但是,NetworkStateTracker是一个抽象类,所以具体的事情要交给它的子类MobileDataStateTracker.java来干。

4. MobileDataStateTracker.java(/frameworks/base/core/java/android/net/MobileDataStateTracker.java)
该类包含多种数据连接,包括MMS,SUPL,DUN等,
在MobileDataStateTracker.java里面的调用流程是这样的:
代码如下:

PRE class=java name="code"mPhoneService = ITelephony.Stub.asInterface(ServiceManager.getService("phone"));/PRE......BR
reconnect-mPhoneService.enableApnType(apnType);P/P
PRE/PRE
mPhoneService是电话的服务的客户端,它的server端实际上是PhoneInterfaceManager对象
P/P
P5. PhoneInterfaceManager.java(/packages/apps/Phone/src/com/android/phone/PhoneInterfaceManager.java)BR
/P
P看PhoneInterfaceManager的enableApnType方法:/P
PPRE class=java name="code" public int enableApnType(String type) {
enforceModifyPermission();
return mPhone.enableApnType(type);
}
/PREP/P
这样,就将连接apn的请求发送到telephony框架层下去了。apn在设置应用里面有指定,一般在你的工程目录下的system/etc/apns-conf.xml文件BR
BR
P6. 上面的mPhone是PhoneProxy对象,/P
P调用流程:/P
PPhoneProxy.java:BR
/P
PPRE class=java name="code"mActivePhone.enableApnType(type)/PREmActivePhone是GSMPhone或者CDMAPhone的上溯接口PhoneBase对象BR
P/P
PPhoneBase.java:/P
PPRE class=java name="code"mDataConnection.enableApnType(type);/PREP/P
P调用到 DataConnectionTracker的enableApnType方法/P
PDataConnectionTracker.java:BR
/P
PenableApnType(String type)-setEnabled-onEnableApn-onEnableNewApnBR
/P
BR
PonEnableNewApn方法在DataConnectionTracker的派生类GsmDataConnectionTracker和CdmaDataConnectionTracker中实现,从而区别不同类型PHONE的数据连接流程。BR
/P
P以GSM为例,调用流程:onEnableNewApn-cleanUpConnection-conn.disconnectBR
BR
/P
conn是DataConnection对象,标识一钟数据连接,可以看出这里实际上实现了一个数据连接的状态机。BR
P在DataConnection对象里面数据连接的状态分为:/P
PPRE class=java name="code"DcDefaultState,默认状态。
DcInactiveState,非激活状态。
DcActivatingState,正在激活状态
DcActiveState,激活状态
DcDisconnectingState,正在断开状态
DcDisconnectingBadDnsState,断开状态(因为错误的DNS)
/PREP/P
P连接成功以后,notifyDefaultData调用到DefaultPhoneNotifier的notifyDataConnection方法。/P
PDefaultPhoneNotifier是ITelephonyRegistry接口的客户端,其服务端是TelephonyRegistry(com.android.server.TelephonyRegistry)/P
PTelephonyRegistry的notifyDataConnection方法调用如下语句BR
PRE class=java name="code" r.callback.onDataConnectionStateChanged(state, networkType);/PREP/P
Pr是当前mRecords中的元素,包含有IPhoneStateListener接口的实现callback,TelephonyRegistry中的每个调用都会遍历mRecords中的元素,如果某个元素注册了对应接听,/P
P则调用callback的某个函数。/P
P客户端通过如下方式调用取得电话状态的监听, 以StatusBarPolicy.java中的mPhoneStateListener为例:/P
P            ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))/P
P                    .listen(mPhoneStateListener,BR
                              PhoneStateListener.LISTEN_SERVICE_STATEBR
                            | PhoneStateListener.LISTEN_SIGNAL_STRENGTHSBR
                            | PhoneStateListener.LISTEN_CALL_STATEBR
                            | PhoneStateListener.LISTEN_DATA_CONNECTION_STATEBR
                            | PhoneStateListener.LISTEN_DATA_ACTIVITY);BR
/P
PmPhoneStateListener是PhoneStateListener实例,PhoneStateListener实现了IPhoneStateListener接口,假如你继承PhoneStateListener子类,首先你要确定你感兴趣的监听/P
P事件,然后重写对应的方法。再像上面那样调用listen方法就可以了。/P
PTelephonyRegistry的方法、监听动作、已经你要重写的方法对应关系如下:/P
PTelephonyRegistry的方法  ---------------------监听动作-------------------------------------------------------PhoneStateListener子类中的中的回调BR
/P
PnotifyServiceState   ---------- PhoneStateListener.LISTEN_SERVICE_STATE       -----------------  public void onServiceStateChanged(ServiceState state) BR
/P
PnotifySignalStrength   ------- PhoneStateListener.LISTEN_SIGNAL_STRENGTHS     --------- --  public void onSignalStrengthsChanged(SignalStrength signalStrength)BR
/P
PnotifyCallState  ---------------- PhoneStateListener.LISTEN_CALL_STATE    -------------------------   public void onCallStateChanged(int state, String incomingNumber)BR
/P
PnotifyDataConnection ------- PhoneStateListener.LISTEN_DATA_CONNECTION_STATE    ---   public void onDataConnectionStateChanged(int state, int networkType)BR
/P
PnotifyDataActivity  -------------- PhoneStateListener.LISTEN_DATA_ACTIVITY -----------------------   public void onDataActivity(int direction)BR
/P
P。。。。。。。。/P
P因此整个调用链是:DefaultPhoneNotifier:notifyDataConnection ---------》 TelephonyRegistry :notifyDataConnection---------》/P
PPhoneStateListener.callback:onDataConnectionStateChanged --------------》PhoneStateListener子类的onDataConnectionStateChanged/P
P除此之外,TelephonyRegistry还发出一个ACTION_ANY_DATA_CONNECTION_STATE_CHANGED,包含数据连接的详细信息。/P
PBR
而Mobile Data Service里面的MobileDataStateTracker会接收到这个动作,由它的BoadcastReceiver类MobileDataStateReceiver提取出数据连接的信息,然后设置好状态/P
PRE class=java name="code"setDetailedState(DetailedState.CONNECTING, reason, apnName);
/PRE
PMobileDataStateTracker根据状态变化给ConnectivityService发送EVENT_STATE_CHANGED消息。/P
PConnectivityService调用handleConnect去执行相关炒作,包括关闭优先级比它低的数据连接,更新状态栏等等。BR
/P
P还有很多地方还没有搞明白,以后再续。BR
/P
PBR
/P
PBR
/P
BR
PBR
BR
/P
展开更多 50%)
分享

猜你喜欢

Android 2.3 拨号上网流程从源码角度进行分析

编程语言 网络编程
Android 2.3 拨号上网流程从源码角度进行分析

怎么拨号上网

电脑入门
怎么拨号上网

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

如何用 Linux 拨号上网

Linux Linux命令 Linux安装 Linux编程 Linux桌面 Linux软件 Linux内核 Linux管理
如何用 Linux 拨号上网

VC++实现拨号上网程序

编程语言 网络编程
VC++实现拨号上网程序

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

怎样用linux拨号上网

Linux Linux命令 Linux安装 Linux编程 Linux桌面 Linux软件 Linux内核 Linux管理
怎样用linux拨号上网

拨号上网必学的安全技巧

windows 操作系统
拨号上网必学的安全技巧

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

回到最初无伤害状态 - QQ图案分组

回到最初无伤害状态 - QQ图案分组

mssql SA帐号的改名和删除

mssql SA帐号的改名和删除
下拉加载更多内容 ↓