Android 網(wǎng)絡通信機制

前言:通過網(wǎng)上查詢Android網(wǎng)絡通信機制,大部分都是介紹這三種课竣。因此嘉赎,自己通過代碼來實現(xiàn)網(wǎng)絡通信。
首先先通過該網(wǎng)址 http://www.w3school.com.cn/tags/html_ref_httpmethods.asp 了解http中最常用的get和post請求區(qū)別公条。

一、標準的java接口(java.NET)

HttpURLConnection

HttpURLconnection是基于http協(xié)議的迂曲,支持get,post路捧,put关霸,delete等各種請求方式杰扫,最常用的就是get和post队寇,下面針對這兩種請求方式進行講解。
HttpURLconnection是同步的請求佳遣,所以必須放在子線程中,下面以登錄功能凡伊,來進行分析。(親測)

private String getUrl = "網(wǎng)址/login.shtml?loginName=xxxxx&password=xxxxx";
private String headUrl = "網(wǎng)址/login.shtml";
MyHttpURLConnection( ) {
    new Thread(new Runnable() {
        @Override
        public void run( ) {
            try {
                URL url = new URL(getUrl);
                //得到connection對象窗声。
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                //設置請求方式
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(3000);//連接的超時時間
                //連接
                connection.connect();
                //得到響應碼
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    //得到響應流  connection.getInputStream()只是得到一個流對象,并不是數(shù)據(jù)笨觅,從這個流對象中只能讀取一次數(shù)據(jù),第二次讀取時將會得到空數(shù)據(jù)
                    InputStream inputStream1 = connection.getInputStream();
                    //將響應流轉(zhuǎn)換成字符串
                    String result1 = stream2String(inputStream1);//將流轉(zhuǎn)換為字符串见剩。
                    Log.d("getHttpURLConnection","result=============" + result1);

                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

    new Thread(new Runnable() {
        @Override
        public void run( ) {
            try {
                URL url = new URL(getUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("POST");//設置請求方式為POST
                connection.setConnectTimeout(3000);//連接的超時時間
                connection.setDoOutput(true);//允許寫出
                connection.setDoInput(true);//允許讀入
                connection.setUseCaches(false);//不使用緩存
                connection.connect();//連接
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = connection.getInputStream();
                    String result = stream2String(inputStream);//將流轉(zhuǎn)換為字符串。
                    Log.d("postHttpURLConnection1","result=============" + result);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

    new Thread(new Runnable() {
        @Override
        public void run( ) {
            try {
                URL url = new URL(headUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("POST");
                connection.setDoOutput(true);
                connection.setDoInput(true);
                connection.setUseCaches(false);
                connection.connect();

                String body = "loginName=xxxx&password=xxxx";
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(),
                        "UTF-8"));
                writer.write(body);
                writer.close();

                //post Json數(shù)據(jù)
                //                    connection.setRequestProperty("Content-Type", "application/json;
                // charset=utf-8");//設置參數(shù)類型是json格式
                //                    connection.connect();
                //                    String body = "{userName:xxxx,password:xxxx}";
                //                    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter
                // (connection.getOutputStream(), "UTF-8"));
                //                    writer.write(body);
                //                    writer.close();

                //post上傳文件
                //                    connection.setRequestProperty("Content-Type", "file/*");//設置數(shù)據(jù)類型
                //                    connection.connect();
                //                    OutputStream outputStream = connection.getOutputStream();
                //                    FileInputStream fileInputStream = new FileInputStream("file");//把文件封裝成一個流
                //                    int length = -1;
                //                    byte[] bytes = new byte[1024];
                //                    while ((length = fileInputStream.read(bytes)) != -1){
                //                        outputStream.write(bytes,0,length);//寫的具體操作
                //                    }
                //                    fileInputStream.close();
                //                    outputStream.close();

                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = connection.getInputStream();
                    String result = stream2String(inputStream);//將流轉(zhuǎn)換為字符串固翰。
                    Log.d("postHttpURLConnection2","result=============" + result);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

}

/**
 * 將get獲取的字節(jié)流轉(zhuǎn)換為字符串
 * @param is
 * @return
 * @throws IOException
 */
private String stream2String(InputStream is) throws IOException {
    if (is != null) {// ByteArrayOutputStream好處:邊讀,邊緩沖數(shù)據(jù)// 可以捕獲內(nèi)存緩沖區(qū)的數(shù)據(jù)骂际,轉(zhuǎn)換成字節(jié)數(shù)組
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int temp = -1;
        while ((temp = is.read(buffer)) != -1) {
            baos.write(buffer,0,temp);
        }
        is.close();
        baos.close();
        return baos.toString();
    }
    return null;
}

以上是簡單的HttpURLConnection數(shù)據(jù)請求,得到的結果是一樣的歉铝,通過以上代碼可以清晰的看得出盈简,post和get請求數(shù)據(jù)的基本差異太示,以及它們通過網(wǎng)址的不同請求。

以下是http://www.w3school.com.cn/tags/html_ref_httpmethods.asp中的關于post和get請求區(qū)別列表

QQ截圖20181010173916.png

圖上標記為目前我所能看到和實現(xiàn)的类缤。

socket(這個比較特殊,下次有空詳細介紹)

二餐弱、Apache接口(org.apache.http)

HttpClient
private String getUrl = "網(wǎng)址/login.shtml?loginName=xxx&password=xxx";
private String headUrl = "網(wǎng)址/login.shtml";
private final BasicCookieStore cookieStore = new BasicCookieStore();
private HttpResponse getResp;
private HttpResponse postResp;
private HttpClient mHttpClient;

public MyHttpClient( ) {
    new Thread(new Runnable() {//get請求數(shù)據(jù)
        @Override
        public void run( ) {
            mHttpClient = new DefaultHttpClient();
            // 保持和服務器登錄狀態(tài)一直是登錄著的,必不可少設置全局唯一的Cookie(不了解這步的意圖岸裙,加不加都可get數(shù)據(jù))
            ((AbstractHttpClient) mHttpClient).setCookieStore(cookieStore);
            HttpGet httpGet = new HttpGet(getUrl);
            httpGet.addHeader("contentType","application/json");
            try {
                getResp = mHttpClient.execute(httpGet);
                if (getResp.getStatusLine().getStatusCode() == 200) {
                    String result = EntityUtils.toString(getResp.getEntity());
                    Log.i(TAG,"get請求結果: " + result);
                } else {
                    Log.i(TAG,"get請求結果: error");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

    new Thread(new Runnable() {//post請求數(shù)據(jù)
        @Override
        public void run( ) {
            mHttpClient = new DefaultHttpClient();
            // 保持和服務器登錄狀態(tài)一直是登錄著的速缆,必不可少設置全局唯一的Cookie
            ((AbstractHttpClient) mHttpClient).setCookieStore(cookieStore);
            HttpPost httpPost = new HttpPost(getUrl);
            httpPost.addHeader("contentType","application/json");
            try {
                postResp = mHttpClient.execute(httpPost);
                if (postResp.getStatusLine().getStatusCode() == 200) {
                    String result = EntityUtils.toString(postResp.getEntity());
                    Log.i(TAG,"post請求結果: " + result);
                } else {
                    Log.i(TAG,"post請求結果: error");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

    new Thread(new Runnable() {//post請求數(shù)據(jù)
        @Override
        public void run( ) {

            //創(chuàng)建客戶端對象
            mHttpClient = new DefaultHttpClient();
            //創(chuàng)建post請求對象
            HttpPost httpPost = new HttpPost(headUrl);

            //封裝form表單提交的數(shù)據(jù)
            BasicNameValuePair basicNameValuePair1 = new BasicNameValuePair("loginName","xxx");
            BasicNameValuePair basicNameValuePair2 = new BasicNameValuePair("password","xxx");
            List<BasicNameValuePair> parameters = new ArrayList<>();
            //把BasicNameValuePair放入集合中
            parameters.add(basicNameValuePair1);
            parameters.add(basicNameValuePair2);

            try {
                //要提交的數(shù)據(jù)都已經(jīng)在集合中了,把集合傳給實體對象
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters,"utf-8");
                //設置post請求對象的實體剧董,其實就是把要提交的數(shù)據(jù)封裝至post請求的輸出流中
                httpPost.setEntity(entity);
                //3.使用客戶端發(fā)送post請求
                postResp = mHttpClient.execute(httpPost);
                if (postResp.getStatusLine().getStatusCode() == 200) {
                    InputStream result = postResp.getEntity().getContent();
                    Log.i(TAG,"post請求結果: " + getTextFromStream(result));
                } else {
                    Log.i(TAG,"post請求結果: error");
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }).start()
  }

/**
 * 字節(jié)流轉(zhuǎn)換為字符串
 * @param result
 * @return
 */
private String getTextFromStream(InputStream result) {

    byte[] b = new byte[1024];
    int len = 0;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
        while ((len = result.read(b)) != -1) {
            bos.write(b,0,len);
        }
        String text = new String(bos.toByteArray());
        bos.close();
        return text;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

以上是HttpClient的get和post請求數(shù)據(jù)破停,簡單的三種數(shù)據(jù)請求翅楼,得到的結果相同真慢,在httpClient中post和get請求數(shù)據(jù)除了HttpPost 和httpGet的對象不同,其余的沒有什么差異黑界,不過也能實現(xiàn)上圖中get和post的區(qū)別表中的特性管嬉。

三朗鸠、Android.net網(wǎng)絡接口

對于android.net網(wǎng)絡接口本人不了解,但從網(wǎng)上查詢了解了一下之后烛占,知道這就是一個api接口,android自帶的接口,常常使用此包下的類進行Android特有的網(wǎng)絡編程德迹,如:訪問WiFi,訪問Android聯(lián)網(wǎng)信息项栏,郵件等功能。這個我用的比較少沼沈,一般用的都是別人寫好的。

 private Context mContext;
 AndroidNet(Context context) {
    this.mContext = context;

}

/**
 *     確定您是否連入了互聯(lián)網(wǎng)
 *     如果您未連入互聯(lián)網(wǎng)列另,則無需安排基于互聯(lián)網(wǎng)資源的更新芽腾。 下面這段代碼展示了如何利用 ConnectivityManager 查詢活動網(wǎng)絡并確定其是否連入了互聯(lián)網(wǎng)页衙。
 * @return true 已連接
 */
private boolean IsNoConnected( ) {
    ConnectivityManager cm =
            (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    //是否是wifi
    //boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
    return isConnected;
}

androidnet.png

這個https://developer.android.google.cn/reference/android/net/wifi/package-summary
網(wǎng)址是官網(wǎng)提供的,里面有對android.net的詳解

以上是我對于通信機制類型的簡單了解店乐,若有補充不到或理解有誤的地方艰躺,望賜教。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腺兴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子页响,更是在濱河造成了極大的恐慌段誊,老刑警劉巖闰蚕,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件连舍,死亡現(xiàn)場離奇詭異,居然都是意外死亡诗鸭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門强岸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來砾赔,“玉大人青灼,你說我怎么就攤上這事≡硬Γ” “怎么了悯衬?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長筋粗。 經(jīng)常有香客問我,道長娜亿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任买决,我火速辦了婚禮,結果婚禮上督赤,老公的妹妹穿的比我還像新娘。我一直安慰自己躲舌,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布枯冈。 她就那樣靜靜地躺著毅贮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪滩褥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天瑰煎,我揣著相機與錄音,去河邊找鬼酒甸。 笑死,一個胖子當著我的面吹牛沽瘦,可吹牛的內(nèi)容都是我干的革骨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼析恋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了筑凫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤巍实,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后橘霎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔫浆,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡姐叁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了原环。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡嘱吗,死狀恐怖滔驾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哆致,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布摊阀,位于F島的核電站,受9級特大地震影響臣咖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜夺蛇,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一酣胀、第九天 我趴在偏房一處隱蔽的房頂上張望愿卸。 院中可真熱鬧,春花似錦趴荸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至精堕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間歹篓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工背捌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留洞斯,地道東北人毡庆。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓烙如,卻偏偏與公主長得像,于是被迫代替她去往敵國和親亚铁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容