亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

【Android Developers Training】 80. 管理網(wǎng)絡

系統(tǒng) 2358 0

注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由于喜愛安卓而產(chǎn)生了翻譯的念頭,純屬個人興趣愛好。

原文鏈接: http://developer.android.com/training/basics/network-ops/managing.html


這節(jié)課將講解如何寫一個對使用網(wǎng)絡資源具有細粒度控制的應用。如果你的應用要執(zhí)行很多網(wǎng)絡操作,你需要提供用戶設置,使得用戶可以控制你的應用處理數(shù)據(jù)的行為,比如你的應用同步數(shù)據(jù)的頻率,是僅在有Wi-Fi連接的情況下上傳/下載,在漫游時是否處理數(shù)據(jù)等。當用戶可以進行這些設置時,用戶就不太會阻止你的應用訪問后臺數(shù)據(jù)了,因為他們能精確地控制應用能處理的數(shù)據(jù)范圍。

有關一些通用的關于如何編寫最小化影響電池壽命的應用程序,相關的引導可以閱讀: Optimizing Battery Life Transferring Data Without Draining the Battery


一). 檢查設備的網(wǎng)絡連接

一個設備可以有許多種網(wǎng)絡連接。這節(jié)課關注于使用Wi-Fi連接或者移動網(wǎng)絡連接。完整的連接類型列表,可以閱讀: ConnectivityManager

一般而言,Wi-Fi速度更快。另外移動數(shù)量一般按照流量計費,所以會很昂貴。通常的策略是只在有Wi-Fi連接的情況下獲取大數(shù)據(jù)。

在你執(zhí)行網(wǎng)絡操作之前,檢查網(wǎng)絡的連接狀態(tài)時一個好的習慣。這可以防止你的應用錯誤地使用網(wǎng)絡連接方式。如果網(wǎng)絡連接無法獲取,你的應用應該恰當?shù)刈龀鲰憫R獧z查網(wǎng)絡連接狀態(tài),通常你會使用下列類:

  • ConnectivityManager ?- 響應網(wǎng)絡連接狀態(tài)的查詢。它也在網(wǎng)絡連接放生改變時,通知應用。
  • NetworkInfo ?- 對給定的類型(移動數(shù)據(jù)或者Wi-Fi)描繪網(wǎng)絡接口的狀態(tài)。

這個代碼檢測Wi-Fi和移動數(shù)據(jù)的網(wǎng)絡連接。它確定這些網(wǎng)絡接口是否可用(網(wǎng)絡連接是否可以獲取)或者是否已連接(也就是說,網(wǎng)絡連接是否存在或者是否可能建立套接字并傳輸數(shù)據(jù)):

      
        private
      
      
        static
      
      
        final
      
       String DEBUG_TAG = "NetworkStatusExample"
      
        ;

...      

ConnectivityManager connMgr 
      
      =
      
         (ConnectivityManager) 

        getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo networkInfo 
      
      =
      
         connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 


      
      
        boolean
      
       isWifiConn =
      
         networkInfo.isConnected();

networkInfo 
      
      =
      
         connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);


      
      
        boolean
      
       isMobileConn =
      
         networkInfo.isConnected();

Log.d(DEBUG_TAG, 
      
      "Wifi connected: " +
      
         isWifiConn);

Log.d(DEBUG_TAG, 
      
      "Mobile connected: " + isMobileConn);
    

注意,在做決策時不可以僅根據(jù)網(wǎng)絡是否可獲得來進行。應該在每次進行網(wǎng)絡操作之間檢查 isConnected() ,因為 isConnected() 能夠處理諸如片狀移動網(wǎng)絡(flaky mobile networks),飛行模式,以及后臺限制的數(shù)據(jù)。

一個更簡潔的方法是檢查是否有一個可獲得的網(wǎng)絡連接接口,如下所示。 getActiveNetworkInfo() 方法返回一個 NetworkInfo 實例,它代表它能發(fā)現(xiàn)的第一個已連接的網(wǎng)絡接口,或者在沒有已連接的網(wǎng)絡接口時返回 null (意味著無法獲取一個網(wǎng)絡連接):

      
        public
      
      
        boolean
      
      
         isOnline() {

    ConnectivityManager connMgr 
      
      =
      
         (ConnectivityManager) 

            getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo networkInfo 
      
      =
      
         connMgr.getActiveNetworkInfo();

    
      
      
        return
      
       (networkInfo != 
      
        null
      
       &&
      
         networkInfo.isConnected());

}  
      
    

