Android Ethernet从上至下解析一
2016-07-16 23:10
246 查看
http://www.2cto.com/kf/201508/438539.html
最近遇到不少框架问题,比如关于网口的,开机后拔掉有线网,状态栏和设置项中有线网显示图标不会更新,还有双网口的需求,下面就带着这个问题,以跟踪网络状态问题为引线,本篇将贯穿分析Ethernet从上至下的框架结构。因能力和时间有限,文中有分析不到位的地方,十分欢迎大侠们拍砖。
首先看下应用层网络监听相关的app 网络监听一:设置 packages/apps/Settings/src/com/android/settings/ethernet/EthernetEnabler.java
设置项网络按钮类定义
网络监听二:statusbar frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
NetworkController本身是个BroadcastReceiver,其中关于网络状态变化的监听消息为EthernetManager.NETWORK_STATE_CHANGED_ACTION,可以猜测这个消息是framework发出来的,往下看。
网络服务框架层 通过整理,网络框架管理器和服务相关代码和基本解释如下: frameworks/base/ethernet/java/com/android/internal/ethernet/
?
在此可以发现网络状态机也在监听NETWORK_STATE_CHANGED_ACTION广播,广播发送者不再这里,那应该就是在service那了,继续往下。 frameworks/base/services/java/com/android/server/EthernetService.java
?
在service中,可以看到发送NETWORK_STATE_CHANGED_ACTION的发送动作,而这个发送行为还不是底层上报的状态直接启动的,而是上面说的网络状态机,它发送的INTERFACE_STATE_CHANGED_ACTION广播信息,怎么源头又跑上面去了?有些人可能并不理解为什么在framework里面要把一个简单的事件广播要这么来回的发送,等明白了网络状态机的作用,就知道这些过程的逻辑性了。
我们知道statemachine的特点是有一个rootstate,然后向下由多个state发展而成一个树状结构,state之间的转换会伴随着enter(),processMessage()等动作。EthernetStateMachine的状态初始化如下:
?
接着前面说到的INTERFACE_STATE_CHANGED_ACTION广播继续来看下状态机中的逻辑。 在ethernetstatemachine中,state状态的变化控制着网络状态的广播通知,部分代码如下:
?
上面就是网络状态机的逻辑功能,而状态机的消息来源是service,
?
看到了来来回回的广播,至此算是结束了,这里还要注意一点,广播收发程序中,我们要注意一个序列化参数的传递,就是EthernetInfo对象,这个对象存储着当前网络状态参数。
我们可以这么理解:网络状态机是EthernetService的辅助逻辑处理单元,service通过给状态机发送消息并等待状态机处理结果,然后将结果发送给应用程序。这个就是网络部分framework层的大致逻辑,了解这个之后,我们继续分析service是从哪里取得网络状态消息的。
来看下EthernetService的构造函数:
?
看下NetworkManagementEventObserver的实现:
?
这里我们看到seivice从NetworkManagementService进行函数回调。 NetworkManagementService也是注册到系统中的服务项,顾名思义负责网络管理服务,具体功能在本篇不做深入分析,其中之一通过socket和netd进行交互,这个在后面继续跟踪。
?
在后续的分析中,我们开始了解到framework到native的交互,这里我们先看一张网络的图示
卓老师三合一建站代理,0加盟
【点击进入】
独立品牌,免备案,PC+手机+微站一键生成
0加盟费,送百万建站系统+销售系统
查 看
我们按照图示的最上层来看看NetworkManagementService.java
?
这里socket值就是netd字符串,service启动了名为NativeDaemonConnector的Runnable线程,同时从构造函数中传递了NetdCallbackReceiver 对象,用于回调处理各种网络事件。
?
?
上面说了NativeDaemonConnector是一个Runnable的实现,那么这个线程在后台做些什么工作呢?在线程run函数中可以看到线程在while死循环中一直listenToSocket,可以猜想这里是在监听获取native中网络相关事件的地方了。
?
我们接下来看一下LocalSocket相关的类,了解一下这个socket是如何connect和get的。 LocalSocket*相关的类定义在 frameworks/base/core/java/android/net/ |->LocalSocket.java
|->LocalSocketAddress.java |->LocalSocketImpl.java 这里重点看下LocalSocketImpl类,其中就可以看到大量的native函数了,也就是通过jni完成java到C++的交互,有些人可能会有疑问,既然这里使用jni调用了C++库函数,但是这里没有看到System.loadlibary字眼啊。通过jni的基础我们知道这里java类使用的jni名字应该是android_net_LocalSocket*样子的,那么在android工程代码中也确实存在这个名字的cpp文件,路径是frameworks/base/core/jni/。可以确认我们这里的java层就是调用这里的lib库了,而编译后我们知道这个库名为libandroid_runtime.so。那么这个库在哪里load的呢?下面简要提一下。
我们知道android启动时,第一个进程init在解析init.rc时创建了app_process,app_process在创建zygote进程前首先建立dalvikvm虚拟机环境,初始化android
runtime,这里就在C环境下预先加载了libandroid_runtime.so库。如下: frameworks/base/core/jni/AndroidRuntime.cpp
?
了解了库加载的问题后,我们接着看LocalSocketImpl.java中使用的几个重要的函数:
?
函数具体内容不具体贴出来,其中可以看到调用了本地方法如read_native(),writeba_native()等。我们就走到native的大门了。打开本地函数文件,看下native中本地函数列表。 frameworks/base/core/jni/android_net_LocalSocketImpl.cpp
?
最近遇到不少框架问题,比如关于网口的,开机后拔掉有线网,状态栏和设置项中有线网显示图标不会更新,还有双网口的需求,下面就带着这个问题,以跟踪网络状态问题为引线,本篇将贯穿分析Ethernet从上至下的框架结构。因能力和时间有限,文中有分析不到位的地方,十分欢迎大侠们拍砖。
首先看下应用层网络监听相关的app 网络监听一:设置 packages/apps/Settings/src/com/android/settings/ethernet/EthernetEnabler.java
设置项网络按钮类定义
网络监听二:statusbar frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
NetworkController本身是个BroadcastReceiver,其中关于网络状态变化的监听消息为EthernetManager.NETWORK_STATE_CHANGED_ACTION,可以猜测这个消息是framework发出来的,往下看。
网络服务框架层 通过整理,网络框架管理器和服务相关代码和基本解释如下: frameworks/base/ethernet/java/com/android/internal/ethernet/
?
?
我们知道statemachine的特点是有一个rootstate,然后向下由多个state发展而成一个树状结构,state之间的转换会伴随着enter(),processMessage()等动作。EthernetStateMachine的状态初始化如下:
?
?
?
我们可以这么理解:网络状态机是EthernetService的辅助逻辑处理单元,service通过给状态机发送消息并等待状态机处理结果,然后将结果发送给应用程序。这个就是网络部分framework层的大致逻辑,了解这个之后,我们继续分析service是从哪里取得网络状态消息的。
来看下EthernetService的构造函数:
?
?
?
卓老师三合一建站代理,0加盟
【点击进入】
独立品牌,免备案,PC+手机+微站一键生成
0加盟费,送百万建站系统+销售系统
查 看
我们按照图示的最上层来看看NetworkManagementService.java
?
?
?
|->LocalSocketAddress.java |->LocalSocketImpl.java 这里重点看下LocalSocketImpl类,其中就可以看到大量的native函数了,也就是通过jni完成java到C++的交互,有些人可能会有疑问,既然这里使用jni调用了C++库函数,但是这里没有看到System.loadlibary字眼啊。通过jni的基础我们知道这里java类使用的jni名字应该是android_net_LocalSocket*样子的,那么在android工程代码中也确实存在这个名字的cpp文件,路径是frameworks/base/core/jni/。可以确认我们这里的java层就是调用这里的lib库了,而编译后我们知道这个库名为libandroid_runtime.so。那么这个库在哪里load的呢?下面简要提一下。
我们知道android启动时,第一个进程init在解析init.rc时创建了app_process,app_process在创建zygote进程前首先建立dalvikvm虚拟机环境,初始化android
runtime,这里就在C环境下预先加载了libandroid_runtime.so库。如下: frameworks/base/core/jni/AndroidRuntime.cpp
?
?
?
相关文章推荐
- android TextView setEms 方法名字
- 给 Android 开发者的 RxJava 详解
- Android CheckBox paddingleft 无效
- Android Netd ndc (Native Daemon Connector)
- 实例:创建、启动、停止和绑定一个Service
- android中wifi原理及流程分析(很经典)
- Android Studio中Intel HAXM的那些坑
- Android setCompoundDrawables无效
- Android Wi-Fi — IP forward — ndc — netd
- Android 学习杂记
- Android View的scrollTo(),scrollBy(),getScrollX(),getScrollY()
- Android中的单位和尺寸
- Android自定义键盘之汉字键盘
- Android RecyclerView 使用完全解析
- Android 事件总线OTTO用法快速入门
- Android系统发送短信
- Android中的进程和线程详解
- Android Activity知识点
- Android-逆向工程
- Android退出启动了多个Activity的应用程序