在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            Android WIFI 詳解

            作者: 時(shí)間:2016-10-08 來源:網(wǎng)絡(luò) 收藏

            public class WifiEnabler implementsPreference.OnPreferenceChangeListener {

            ……

            public boolean onPreferenceChange(Preference preference,Object value) {

            booleanenable = (Boolean) value;

            ……

            if (mWifiManager.setWifiEnabled(enable)) {

            mCheckBox.setEnabled(false);

            ……

            }

            ……

            }

            我們都知道Wifimanager只是個(gè)服務(wù)代理,所以它會(huì)調(diào)用WifiService的setWifiEnabled()函數(shù),而這個(gè)函數(shù)會(huì)調(diào)用 sendEnableMessage()函數(shù),了解android消息處理機(jī)制的都知道,這個(gè)函數(shù)最終會(huì)給自己發(fā)送一個(gè) MESSAGE_ENABLE_WIFI的消息,被WifiService里面定義的handlermessage()函數(shù)處理,會(huì)調(diào)用 setWifiEnabledBlocking()函數(shù)。下面是調(diào)用流程:

            mWifiEnabler.onpreferencechange()=>mWifiManage.setWifienabled()=>mWifiService.setWifiEnabled()=>mWifiService.sendEnableMessage()=>mWifiService.handleMessage()=>mWifiService.setWifiEnabledBlocking().

            在setWifiEnabledBlocking()函數(shù)中主要做如下工作:加載Wifi驅(qū)動(dòng),啟動(dòng)wpa_supplicant,注冊(cè)廣播接收器,啟動(dòng)WifiThread監(jiān)聽線程。代碼如下:

            ……

            if (enable) {

            if (!mWifiStateTracker.loadDriver()) {

            Slog.e(TAG, Failed toload Wi-Fi driver.);

            setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);

            return false;

            }

            if (!mWifiStateTracker.startSupplicant()) {

            mWifiStateTracker.unloadDriver();

            Slog.e(TAG, Failed tostart supplicant daemon.);

            setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);

            return false;

            }

            registerForBroadcasts();

            mWifiStateTracker.startEventLoop();

            ……

            至此,Wifi使能結(jié)束,自動(dòng)進(jìn)入掃描階段。

            (2) 掃描AP

            當(dāng)驅(qū)動(dòng)加載成功后,如果配置文件的AP_SCAN = 1,掃描會(huì)自動(dòng)開始,WifiMonitor將會(huì)從supplicant收到一個(gè)消息EVENT_DRIVER_STATE_CHANGED,調(diào)用 handleDriverEvent(),然后調(diào)用mWifiStateTracker.notifyDriverStarted(),該函數(shù)向消息隊(duì)列 添加EVENT_DRIVER_STATE_CHANGED,handlermessage()函數(shù)處理消息時(shí)調(diào)用scan()函數(shù),并通過 WifiNative將掃描命令發(fā)送到wpa_supplicant。

            Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java

            private void handleDriverEvent(Stringstate) {

            if (state == null) {

            return;

            }

            if (state.equals(STOPPED)) {

            mWifiStateTracker.notifyDriverStopped();

            } else if (state.equals(STARTED)) {

            mWifiStateTracker.notifyDriverStarted();

            } else if (state.equals(HANGED)) {

            mWifiStateTracker.notifyDriverHung();

            }

            }

            Frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java

            case EVENT_DRIVER_STATE_CHANGED:

            switch(msg.arg1) {

            case DRIVER_STARTED:

            /**

            *Set the number of allowed radio channels according

            *to the system setting, since it gets reset by the

            *driver upon changing to the STARTED state.

            */

            setNumAllowedChannels();

            synchronized (this) {

            if (mRunState == RUN_STATE_STARTING) {

            mRunState = RUN_STATE_RUNNING;

            if (!mIsScanOnly) {

            reconnectCommand();

            } else {

            // In somesituations, supplicant needs to be kickstarted to

            // start thebackground scanning

            scan(true);

            }

            }

            }

            break;

            上面是啟動(dòng)Wifi時(shí),自動(dòng)進(jìn)行的AP的掃描,用戶當(dāng)然也可以手動(dòng)掃描AP,這部分實(shí)現(xiàn)在WifiService里面,WifiService通過startScan()接口函數(shù)發(fā)送掃描命令到supplicant。

            Frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java

            public boolean startScan(booleanforceActive) {

            enforceChangePermission();

            switch (mWifiStateTracker.getSupplicantState()) {

            case DISCONNECTED:

            case INACTIVE:

            case SCANNING:

            case DORMANT:

            break;

            default:

            mWifiStateTracker.setScanResultHandling(

            WifiStateTracker.SUPPL_SCAN_HANDLING_LIST_ONLY);

            break;

            }

            return mWifiStateTracker.scan(forceActive);

            }

            然后下面的流程同上面的自動(dòng)掃描,我們來分析一下手動(dòng)掃描從哪里開始的。我們應(yīng)該知道手動(dòng)掃描是通過菜單鍵的掃描鍵來響應(yīng)的,而響應(yīng)該動(dòng)作的應(yīng)該是 WifiSettings類中Scanner類的handlerMessage()函數(shù),它調(diào)用WifiManager的 startScanActive(),這才調(diào)用WifiService的startScan()。

            packages/apps/Settings/src/com/android/settings/wifiwifisettings.java

            public boolean onCreateOptionsMenu(Menu menu) {

            menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan)

            .setIcon(R.drawable.ic_menu_scan_network);

            menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)

            .setIcon(android.R.drawable.ic_menu_manage);

            return super.onCreateOptionsMenu(menu);

            }

            當(dāng)按下菜單鍵時(shí),WifiSettings就會(huì)調(diào)用這個(gè)函數(shù)繪制菜單。如果選擇掃描按鈕,WifiSettings會(huì)調(diào)用onOptionsItemSelected()。

            packages/apps/Settings/src/com/android/settings/wifiwifisettings.java



            關(guān)鍵詞:

            評(píng)論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