Okhttp的簡單使用(kt&java)

這是一個網絡請求的框架,接下來介紹如何使用,不說原理,直說怎么使用

1.依賴注入

 compile 'com.squareup.okhttp:okhttp:2.4.0'
 compile 'com.google.code.gson:gson:2.6.2'

2.提供一個HttpUtils的封裝類

package com.wocus.myapplication.util;

import android.os.Handler;
import android.os.Looper;

import com.squareup.okhttp.Callback;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Created on 2017/8/15.
 * Author:crs
 * Description:網絡請求工具類的封裝
 */
public class HttpUtils {
 
    private OkHttpClient client;
    private Handler mHandler;
 
    public HttpUtils() {
        client = new OkHttpClient();
        //設置連接超時時間,在網絡正常的時候有效
        client.setConnectTimeout(30*1000, TimeUnit.SECONDS);
        //設置讀取數據的超時時間
        client.setReadTimeout(30*1000, TimeUnit.SECONDS);
        //設置寫入數據的超時時間
        client.setWriteTimeout(30*1000, TimeUnit.SECONDS);
 
        //Looper.getMainLooper()  獲取主線程的消息隊列
        mHandler = new Handler(Looper.getMainLooper());
    }



 
    public void get(String url, BaseCallBack baseCallBack) {
        Request request = buildRequest(url, null, HttpMethodType.GET);
        sendRequest(request, baseCallBack);
    }
 
 
    public void post(String url, HashMap<String,String> params, BaseCallBack baseCallBack) {
        Request request = buildRequest(url, params, HttpMethodType.POST);
        sendRequest(request, baseCallBack);
 
    }
 
    /**
     * 1)獲取Request對象
     *
     * @param url
     * @param params
     * @param httpMethodType 請求方式不同,Request對象中的內容不一樣
     * @return Request 必須要返回Request對象, 因為發(fā)送請求的時候要用到此參數
     */
    private Request buildRequest(String url, HashMap<String, String> params, HttpMethodType httpMethodType) {
        //獲取輔助類對象
        Request.Builder builder = new Request.Builder();
        builder.url(url);
 
        //如果是get請求
        if (httpMethodType == HttpMethodType.GET) {
            builder.get();
        } else {
            RequestBody body = buildFormData(params);
            builder.post(body);
        }
 
        //返回請求對象
        return builder.build();
    }
 
    /**
     * 2)發(fā)送網絡請求
     *
     * @param request
     * @param baseCallBack
     */
    private void sendRequest(Request request, final BaseCallBack baseCallBack) {
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                callBackFail(baseCallBack,request, e);
            }
 
            @Override
            public void onResponse(Response response) throws IOException {
                if (response.isSuccessful()) {
                    String json = response.body().string();
                    //此時請求結果在子線程里面,如何把結果回調到主線程里?
                    callBackSuccess(baseCallBack,response, json);
                } else {
                    callBackError(baseCallBack,response, response.code());
                }
            }
        });
    }
 
 
    /**
     * 主要用于構建請求參數
     *
     * @param param
     * @return ResponseBody
     */
    private RequestBody buildFormData(HashMap<String,String> param) {
 
        FormEncodingBuilder builder = new FormEncodingBuilder();
        //遍歷HashMap集合
        if (param != null && !param.isEmpty()) {
            Set<Map.Entry<String, String>> entries = param.entrySet();
            for (Map.Entry<String, String> entity : entries) {
                String key = entity.getKey();
                String value = entity.getValue();
                builder.add(key, value);
            }
        }
        return builder.build();
    }
 
    //請求類型定義
    private enum HttpMethodType {
        GET,
        POST
    }
 
    //定義回調接口
    public interface BaseCallBack {
        void onSuccess(Response response, String json);
 
        void onFail(Request request, IOException e);
 
        void onError(Response response, int code);
    }
 
 
 
    //主要用于子線程和主線程進行通訊
   private void callBackSuccess(final BaseCallBack baseCallBack, final Response response, final String json){
       mHandler.post(new Runnable() {
           @Override
           public void run() {
               baseCallBack.onSuccess(response,json);
           }
       });
   }
 
 
    private void callBackError(final BaseCallBack baseCallBack, final Response response, final int code){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                baseCallBack.onError(response,code);
            }
        });
    }
 
    private void callBackFail(final BaseCallBack baseCallBack, final Request request, final IOException e){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                //相當于此run方法是在主線程執(zhí)行的,可以進行更新UI的操作
                baseCallBack.onFail(request,e);
            }
        });
    }

}