要查詢更詳細的連接狀態(tài),你可以使用 NetworkInfo.DetailedState ,但一般來說這是不必要的。


二). 管理網(wǎng)絡的使用

你可以實現(xiàn)一個用以對應用進行設置的activity,使得用戶可以對應用對網(wǎng)絡資源的使用進行控制。例如:

  • 你可以只允許用戶在連接了Wi-Fi的情況下上傳視頻;
  • 你可以根據(jù)多個標準,如網(wǎng)絡可獲得否,時間間隔,等等,進行同步(或不進行)。

要寫一個支持網(wǎng)絡訪問和管理網(wǎng)絡使用的應用,你的應用需要有相應的權限和intent過濾器。

  • 下面摘錄的的配置清單包含下列權限:
  • 你可以聲明針對于 ACTION_MANAGE_NETWORK_USAGE (該action自Android 4.0開始引入)的intent過濾器,它用來表明你的應用定義了一個可以對數(shù)據(jù)使用進行控制的activity。 ACTION_MANAGE_NETWORK_USAGE 展示了對某個特定應用的數(shù)據(jù)使用管理的設置。當你的應用有允許用戶設置網(wǎng)絡使用的activity時,你應該為該activity配置此intent過濾器。在樣例代碼中,該action由 SettingsActivity 捕獲并處理,它顯示一個配置界面,讓用戶來選擇何時下載:
      
        <?
      
      
        xml version="1.0" encoding="utf-8"
      
      
        ?>
      
      
        <
      
      
        manifest 
      
      
        xmlns:android
      
      
        ="http://schemas.android.com/apk/res/android"
      
      
        

    package
      
      
        ="com.example.android.networkusage"
      
      
        

    ...
      
      
        >
      
      
        <
      
      
        uses-sdk 
      
      
        android:minSdkVersion
      
      
        ="4"
      
      
         

           android:targetSdkVersion
      
      
        ="14"
      
      
        />
      
      
        <
      
      
        uses-permission 
      
      
        android:name
      
      
        ="android.permission.INTERNET"
      
      
        />
      
      
        <
      
      
        uses-permission 
      
      
        android:name
      
      
        ="android.permission.ACCESS_NETWORK_STATE"
      
      
        />
      
      
        <
      
      
        application

        
      
      
        ...
      
      
        >
      
      
        

        ...

        
      
      
        <
      
      
        activity 
      
      
        android:label
      
      
        ="SettingsActivity"
      
      
         android:name
      
      
        =".SettingsActivity"
      
      
        >
      
      
        <
      
      
        intent-filter
      
      
        >
      
      
        <
      
      
        action 
      
      
        android:name
      
      
        ="android.intent.action.MANAGE_NETWORK_USAGE"
      
      
        />
      
      
        <
      
      
        category 
      
      
        android:name
      
      
        ="android.intent.category.DEFAULT"
      
      
        />
      
      
        </
      
      
        intent-filter
      
      
        >
      
      
        </
      
      
        activity
      
      
        >
      
      
        </
      
      
        application
      
      
        >
      
      
        </
      
      
        manifest
      
      
        >
      
    

三). 實現(xiàn)一個配置Activity

如同你所看到的上述清單文件,樣例中的activity: SettingsActivity有一個針對于 ACTION_MANAGE_NETWORK_USAGE 的intent過濾器。 SettingsActivity是 PreferenceActivity 的一個子類。它顯示一個配置界面(如圖1所示)讓用戶可以進行下列控制:

  • 是否顯示每一個XML源條目的摘要,或僅對每個條目顯示其鏈接;
  • 是否在任何情況下下載XML源,或只在連接了Wi-Fi的情況下。

?

圖1. 配置activity

