OKHttp的使用学习

2018-10-11  本文已影响0人  风二叽

       最近实际项目需要处理网络请求(一般是个app都会有的),于是接触了okhttp,目前也就刚刚会使用的程度,不过还是总结一下吧,个人学习的理解不喜勿喷哈。

       介绍就不多说了,它就是一个Android用来请求网络的第三方类库,开源的,是目前非常火的一款轻量级HTTP框架,由Square公司开发。

        好了废话少说,下面直接上使用说明,我使用的是OKHttp3,就以OKHttp3为例子,因为是提取出来的单独demo,可能有的变量类名没有完全修改对,可能有名字不对的低级错误欢迎指正。

导入方法

在gradle里导入就行了

dependencies里添加这一行完成导入

implementation 'com.squareup.okhttp3:okhttp:3.10.0'

GET方法

同步:

public void getOkHttpByExeCute(final String url){

        new Thread(new Runnable() {

            @Override

            public void run() {

                try {

                    //创建OkHttpClient实例

                    OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)

                            .writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS)

                            .build();

                    //创建Request

                    Request request = new Request.Builder().url(url).build();

                    Call call = okHttpClient.newCall(request);

                    //获取Response响应

                    final Response response = call.execute();

                    if (response.isSuccessful()) {

                        //UI操作在回到主线程执行

                        runOnUiThread(new Runnable() {

                            @Override

                            public void run() {

                                Toast.makeText(mContext,response.code() + response.message() + "",Toast.LENGTH_SHORT).show();

                            }

                        });

                    }

                }catch (Exception e) {

                    e.printStackTrace();

                }

            }

        });

    }

异步:

异步请求不需要开启新线程,只需要将回调在子线程中执行

public void getOkHttpByEnqueue(final String url,final Context context){

try {

//创建OkHttpClient实例

        OkHttpClient okHttpClient =new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)

.writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS)

.build();

        //创建Request

        Request request =new Request.Builder().url(url).build();

        Call call = okHttpClient.newCall(request);

        //回调

        call.enqueue(new Callback() {

@Override

            public void onFailure(Call call, IOException e) {

}

@Override

            public void onResponse(Call call, Response response)throws IOException {

if(response.isSuccessful()){

//本部分在子线程执行

//UI操作在回到主线程执行

                    final Response response2 = response;

                    runOnUiThread(new Runnable() {

@Override

                        public void run() {

Toast.makeText(context,response2.code() +response2.message() +"",Toast.LENGTH_SHORT).show();

                        }

});

                }

}

});

    }catch (Exception e) {

e.printStackTrace();

    }

}

POST方法

post键值对

//post异步请求发送键值对

public static void PostMapByEnqueue (String url, Map map, Callback callback,final Context context) {

FormBody.Builder builder =new FormBody.Builder();

    //遍历集合

    for (String key : map.keySet()) {

builder.add(key, map.get(key));

    }

//创建Request

    Request request =new Request.Builder().url(url).post(builder.build()).build();

    Call call =getOkHttpClient().newCall(request);

    call.enqueue(new Callback() {

@Override

        public void onFailure(Call call, IOException e) {

}

@Override

        public void onResponse(Call call, Response response)throws IOException {

if(response.isSuccessful()){

//子线程执行

//UI操作在回到主线程执行

                final Response response2 = response;

                runOnUiThread(new Runnable() {

@Override

                    public void run() {

Toast.makeText(context,response2.code() +response2.message() +"",Toast.LENGTH_SHORT).show();

                    }

});

            }

}

});

}

post JSON数据

//post异步请求发送json数据

public static void PostJson(String url, String string, Callback callback,final Context context) {

MediaType JSON = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式,

    RequestBody body = RequestBody.create(JSON, string);

    //创建Request

    Request request =new Request.Builder().url(url).post(body).build();

    Call call =getOkHttpClient().newCall(request);

    call.enqueue(new Callback() {

@Override

        public void onFailure(Call call, IOException e) {

}

@Override

        public void onResponse(Call call, Response response)throws IOException {

if(response.isSuccessful()){

//子线程执行

//UI操作在回到主线程执行

                final Response response2 = response;

               runOnUiThread(new Runnable() {

@Override

                    public void run() {

Toast.makeText(context,response2.code() +response2.message() +"",Toast.LENGTH_SHORT).show();

                    }

});

            }

}

});

}

okhttp实现下载功能

这一步在回调Callback中执行,原理理解同上,将onResponse中的子线程操作具体为下载就行了,下载功能原理是从Response中获取输入流对象实现文件下载

//Okhttp实现下载功能(json数据同理)

