用AI赚第一桶💰低成本搭建一套AI赚钱工具,源码可二开。 广告
Netd中第二个重要成员是CommandListener(以后简称CL),其主要作用是接收来自Framework层NetworkManageService的命令。从角色来看,CL仅是一个Listener。它在收到命令后,只是将它们转交给对应的命令处理对象去处理。CL内部定义了许多命令,而这些命令都有较深的背景知识。本节拟以分析CL的工作流程为主,而相关的命令处理则放到后文再集中分析。 CL中的图2-4所示为CL中的Command对象及对应的Controller对象。 :-: ![](http://img.blog.csdn.net/20140303220835203?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSW5ub3N0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 图2-4 CL中的命令及控制类 由图2-4可知: CL定义了11个和网络相关的Command类。这些类均从NetdCommand派生(注意,为保持绘图简洁,这11个Command的派生关系由1个派生箭头表达)。CL还定义了10个控制类,这些控制类将和命令类共同完成相应的命令处理工作。 结合前面图2-2中对NM家族成员的介绍,CL创建时,需要注册自己支持的命令类。这部分代码在其构造函数中实现,代码如下所示: **CommandListener::CommandListener构造函数** ~~~ CommandListener::CommandListener() : FrameworkListener("netd", true) { registerCmd(new InterfaceCmd());//注册11个命令类对象 registerCmd(new IpFwdCmd()); registerCmd(new TetherCmd()); registerCmd(new NatCmd()); registerCmd(new ListTtysCmd()); registerCmd(new PppdCmd()); registerCmd(new SoftapCmd()); registerCmd(new BandwidthControlCmd()); registerCmd(new IdletimerControlCmd()); registerCmd(new ResolverCmd()); registerCmd(new FirewallCmd()); //创建对应的控制类对象 if (!sSecondaryTableCtrl) sSecondaryTableCtrl = new SecondaryTableController(); if (!sTetherCtrl) sTetherCtrl = new TetherController(); if (!sNatCtrl) sNatCtrl = new NatController(sSecondaryTableCtrl); if (!sPppCtrl) sPppCtrl = new PppController(); if (!sSoftapCtrl) sSoftapCtrl = new SoftapController(); if (!sBandwidthCtrl) sBandwidthCtrl = new BandwidthController(); if (!sIdletimerCtrl) sIdletimerCtrl = new IdletimerController(); if (!sResolverCtrl) sResolverCtrl = new ResolverController(); if (!sFirewallCtrl) sFirewallCtrl = new FirewallController(); if (!sInterfaceCtrl) sInterfaceCtrl = new InterfaceController(); //其他重要工作,后文再分析 } ~~~ 由于CL的间接基类也是SocketListener,所以其工作流程和NetlinkHandler类似。 为了方便读者理解,图2-5给出了CL的工作流程图: :-: ![](http://img.blog.csdn.net/20140303220904562?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSW5ub3N0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 图2-5 CL的工作流程示意图 图2-5中,假设Client端发送的命令名是"nat",当CL收到这个命令后,首先会从其构造函数中注册的那些命令对象中找到对应该名字(即"nat")的命令对象,其结果就是图中的NatCmd对象。而该命令最终的处理工作将由此NatCmd对象的runCommand函数完成。