下面的代碼是 SettingsActivity ,注意它實現(xiàn)了 OnSharedPreferenceChangeListener 。當用戶進行了設置的變更時,會激活 onSharedPreferenceChanged() ,在該方法中會把 refreshDisplay 變?yōu)? true ,這會導致當用戶回到主activity時發(fā)生顯示刷新:

      
        public
      
      
        class
      
       SettingsActivity 
      
        extends
      
       PreferenceActivity 
      
        implements
      
      
         OnSharedPreferenceChangeListener {

    

    @Override

    
      
      
        protected
      
      
        void
      
      
         onCreate(Bundle savedInstanceState) {

        
      
      
        super
      
      
        .onCreate(savedInstanceState);

        

        
      
      
        //
      
      
         Loads the XML preferences file
      
      
                addPreferencesFromResource(R.xml.preferences);

    }

  

    @Override

    
      
      
        protected
      
      
        void
      
      
         onResume() {

        
      
      
        super
      
      
        .onResume();



        
      
      
        //
      
      
         Registers a listener whenever a key changes            
      
      

        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(
      
        this
      
      
        );

    }

  

    @Override

    
      
      
        protected
      
      
        void
      
      
         onPause() {

        
      
      
        super
      
      
        .onPause();



       
      
      
        //
      
      
         Unregisters the listener set in onResume().

       
      
      
        //
      
      
         It's best practice to unregister listeners when your app isn't using them to cut down on 

       
      
      
        //
      
      
         unnecessary system overhead. You do this in onPause().            
      
      

       getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
      
        this
      
      
        );    

    }

  

    
      
      
        //
      
      
         When the user changes the preferences selection, 

    
      
      
        //
      
      
         onSharedPreferenceChanged() restarts the main activity as a new

    
      
      
        //
      
      
         task. Sets the refreshDisplay flag to "true" to indicate that

    
      
      
        //
      
      
         the main activity should update its display.

    
      
      
        //
      
      
         The main activity queries the PreferenceManager to get the latest settings.
      
      
            

    @Override

    
      
      
        public
      
      
        void
      
      
         onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {    

        
      
      
        //
      
      
         Sets refreshDisplay to true so that when the user returns to the main

        
      
      
        //
      
      
         activity, the display refreshes to reflect the new settings.
      
      

        NetworkActivity.refreshDisplay = 
      
        true
      
      
        ;

    }

}
      
    

四). 響應配置變更

