天天看點

安卓網絡程式設計-OkHttp-網絡通信庫

在使用之前,我們需要先在項目中添加OkHttp庫的依賴。編輯app/build.gradle檔案,在 dependencies閉包添加如下内容:

dependencies {

    compile fileTree(dir: 'libs', include: ['*.jar'])

    testCompile 'junit:junit:4.12'

    compile 'com.android.support:appcompat-v7:23.4.0'

    compile 'com.squareup.okhttp3:okhttp:3.4.1'

}

添加上述依賴會自動下載下傳兩個庫,一個是OkHttp庫,一個是Okio庫,後者是前者的通信機礎,其中3.4.1是版本号。

 OkHttp基本用法,首先建立OkHttpClient的執行個體,如下所示:

    OkHttpClient client = new OkHttpClient();

    接下來如果想要發起一條HTTP請求,就需要建立一個Request對象:

    Request request = new Request.Builser().build();

    當然上述代碼隻是建立一個空的Request對象,并沒有實際作用,我們可以在最終的build()方法之前連綴很多其他的方法來豐富這個Request對象。比如可以通過url()方法來設定目标的網絡位址,如下所示:

    Request request = new Request.Builser()

    .url("http://www.baidu.com")

    build();

  之後調用OkHttpClient的newCall()方法來建立一個Call對象,并調用它的execute()方法來發送請求并擷取伺服器傳回的資料,寫法如下:

    Response response = client.newCall(request).execute();

  其中Response對象就是伺服器傳回的資料了,我們可以使用如下寫法開得到傳回的具體内容:

    String responseData = response.body().string();

  如果是發起一條POST請求會比GET請求稍微複雜一點,我們需要先建構出一個RequestBody對象來存放待送出的參數,如下所示:

    ReqestBody requestBody = new FormBody.Builder()

     .add("username","admin")

     .add("password","123456")

     .build();

  然後在Request.Builder中調用一下post()方法,并将RequestBody對象傳入:

   Request request = new Request.Builder()

     .url("http://www.baidu.com")

     .post(requestBody)

     .build();

   接下來就跟GET請求一樣了,調用execute()方法來發送請求并擷取伺服器傳回的資料即可。

   現在對HTTPURLConnection項目改用Okhttp的方式實作一遍

   main.xml

   <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical">

    <Button

        android:id="@+id/send_request"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Send Request"/>

    <ScrollView

        android:layout_width="match_parent"

        android:layout_height="match_parent">

    <TextView

        android:id="@+id/response_text"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" />

    </ScrollView>

</LinearLayout>

MainActivity.java

package com.example.administrator.httpurlconnection;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;

import java.io.BufferedReader;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.HttpURLConnection;

import java.net.URL;

import okhttp3.Call;

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.Response;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    TextView responseText;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        Button sendRequest = (Button) findViewById(R.id.send_request);

        responseText = (TextView) findViewById(R.id.response_text);

        sendRequest.setOnClickListener(this);

    }

    @Override

    public void onClick(View v) {

        if (v.getId() == R.id.send_request){

           // sendRequestWithHttpURLConnection();//調用 sendRequestWithHttpURLConnection()方法

            sendRequestWithOkHttp();

        }

    }

    private void sendRequestWithOkHttp() {

        new Thread(new Runnable() {//開啟個子線程

            @Override

            public void run() {

                try {

                    OkHttpClient client = new OkHttpClient();//建立OkHttp執行個體

                    Request request = new Request.Builder()//發起一條HTTP請求

                            .url("http://www.baidu.com")

                            .build();

//調用OkHttpClient的newCall()方法來建立一個Call對象,并調用它的execute()方法來發送請求并擷取伺服器傳回的資料

                    Response response = client.newCall(request).execute();

                    String responseData = response.body().string();

                    showResponse(responseData);//将伺服器的資料傳回到界面上

                }catch (Exception e){

                    e.printStackTrace();

                }

            }

        }).start();

    }

    private void sendRequestWithHttpURLConnection() {

        //開啟線程來發起網絡請求

        new Thread(new Runnable() {

            @Override

            public void run() {

                HttpURLConnection connection = null;

                BufferedReader reader = null;

                try{

                    URL url = new URL("https://www.baidu.com");//請求目标位址百度首頁

                    connection = (HttpURLConnection) url.openConnection();

                  //  connection.setRequestMethod("GET");

                    connection.setRequestMethod("POST");

                    DataOutputStream out = new DataOutputStream(connection.getOutputStream());

                    out.writeBytes("username=admin&password=123456");

                    connection.setConnectTimeout(8000);

                    connection.setReadTimeout(8000);

                    InputStream in = connection.getInputStream();

                    //下面對擷取到的輸入流進行讀取

                    reader = new BufferedReader(new InputStreamReader(in));

                    StringBuilder response = new StringBuilder();

                    String line;

                    while ((line = reader.readLine()) != null){

                        response.append(line);

                    }

                    showResponse(response.toString());

                }catch (Exception e){

                        e.printStackTrace();

                }finally {

                    if (reader != null){

                        try{

                            reader.close();

                        }catch (IOException e){

                            e.printStackTrace();

                        }

                    }

                    if (connection != null){

                        connection.disconnect();

                    }

                }

            }

        }).start();

    }

    private void showResponse(final String response) {

        runOnUiThread(new Runnable() {//你明磊參數進行操作,将傳回的資料進行讀取,并将結果傳入到了showResponse()方法中,将線程切換到主線程,然後将更新UI元素

            @Override

            public void run() {

                //在這裡進行UI操作

                responseText.setText(response);

            }

        });

    }

}