public static void download(String url, Map map, Callback callback, final Context context, final String pathStr) {

FormBody.Builder builder =new FormBody.Builder();

    //遍历集合

    for (String key : map.keySet()) {

builder.add(key, map.get(key));

    }

//创建Request

    Request request =new Request.Builder().url(url).post(builder.build()).build();

    Call call =getOkHttpClient().newCall(request);

    call.enqueue(new Callback() {

@Override

        public void onFailure(Call call, IOException e) {

}

@Override

        public void onResponse(Call call, Response response)throws IOException {

if(response.isSuccessful()){

//子线程执行

                try{

InputStream  is = response.body().byteStream();// 在Response中获取输入流对象

                    File dir =new File(pathStr);

                    if (!dir.exists()){

dir.mkdirs();

                    }

File file =new File(dir, pathStr);

                    FileOutputStream  fos =new FileOutputStream(file);

                    byte[] buf =new byte[1024*8];

                    int len =0;

                    while ((len = is.read(buf)) != -1){

fos.write(buf, 0, len);

                    }

fos.flush();//file下载完成

                }catch (Exception e) {

e.printStackTrace();

                }

}

}

});

}

进一步的封装

实际开发中,肯定一堆不同的地方要用到网络请求,我们不可能每一次都写一个post,get请求。为了进一步方便使用,可以考虑封装成一个工具类,我的思路如下:

首先定义获取的数据类,ResponseResult

public class ResponseResult {

private int status;

    private Stringmsg;

    private Objectdata;

    public ResponseResult(int status, String msg, Object data) {

this.status = status;

        this.msg = msg;

        this.data = data;

    }

public ResponseResult() {

}

public int getStatus() {

return status;

    }

public void setStatus(int status) {

this.status = status;

    }

public StringgetMsg() {

return msg;

    }

public void setMsg(String msg) {

this.msg = msg;

    }

public ObjectgetData() {

return data;

    }

public void setData(Object data) {

this.data = data;

    }

}

然后自定义回调类,ResponseCallBack

在这里为了更好转换返回的json数据,我们需要导入fastjson这个类库,解析json非常方便实用,当然这就又是另一部分内容了,这里就一笔带过不做详细介绍。

导入方法:

gradle里加入这一行完成导入

implementation"com.alibaba:fastjson:1.2.47"

好的回来继续写ResponseCallBack回调

public abstract class ResponseCallBack Callback {

private Handlerhandler = HttpRequestHandler.getInstance().getHandler();

    //主线程处理

    public abstract void onUi(HttpResult result);

    //主线程处理

    public abstract void onFailed(Call call, IOException e);

    @Override

    public void onFailure(final Call call, final IOException e) {

handler.post(new Runnable() {

@Override

            public void run() {

onFailed(call, e);

            }

});

    }

@Override

    public void onResponse(Call call, Response response)throws IOException {

final String result = response.body().string();

        handler.post(new Runnable() {

@Override

            public void run() {

onUi(JSON.parseObject(result, ResponseResult .class));

            }

});

    }

}

接下来写重点,okhttp的工具类:OkHttpUtil

public class OkHttpUtil {

private static OkHttpUtil okHttpUtil =null;

    private OkHttpUtil() {

}

public static OkHttpUtil getInstance() {

if (okHttpUtil ==null) {

//加同步安全

            synchronized (OkHttpUtil.class) {

if (okHttpUtil ==null) {

okHttpUtil =new OkHttpUtil();

                }

}

}

return okHttpUtil;

    }

private static OkHttpClient okHttpClient =null;

    public synchronized static OkHttpClient getOkHttpClient() {

if (okHttpClient ==null) {

okHttpClient =new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)

.writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS)

.build();

        }

return okHttpClient;

    }

private static Handler mHandler =null;

    public synchronized static Handler getHandler() {

if (mHandler ==null) {

mHandler =new Handler();

        }

return mHandler;

    }

public static void doPost(String url, Map<String, String> map, Callback callback) {

FormBody.Builder builder =new FormBody.Builder();

        //遍历集合

        for (String key : map.keySet()) {

builder.add(key, map.get(key));

        }

//创建Request

        Request request =new Request.Builder().url(url).post(builder.build()).build();

        Call call =getOkHttpClient().newCall(request);

        call.enqueue(callback);

    }

public static void doPost(String url, String string, Callback callback) {

MediaType JSON = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式,

        RequestBody body = RequestBody.create(JSON, string);

        //创建Request

        Request request =new Request.Builder().url(url).post(body).build();

        Call call =getOkHttpClient().newCall(request);

        call.enqueue(callback);

    }

}

最后是使用,这里只举post键值对的例子

private static int GET_OK = 0//获取数据成功,实际数值根据项目定

public void getHttpData(String key,String value,String url){

final Map map =new HashMap();

    map.put(key, value);

    OkHttpUtil.getInstance().doPost(url, map, new ResponseCallBack() {

@Override

        public void onUi(ResponseResult result) {

if (result.getStatus() ==GET_OK) {

//主线程执行操作

            }

}

@Override

        public void onFailed(Call call, IOException e) {

//主线程执行操作

        }

});

}

封装完成,收工~

上一篇下一篇

猜你喜欢

热点阅读