當用戶在配置界面改變了設置,它會改變應用的行為。在下面的代碼片段中,應用在 onStart() 方法內(nèi)檢查各項設置。如果在設置和設備網(wǎng)絡連接之間能夠匹配的上(例如,設置是“Wi-Fi”且應用具有一個可使用的Wi-Fi連接),那么應用會下載數(shù)據(jù)源并刷新頁面:

      
        public
      
      
        class
      
       NetworkActivity 
      
        extends
      
      
         Activity {

    
      
      
        public
      
      
        static
      
      
        final
      
       String WIFI = "Wi-Fi"
      
        ;

    
      
      
        public
      
      
        static
      
      
        final
      
       String ANY = "Any"
      
        ;

    
      
      
        private
      
      
        static
      
      
        final
      
       String URL = "http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest"
      
        ;

   

    
      
      
        //
      
      
         Whether there is a Wi-Fi connection.
      
      
        private
      
      
        static
      
      
        boolean
      
       wifiConnected = 
      
        false
      
      
        ; 

    
      
      
        //
      
      
         Whether there is a mobile connection.
      
      
        private
      
      
        static
      
      
        boolean
      
       mobileConnected = 
      
        false
      
      
        ;

    
      
      
        //
      
      
         Whether the display should be refreshed.
      
      
        public
      
      
        static
      
      
        boolean
      
       refreshDisplay = 
      
        true
      
      
        ;

    

    
      
      
        //
      
      
         The user's current network preference setting.
      
      
        public
      
      
        static
      
       String sPref = 
      
        null
      
      
        ;

    

    
      
      
        //
      
      
         The BroadcastReceiver that tracks network connectivity changes.
      
      
        private
      
       NetworkReceiver receiver = 
      
        new
      
      
         NetworkReceiver();

    

    @Override

    
      
      
        public
      
      
        void
      
      
         onCreate(Bundle savedInstanceState) {

        
      
      
        super
      
      
        .onCreate(savedInstanceState);

        

        
      
      
        //
      
      
         Registers BroadcastReceiver to track network connection changes.
      
      

        IntentFilter filter = 
      
        new
      
      
         IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);

        receiver 
      
      = 
      
        new
      
      
         NetworkReceiver();

        
      
      
        this
      
      
        .registerReceiver(receiver, filter);

    }

    

    @Override 

    
      
      
        public
      
      
        void
      
      
         onDestroy() {

        
      
      
        super
      
      
        .onDestroy();

        
      
      
        //
      
      
         Unregisters BroadcastReceiver when app is destroyed.
      
      
        if
      
       (receiver != 
      
        null
      
      
        ) {

            
      
      
        this
      
      
        .unregisterReceiver(receiver);

        }

    }

    

    
      
      
        //
      
      
         Refreshes the display if the network connection and the

    
      
      
        //
      
      
         pref settings allow it.
      
      
            

    @Override

    
      
      
        public
      
      
        void
      
      
         onStart () {

        
      
      
        super
      
      
        .onStart();  

        

        
      
      
        //
      
      
         Gets the user's network preference settings
      
      

        SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(
      
        this
      
      
        );

        

        
      
      
        //
      
      
         Retrieves a string value for the preferences. The second parameter

        
      
      
        //
      
      
         is the default value to use if a preference value is not found.
      
      

        sPref = sharedPrefs.getString("listPref", "Wi-Fi"
      
        );



        updateConnectedFlags(); 

       

        
      
      
        if
      
      
        (refreshDisplay){

            loadPage();    

        }

    }

    

    
      
      
        //
      
      
         Checks the network connection and sets the wifiConnected and mobileConnected

    
      
      
        //
      
      
         variables accordingly. 
      
      
        public
      
      
        void
      
      
         updateConnectedFlags() {

        ConnectivityManager connMgr 
      
      =
      
         (ConnectivityManager) 

                getSystemService(Context.CONNECTIVITY_SERVICE);

        

        NetworkInfo activeInfo 
      
      =
      
         connMgr.getActiveNetworkInfo();

        
      
      
        if
      
       (activeInfo != 
      
        null
      
       &&
      
         activeInfo.isConnected()) {

            wifiConnected 
      
      = activeInfo.getType() ==
      
         ConnectivityManager.TYPE_WIFI;

            mobileConnected 
      
      = activeInfo.getType() ==
      
         ConnectivityManager.TYPE_MOBILE;

        } 
      
      
        else
      
      
         {

            wifiConnected 
      
      = 
      
        false
      
      
        ;

            mobileConnected 
      
      = 
      
        false
      
      
        ;

        }  

    }

      

    
      
      
        //
      
      
         Uses AsyncTask subclass to download the XML feed from stackoverflow.com.
      
      
        public
      
      
        void
      
      
         loadPage() {

        
      
      
        if
      
       (((sPref.equals(ANY)) && (wifiConnected ||
      
         mobileConnected))

                
      
      || ((sPref.equals(WIFI)) &&
      
         (wifiConnected))) {

            
      
      
        //
      
      
         AsyncTask subclass
      
      
        new
      
      
         DownloadXmlTask().execute(URL);

        } 
      
      
        else
      
      
         {

            showErrorPage();

        }

    }

...

    

}
      
    

五). 檢測連接變更

最后一部分內(nèi)容是關于 NetworkReceiver BroadcastReceiver 的子類。當設備的網(wǎng)絡連接發(fā)生了變化, NetworkReceiver 會攔截 CONNECTIVITY_ACTION ,確定當前的連接狀態(tài)時什么,并相應地將 wifiConnected mobileConnected 設置為true/false。產(chǎn)生的結(jié)果是,下一次用戶回到應用時,應用會僅下載最后一個源并在 NetworkActivity.refreshDisplay 為true的情況下刷新頁面。

