美文网首页
Okhttp的简单使用(kt&java)

Okhttp的简单使用(kt&java)

作者: Wocus | 来源:发表于2017-08-15 11:19 被阅读19次

    这是一个网络请求的框架,接下来介绍如何使用,不说原理,直说怎么使用

    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对象, 因为发送请求的时候要用到此参数
         */
        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)发送网络请求
         *
         * @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方法是在主线程执行的,可以进行更新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, "服务器发生错误").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 下载监听
         */
        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();
                }
            });
    

    简单使用就到这里。

    相关文章

      网友评论

          本文标题:Okhttp的简单使用(kt&java)

          本文链接:https://www.haomeiwen.com/subject/twumrxtx.html