3.再提供一個gson的封裝類

    package com.wocus.myapplication.util;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


public class GsonUtil {
    private static Gson gson = null;

    static {
        if (gson == null) {
            gson = new Gson();
        }
    }

    private GsonUtil() {
    }

    /**
     * 轉成json
     *
     * @param object
     * @return
     */
    public static String GsonString(Object object) {
        String gsonString = null;
        if (gson != null) {
            gsonString = gson.toJson(object);
        }
        return gsonString;
    }

    /**
     * 轉成bean
     *
     * @param gsonString
     * @param cls
     * @return
     */
    public static <T> T GsonToBean(String gsonString, Class<T> cls) {
        T t = null;
        if (gson != null) {
            t = gson.fromJson(gsonString, cls);
        }
        return t;
    }

    /**
     * 轉成list
     * 泛型在編譯期類型被擦除導致報錯
     *
     * @param gsonString
     * @param cls
     * @return
     */
    public static <T> List<T> GsonToList(String gsonString, Class<T> cls) {
        List<T> list = null;
        if (gson != null) {
            list = gson.fromJson(gsonString, new TypeToken<List<T>>() {
            }.getType());
        }
        return list;
    }

    /**
     * 轉成list
     * 解決泛型問題
     *
     * @param json
     * @param cls
     * @param <T>
     * @return
     */
    public <T> List<T> jsonToList(String json, Class<T> cls) {
        Gson gson = new Gson();
        List<T> list = new ArrayList<T>();
        JsonArray array = new JsonParser().parse(json).getAsJsonArray();
        for (final JsonElement elem : array) {
            list.add(gson.fromJson(elem, cls));
        }
        return list;
    }


    /**
     * 轉成list中有map的
     *
     * @param gsonString
     * @return
     */
    public static <T> List<Map<String, T>> GsonToListMaps(String gsonString) {
        List<Map<String, T>> list = null;
        if (gson != null) {
            list = gson.fromJson(gsonString,
                    new TypeToken<List<Map<String, T>>>() {
                    }.getType());
        }
        return list;
    }

    /**
     * 轉成map的
     *
     * @param gsonString
     * @return
     */
    public static <T> Map<String, T> GsonToMaps(String gsonString) {
        Map<String, T> map = null;
        if (gson != null) {
            map = gson.fromJson(gsonString, new TypeToken<Map<String, T>>() {
            }.getType());
        }
        return map;
    }

}
    

4.請求網絡使用

package com.wocus.myapplication.activity

import android.app.ProgressDialog
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.View
import com.daimajia.androidanimations.library.Techniques
import com.daimajia.androidanimations.library.YoYo
import com.squareup.okhttp.Request
import com.squareup.okhttp.Response
import com.wocus.myapplication.R
import com.wocus.myapplication.util.GsonUtil
import com.wocus.myapplication.util.HttpUtils
import com.wocus.myapplication.util.SUtils
import es.dmoral.toasty.Toasty
import kotlinx.android.synthetic.main.activity_main.*
import java.io.IOException


/**
 * 登錄界面
 */
class MainActivity : AppCompatActivity(), View.OnClickListener ,HttpUtils.BaseCallBack{

    var load_dialog: ProgressDialog?=null

    override fun onSuccess(response: Response?, json: String?) {
        Log.d("TAG","請求成功"+json)
        load_dialog!!.dismiss()
        var modelbean: MutableMap<String, String>? =GsonUtil.GsonToMaps<String>(json)
        if (modelbean!!["code"].toString() == "1") {
            startActivity(Intent(this, IndexActivity::class.java))
            Toasty.success(this, "登錄成功").show()
        }else{
            Toasty.error(this,modelbean.get("msg").toString())
        }
    }
    override fun onFail(request: Request?, e: IOException?) {
        load_dialog!!.dismiss()
        Toasty.error(this,"網絡連接超時").show()
    }

