Wifi源码学习之wifi连接
来源:互联网 发布:sql删除 编辑:程序博客网 时间:2024/06/03 05:06
wifi 连接,我们从 点击连接开始分析。
Settings\src\com\android\settings\wifi\WifiSettings.java
首先看到 onActivityCreate() 方法中写了三个Listener。(看名字就知道是监听者模式)
而这一切似乎都和 这个 WifiManager.java 息息相关。
@Overridepublic void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); mConnectListener = new WifiManager.ActionListener() { @Override public void onSuccess() { } @Override public void onFailure(int reason) { Activity activity = getActivity(); if (activity != null) { Toast.makeText(activity, R.string.wifi_failed_connect_message, Toast.LENGTH_SHORT).show(); } } }; mSaveListener = new WifiManager.ActionListener() { @Override public void onSuccess() { } @Override public void onFailure(int reason) { Activity activity = getActivity(); if (activity != null) { Toast.makeText(activity, R.string.wifi_failed_save_message, Toast.LENGTH_SHORT).show(); } } }; mForgetListener = new WifiManager.ActionListener() { @Override public void onSuccess() { } @Override public void onFailure(int reason) { Activity activity = getActivity(); if (activity != null) { Toast.makeText(activity, R.string.wifi_failed_forget_message, Toast.LENGTH_SHORT).show(); } } };......}
我们再找找注册这些监听的地方:
发现有两种连接方式:
protected void connect(final WifiConfiguration config) { mWifiManager.connect(config, mConnectListener);}protected void connect(final int networkId) { mWifiManager.connect(networkId, mConnectListener);}
在这儿被调用
@Overridepublic boolean onContextItemSelected(MenuItem item) { // 我们再找找这个 mSelectedAccessPoint 变量在哪儿赋值 if (mSelectedAccessPoint == null) { return super.onContextItemSelected(item); } switch (item.getItemId()) { // 最终发现,连接的方法在这儿被调用。very good! case MENU_ID_CONNECT: { if (mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) { connect(mSelectedAccessPoint.networkId); } else if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE) { /** Bypass dialog for unsecured networks */ mSelectedAccessPoint.generateOpenNetworkConfig(); connect(mSelectedAccessPoint.getConfig()); } else { showDialog(mSelectedAccessPoint, true); } return true; } case MENU_ID_FORGET: { forget(); return true; } case MENU_ID_MODIFY: { showDialog(mSelectedAccessPoint, true); return true; } case MENU_ID_WRITE_NFC: showDialog(WRITE_NFC_DIALOG_ID); return true; } return super.onContextItemSelected(item);}
最终发现,mSelectedAccessPoint 在这个方法中赋值
@Overridepublic boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) { if (preference instanceof AccessPoint) { // 这个变量就是指当前点击的 wifi mSelectedAccessPoint = (AccessPoint) preference; /** Bypass dialog for unsecured, unsaved, and inactive networks */ if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE && mSelectedAccessPoint.networkId == INVALID_NETWORK_ID && !mSelectedAccessPoint.isActive()) { mSelectedAccessPoint.generateOpenNetworkConfig(); if (!savedNetworksExist) { savedNetworksExist = true; getActivity().invalidateOptionsMenu(); } connect(mSelectedAccessPoint.getConfig()); } else { showDialog(mSelectedAccessPoint, false); } } else { return super.onPreferenceTreeClick(screen, preference); } return true;}
继续追踪 connect 方法:注释很多哈
/** * Connect to a network with the given configuration. The network also * gets added to the supplicant configuration. * * For a new network, this function is used instead of a * sequence of addNetwork(), enableNetwork(), saveConfiguration() and * reconnect() * * @param config the set of variables that describe the configuration, * contained in a {@link WifiConfiguration} object. * @param listener for callbacks on success or failure. Can be null. * @throws IllegalStateException if the WifiManager instance needs to be * initialized again * * @hide */public void connect(WifiConfiguration config, ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); validateChannel(); // Use INVALID_NETWORK_ID for arg1 when passing a config object // arg1 is used to pass network id when the network already exists sAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, putListener(listener), config);}/** * Connect to a network with the given networkId. * * This function is used instead of a enableNetwork(), saveConfiguration() and * reconnect() * * @param networkId the network id identifiying the network in the * supplicant configuration list * @param listener for callbacks on success or failure. Can be null. * @throws IllegalStateException if the WifiManager instance needs to be * initialized again * @hide */public void connect(int networkId, ActionListener listener) { if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative"); validateChannel(); sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener));}
继续追踪;原来 sAsyncChannel 是在这儿被创建的。
private void init() { synchronized (sThreadRefLock) { if (++sThreadRefCount == 1) { Messenger messenger = getWifiServiceMessenger(); if (messenger == null) { sAsyncChannel = null; return; } sHandlerThread = new HandlerThread("WifiManager"); // 就是在这儿 sAsyncChannel = new AsyncChannel(); sConnected = new CountDownLatch(1); sHandlerThread.start(); Handler handler = new ServiceHandler(sHandlerThread.getLooper()); // 这个connect 方法就是初始化的作用 sAsyncChannel.connect(mContext, handler, messenger); try { sConnected.await(); } catch (InterruptedException e) { Log.e(TAG, "interrupted wait at init"); } } }}
然后我们回头看 它的 sendMessage() 方法到底干了什么。
frameworks\base\core\java\com\android\internal\util\AsyncChannel.java
public void sendMessage(int what, int arg1, int mListener, Object obj) { Message msg = Message.obtain(); msg.what = what; msg.arg1 = arg1; // 我们的监听 msg.mListener= mListener; msg.obj = obj; sendMessage(msg);}
继续吧。
/** * Send a message to the destination handler. * * @param msg */public void sendMessage(Message msg) { msg.replyTo = mSrcMessenger; try { mDstMessenger.send(msg); } catch (RemoteException e) { replyDisconnected(STATUS_SEND_UNSUCCESSFUL); }}
找找这个 mDstMessenger 是从哪儿来的?
connected 方法,是不是很熟悉。刚刚在我们的 init()方法中。
public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) { if (DBG) log("connected srcHandler to the dstMessenger E"); // Initialize source fields mSrcContext = srcContext; mSrcHandler = srcHandler; mSrcMessenger = new Messenger(mSrcHandler); // Initialize destination fields mDstMessenger = dstMessenger; if (DBG) log("connected srcHandler to the dstMessenger X");}
private void init() { synchronized (sThreadRefLock) { if (++sThreadRefCount == 1) { // 最终发现 Messenger messenger = getWifiServiceMessenger();再往下看看吧!public Messenger getWifiServiceMessenger() { try { return mService.getWifiServiceMessenger(); } catch (RemoteException e) { return null; } catch (SecurityException e) { return null; }}
追踪 mService.在这儿赋值。
public WifiManager(Context context, IWifiManager service) { mContext = context; mService = service; init();}
找找 WifiManager 初始化的地方:
frameworks\base\core\java\android\app\ContextImpl.java
Binder 进程间通信,咱就不再深究了。wifi 毕竟最终还是和硬件交互。registerService(WIFI_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(WIFI_SERVICE); IWifiManager service = IWifiManager.Stub.asInterface(b); return new WifiManager(ctx.getOuterContext(), service); }});
连接成功,失败都是在回调中处理。其它的好像也没有什么了。
阅读全文
0 0
- Wifi源码学习之wifi连接
- Android之Wifi学习(2)------连接Wifi
- Android之Wifi学习(2)------连接Wifi
- Android之Wifi学习(2)------连接Wifi
- Wifi 源码学习之wifi列表
- android学习之wifi - wifi连接woosim打印机
- Wifi源码学习(Android5.1)之wifi开关
- Wifi源码学习(Android5.1)之wifi optionItem
- wifi连接学习
- Android连接Wifi详细源码
- Android之Wifi学习
- WIFI学习之二:wifi 流程
- wifi连接
- WIFI连接
- Android4.0 wifi 启动流程3 之 wifi连接
- iOS私有API之wifi扫描和wifi连接
- iOS私有API之wifi扫描和wifi连接
- Android之Wifi学习(1)
- 微信公众号消息增加跳转链接
- 重新开始写博客 时间待定
- 完全卸载oracle11g步骤
- pyqt配置记录-关于eirc6的QT设计大师无法启动的问题
- Java多线程总结之由synchronized说开去
- Wifi源码学习之wifi连接
- 121. Best Time to Buy and Sell Stock 最佳买卖股票时间
- 一些从源码编译 pytorch的时候的问题
- 乌云平台资料
- Redis中的事件
- 搭建Nginx服务器
- C++文件流式读写
- CosmoMC第一次测试
- web删除文件例程