OKHttp的使用学习

       最近实际项目需要处理网络请求(一般是个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) {

//主线程执行操作

        }

});

}

封装完成,收工~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139
  • 项目要求用json提交参数,以前在网上找的别的大神(忘了是谁)封装的NetUtils工具不适应了,在网上也没找到适...
    微暖_440e阅读 1,127评论 0 0
  • 自己备忘,随便写 android网络框架源码解析及对比 android常用网络框架对比 Volley: 特点 基于...
    幻海流心阅读 1,453评论 0 4
  • 一颗老树 一支中性笔 一屋子的书 一处陌生的地方 一群不相识的人 一心一意 一人一生
    丿锋芒阅读 116评论 0 0
  • 蓝裳怎比赤衣襟,背景争如南海深。 偶现神情惊四座,孰知影响胜千金。 可怜无力施援手,始信无情非本心。 阮籍善为青白...
    随意郝学敏阅读 204评论 0 2