    override fun onError(response: Response?, code: Int) {
        load_dialog!!.dismiss()
        Toasty.error(this, "服務器發(fā)生錯誤").show()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        btn_login_login.setOnClickListener(this)
        load_dialog=SUtils().initDialog(this)
    }

    override fun onClick(v: View?) {
        when(v?.id){
            R.id.btn_login_login->
                if(edt_login_account.text.trim().length<=0){
                    Toasty.info(this,"請輸入賬號").show()
                    YoYo.with(Techniques.Tada).duration(500).playOn(layout_login_account)
                    return
                }else if(edt_login_password.text.trim().length<=0){
                    Toasty.info(this,"請輸入密碼").show()
                    YoYo.with(Techniques.Tada).duration(500).playOn(layout_login_pwd)
                    return
                }else{
                     load_dialog!!.show()
                    startActivity(Intent(this, IndexActivity::class.java))
                    var map:HashMap<String,String>?= HashMap()
                    map!!.put("account",edt_login_account.text.toString())
                    map.put("password",edt_login_account.text.toString())
                   HttpUtils().post("http://192.168.0.117:8080/Shopnert/login.do",map,this)
                }
        }
    }
}

請求網絡就到這里,接下來使用okhttp實現下載,提供一個okhttp下載封裝工具類

package com.wocus.myapplication.util;

import android.os.Environment;
import android.support.annotation.NonNull;

import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class DownloadUtil {

    private static DownloadUtil downloadUtil;
    private final OkHttpClient okHttpClient;

    public static DownloadUtil get() {
        if (downloadUtil == null) {
            downloadUtil = new DownloadUtil();
        }
        return downloadUtil;
    }

    private DownloadUtil() {
        okHttpClient = new OkHttpClient();
    }

    /**
     * @param url 下載連接
     * @param saveDir 儲存下載文件的SDCard目錄
     * @param listener 下載監(jiān)聽
     */
    public void download(final String url, final String saveDir, final OnDownloadListener listener) {
        Request request = new Request.Builder().url(url).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                listener.onDownloadFailed();
            }

            @Override
            public void onResponse(Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                // 儲存下載文件的目錄
                String savePath = isExistDir(saveDir);
                try {
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    File file = new File(savePath, getNameFromUrl(url));
                    fos = new FileOutputStream(file);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total * 100);
                        // 下載中
                        listener.onDownloading(progress);
                    }
                    fos.flush();
                    // 下載完成
                    listener.onDownloadSuccess();
                } catch (Exception e) {
                    listener.onDownloadFailed();
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException e) {
                    }
                }
            }
        });
    }

    /**
     * @param saveDir
     * @return
     * @throws IOException
     * 判斷下載目錄是否存在
     */
    private String isExistDir(String saveDir) throws IOException {
        // 下載位置
        File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);
        if (!downloadFile.mkdirs()) {
            downloadFile.createNewFile();
        }
        String savePath = downloadFile.getAbsolutePath();
        return savePath;
    }

    /**
     * @param url
     * @return
     * 從下載連接中解析出文件名
     */
    @NonNull
    private String getNameFromUrl(String url) {
        return url.substring(url.lastIndexOf("/") + 1);
    }

    public interface OnDownloadListener {
        /**
         * 下載成功
         */
        void onDownloadSuccess();

        /**
         * @param progress
         * 下載進度
         */
        void onDownloading(int progress);

        /**
         * 下載失敗
         */
        void onDownloadFailed();
    }
}

下載封裝類的使用

DownloadUtil.get().download("http://192.168.0.117:8080/Shopnert/ShipCargo.apk", "download", new DownloadUtil.OnDownloadListener() {
            @Override
            public void onDownloadSuccess() {
                Toasty.error(getBaseContext(), "下載成功").show();
            }

            @Override
            public void onDownloading(int progress) {
                Toasty.error(getBaseContext(), "進度為" + progress).show();
            }

            @Override
            public void onDownloadFailed() {
                Toasty.error(getBaseContext(), "下載失敗").show();
            }
        });

簡單使用就到這里。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容