配置一個會被不必要地調(diào)用的 BroadcastReceiver會消耗系統(tǒng)資源。樣例中,在 onCreate() 方法中注冊了 BroadcastReceiver ? NetworkReceiver,并在 onDestroy() 中銷毀它。一種更輕量級的解決方法是在清單文件中聲明一個 ? <receiver> 。當你這樣做了之后,它會在任何時間喚起你的應用,甚至是你已經(jīng)好幾周沒有運行該應用了。如果在主 activity 中注冊或注銷 NetworkReceiver, 用戶在離開應用后就不會再被喚起了。如果你在清單文件中聲明了一個 <receiver>,并且你明確的知道你在什么地方會需要它,那么你可以使用 setComponentEnabledSetting() 在恰當?shù)貢r機啟用或禁用它。

下面是 NetworkReceiver:

      
        public
      
      
        class
      
       NetworkReceiver 
      
        extends
      
      
         BroadcastReceiver {   

      

@Override


      
      
        public
      
      
        void
      
      
         onReceive(Context context, Intent intent) {

    ConnectivityManager conn 
      
      =
      
          (ConnectivityManager)

        context.getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo networkInfo 
      
      =
      
         conn.getActiveNetworkInfo();

       

    
      
      
        //
      
      
         Checks the user prefs and the network connection. Based on the result, decides whether

    
      
      
        //
      
      
         to refresh the display or keep the current display.

    
      
      
        //
      
      
         If the userpref is Wi-Fi only, checks to see if the device has a Wi-Fi connection.
      
      
        if
      
       (WIFI.equals(sPref) && networkInfo != 
      
        null
      
       && networkInfo.getType() ==
      
         ConnectivityManager.TYPE_WIFI) {

        
      
      
        //
      
      
         If device has its Wi-Fi connection, sets refreshDisplay

        
      
      
        //
      
      
         to true. This causes the display to be refreshed when the user

        
      
      
        //
      
      
         returns to the app.
      
      

        refreshDisplay = 
      
        true
      
      
        ;

        Toast.makeText(context, R.string.wifi_connected, Toast.LENGTH_SHORT).show();



    
      
      
        //
      
      
         If the setting is ANY network and there is a network connection

    
      
      
        //
      
      
         (which by process of elimination would be mobile), sets refreshDisplay to true.
      
      

    } 
      
        else
      
      
        if
      
       (ANY.equals(sPref) && networkInfo != 
      
        null
      
      
        ) {

        refreshDisplay 
      
      = 
      
        true
      
      
        ;

                 

    
      
      
        //
      
      
         Otherwise, the app can't download content--either because there is no network

    
      
      
        //
      
      
         connection (mobile or Wi-Fi), or because the pref setting is WIFI, and there 

    
      
      
        //
      
      
         is no Wi-Fi connection.

    
      
      
        //
      
      
         Sets refreshDisplay to false.
      
      

    } 
      
        else
      
      
         {

        refreshDisplay 
      
      = 
      
        false
      
      
        ;

        Toast.makeText(context, R.string.lost_connection, Toast.LENGTH_SHORT).show();

    }

}
      
    

【Android Developers Training】 80. 管理網(wǎng)絡使用


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 免费一级毛片不卡在线播放 | 天天插天天操天天干 | 在线观看a视频 | 欧美一级毛片无遮 | 亚洲国产婷婷香蕉久久久久久 | 色淫综合| www欧美com| 性做久久 | 日本免费成人网 | 免费一级欧美大片久久网 | 色片网站在线观看 | 亚洲综合极品香蕉久久网 | 性一交一乱一视频免费看 | 国产色网 | 四虎黄色影视库 | 日本午夜大片a在线观看 | 99久久日本一区二区波多野结衣 | 在线观看视频中文字幕 | 99热国产这里只有精品99 | 亚欧人成精品免费观看 | 成人免费一级片 | 久久国产精品99久久久久久老狼 | 日韩黄色网 | 欧美日韩视频在线 | 就色干综合 | 香蕉久久ac一区二区三区 | 日本精品久久久一区二区三区 | 天天爽夜夜爽人人爽 | 99久久精品国产高清一区二区 | 国产福利第一页 | 久久精品国产一区二区小说 | 欧美在线成人午夜影视 | japanese乱子欧美| 久久亚洲欧美成人精品 | 亚洲性夜夜综合久久麻豆 | 伊人96| 狠狠色噜狠狠狠狠色综合久 | 高清国产一区二区三区 | 日日干日日爽 | 手机看片国产精品 | 亚洲欧美日韩国产综合 |