1. 程式人生 > >Volley + OkHttp3 + Gson 組合的簡單網路請求封裝

Volley + OkHttp3 + Gson 組合的簡單網路請求封裝

1. Volley —— Google出品的android平臺輕量級網路庫

優點:擴充套件性強,請求佇列管理

基本介紹:http://blog.csdn.net/itachi85/article/details/51043704

github映象: https://github.com/mcxiaoke/android-volley

2. okhttp —— Square出品的java網路庫,android4.4以後已作為預設的HTTP連線實現

優點:支援SPDY,連線池,傳輸效率的各種優化

基本介紹:http://blog.csdn.net/itachi85/article/details/51142486

原始碼:https:
//github.com/square/okhttp 官方wiki:https://github.com/square/okhttp/wiki

3. Volley + OkHttp 結合

由於 Volley 和 OKHttp 各有優缺點,Volley 不支援 HTTPS,而 OKHttp 支援 HTTPS。Volley的擴充套件性又非常強,因此我們可以將 Volley 和 OKHTTP結合使用。

4. 新增依賴

// Volley
compile 'com.android.volley:volley:1.0.0'
// okhttp
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
// gson compile 'com.google.code.gson:gson:2.7'

5. AppConfig.java —— 全域性Application的配置

package com.qianxingzhe.mynetwork.app;

import android.app.Application;

import com.android.volley.RequestQueue;
import com.qianxingzhe.mynetwork.network.RequestManager;

/**
 * Created by lunyi.yly on 16/9/5.
 */

public
class AppConfig extends Application { private static AppConfig instance; @Override public void onCreate() { super.onCreate(); initAppConfig(); initNetWork(); } private void initNetWork() { if (RequestManager.getRequestQueueNoThrowable() == null) { RequestManager.init(this); } } private void initAppConfig() { if (instance == null) { instance = this; } } public static Application getApp() { return instance; } public static RequestQueue requestQueue() { return RequestManager.getRequestQueue(); } }

6. OkHttpStack

package com.qianxingzhe.mynetwork.network;

import com.android.volley.toolbox.HurlStack;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyStore;
import java.util.Arrays;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import okhttp3.OkUrlFactory;

/**
 * Created by lunyi.yly on 16/9/5.
 */

public class OkHttpStack extends HurlStack {
    private final OkUrlFactory okUrlFactory;

    public OkHttpStack() {
        this(new OkUrlFactory(getUnsafeOkHttpClient()));
    }

    public OkHttpStack(OkUrlFactory okUrlFactory) {
        if (okUrlFactory == null) {
            throw new NullPointerException("Client must not be null.");
        }
        this.okUrlFactory = okUrlFactory;
    }

    @Override
    protected HttpURLConnection createConnection(URL url) throws IOException {
        return okUrlFactory.open(url);
    }

    /**
     * 支援HTTPS。按下面的註釋進行
     *
     * @return
     */
    private static OkHttpClient getUnsafeOkHttpClient() {
        try {
            /**
             * 讀取公鑰證書內容
             * 首先要把你的https公鑰證書通過瀏覽器或者其他方法匯出,放進android資源目錄assets下。
             * 然後AppConfig這個類是繼承了Application的,android啟動的時候會先執行它,getApp是一個單例模式的實現
             */

            // 配置HTTPS時需要開啟下面的註釋

            // InputStream inputStream = AppConfig.getApp().getAssets().open("https.cer");
            //
            // CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            //
            // KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            // keyStore.load(null);
            //
            // int index = 0;
            // String certificateAlias = Integer.toString(index++);
            // keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(inputStream));

            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                    TrustManagerFactory.getDefaultAlgorithm());

            // 配置HTTPS時需要把下面的註釋開啟
            // trustManagerFactory.init(keyStore);

            // 配置HTTPS時需要把下面這句註釋掉
            trustManagerFactory.init((KeyStore) null);

            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
                throw new IllegalStateException("Unexpected default trust managers:"
                        + Arrays.toString(trustManagers));
            }
            X509TrustManager trustManager = (X509TrustManager) trustManagers[0];

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{trustManager}, null);
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient client = new OkHttpClient
                    .Builder()
                    .sslSocketFactory(sslSocketFactory, trustManager)
                    .build();
            return client;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

7. RequestManager

package com.qianxingzhe.mynetwork.network;

import android.content.Context;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

/**
 * Created by lunyi.yly on 16/9/5.
 */

public class RequestManager {

    private static RequestQueue mRequestQueue;

    private RequestManager() {
    }

    public static void init(Context context) {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(context, new OkHttpStack());
        }
    }

    /**
     * @return instance() of the queue
     * @throws IllegalStateException if init has not yet been called
     */
    public static RequestQueue getRequestQueue() {
        if (mRequestQueue != null) {
            return mRequestQueue;
        } else {
            throw new IllegalStateException("Not initialized");
        }
    }

    /**
     * @return instance() of the queue
     * @throws IllegalStateException if init has not yet been called
     */
    public static RequestQueue getRequestQueueNoThrowable() {
        return mRequestQueue;
    }

}

9. MyJsonObjectRequest

package com.qianxingzhe.mynetwork.network;

import android.util.Log;
import android.widget.Toast;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.qianxingzhe.mynetwork.BuildConfig;
import com.qianxingzhe.mynetwork.app.AppConfig;

import org.json.JSONObject;

import java.util.Map;

/**
 * Created by lunyi.yly on 16/9/6.
 */

public class MyJsonObjectRequest {

    /**
     * 請求型別。如: GET,POST等
     */
    private int method;

    /**
     * 請求的URL
     */
    private String url;

    /**
     * 請求的引數
     */
    private JSONObject requestParameter;

    /**
     * 請求成功的響應
     */
    private RequestNetWork requestNetWork;

    public MyJsonObjectRequest(int method, String url, Map<String, Object> parameter, RequestNetWork requestNetWork) {
        this.method = method;
        this.url = url;
        this.requestNetWork = requestNetWork;

        initRequestParameter(parameter);

        createJsonObjectRequest();
    }

    private void initRequestParameter(Map<String, Object> parameter) {
        if (parameter == null) {
            return;
        }

        this.requestParameter = new JSONObject(parameter);
    }

    private void createJsonObjectRequest() {
        JsonObjectRequest mJsonObjectRequest = new JsonObjectRequest(
                method,
                url,
                requestParameter,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        if (BuildConfig.DEBUG) {
                            Log.e("TAG", response.toString());
                        }

                        requestNetWork.onSuccess(response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        if (BuildConfig.DEBUG) {
                            Log.e("TAG", error.getMessage(), error);
                        }

                        Toast.makeText(AppConfig.getApp(), "網路請求失敗", Toast.LENGTH_SHORT).show();
                    }
                }
        );
        AppConfig.requestQueue().add(mJsonObjectRequest);
    }

    public interface RequestNetWork {
        void onSuccess(JSONObject response);
    }
}

10. 使用示例

MyJsonObjectRequest mRequest = new MyJsonObjectRequest(
                Request.Method.POST,
                "http://api.1-blog.com/biz/bizserver/article/list.do",
                null,
                new MyJsonObjectRequest.RequestNetWork() {
                    @Override
                    public void onSuccess(JSONObject response) {
                        Gson mGson = new Gson();
                        Article article = mGson.fromJson(response.toString(), Article.class);
                        Log.e("TAG", article.getDetail().get(0).getTitle());
                    }
                }
        );

11. AndroidManifest設定

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.qianxingzhe.mynetwork">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:name=".app.AppConfig"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>