如今android网络方面的第三方库非常多,volley。Retrofit。OKHttp等,各有各自的特点,这边博客就来简介下怎样使用OKHttp。

梗概

OKHttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,通过连接池来减小响应延迟。还有透明的GZIP压缩。请求缓存等优势 OKHttp官网

配置环境

支持Android 2.3及其以上版本号。要求java JDK1.7以上

jar包引入

能够通过下载jar包直接导入project地址例如以下下载地址

或者通过构建的方式导入

MAVEN:

<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>2.4.0</version>
</dependency>

GRADLE

compile 'com.squareup.okhttp:okhttp:2.4.0'

使用方法

在向网络发起请求的时候,我们最常常使用的就是GET和POST。以下就来看看怎样使用

1. GET

在OKHttp,每次网络请求就是一个Request,我们在Request里填写我们须要的url,header等其它參数,再通过Request构造出Call,Call内部去请求參数,得到回复,并将结果告诉调用者。

package com.jackchan.test.okhttptest;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log; import com.squareup.okhttp.Cache;
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.IOException; public class TestActivity extends ActionBarActivity { private final static String TAG = "TestActivity"; private final OkHttpClient client = new OkHttpClient(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
new Thread(new Runnable() {
@Override
public void run() {
try {
execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
} public void execute() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
Response response = client.newCall(request).execute();
if(response.isSuccessful()){
System.out.println(response.code());
System.out.println(response.body().string());
}
}
}

我们通过Request.Builder传入url,然后直接execute运行得到Response,通过Response能够得到code,message等信息。

这个是通过同步的方式去操作网络请求,而android本身是不同意在UI线程做网络请求操作的,因此我们须要自己开启一个线程。

当然,OKHttp也支持异步线程而且有回调返回。有了上面同步的基础,异步仅仅要稍加修改即可

private void enqueue(){
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) { } @Override
public void onResponse(Response response) throws IOException {
//NOT UI Thread
if(response.isSuccessful()){
System.out.println(response.code());
System.out.println(response.body().string());
}
}
});
}

就是在同步的基础上讲execute改成enqueue,而且传入回调接口,但接口回调回来的代码是在非UI线程的,因此假设有更新UI的操作记得用Handler或者其它方式。

2、POST

说完GET该介绍些怎样使用POST,POST情况下我们一般须要传入參数,甚至一些header。传入參数或者header

比方传入header

Request request = new Request.Builder()

.url("https://api.github.com/repos/square/okhttp/issues")

.header("User-Agent", "OkHttp Headers.java")

.addHeader("Accept", "application/json; q=0.5")

.addHeader("Accept", "application/vnd.github.v3+json")

.build();


传入POST參数

RequestBody formBody = new FormEncodingBuilder()
.add("platform", "android")
.add("name", "bug")
.add("subject", "XXXXXXXXXXXXXXX")
.build(); Request request = new Request.Builder()
.url(url)
.post(body)
.build();

能够看出来,传入header或者post參数都是传到Request里面。因此最后的调用方式也和GET方式一样

Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}

这个代码是同步网络请求。异步就改成enqueue即可了。

请求缓存

在网络请求中。缓存技术是一项应用比較广泛的技术,须要对请求过的网络资源进行缓存。而okhttp也支持这一技术,也使用十分方便。前文涨常常出现的OkHttpclient这个时候就要派送用场了。

看以下代码

package com.jackchan.test.okhttptest;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log; import com.squareup.okhttp.Cache;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.Call;
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.IOException; public class TestActivity extends ActionBarActivity { private final static String TAG = "TestActivity"; private final OkHttpClient client = new OkHttpClient(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
File sdcache = getExternalCacheDir();
int cacheSize = 10 * 1024 * 1024; // 10 MiB
client.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
new Thread(new Runnable() {
@Override
public void run() {
try {
execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
} public void execute() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build(); Response response1 = client.newCall(request).execute();
if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1); String response1Body = response1.body().string();
System.out.println("Response 1 response: " + response1);
System.out.println("Response 1 cache response: " + response1.cacheResponse());
System.out.println("Response 1 network response: " + response1.networkResponse()); Response response2 = client.newCall(request).execute();
if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2); String response2Body = response2.body().string();
System.out.println("Response 2 response: " + response2);
System.out.println("Response 2 cache response: " + response2.cacheResponse());
System.out.println("Response 2 network response: " + response2.networkResponse()); System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body)); }
}

okhttpclient有点像Application的概念,统筹着整个okhttp的大功能。通过它设置缓存文件夹。我们运行上面的代码,得到的结果例如以下



response1 的结果在networkresponse。代表是从网络请求载入过来的,而response2的networkresponse 就为null,而cacheresponse有数据,由于我设置了缓存因此第二次请求时发现缓存里有就不再去走网络请求了。

但有时候即使在有缓存的情况下我们依旧须要去后台请求最新的资源(比方资源更新了)这个时候能够使用强制走网络来要求必须请求网络数据

 public void execute() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build(); Response response1 = client.newCall(request).execute();
if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1); String response1Body = response1.body().string();
System.out.println("Response 1 response: " + response1);
System.out.println("Response 1 cache response: " + response1.cacheResponse());
System.out.println("Response 1 network response: " + response1.networkResponse()); request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
Response response2 = client.newCall(request).execute();
if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2); String response2Body = response2.body().string();
System.out.println("Response 2 response: " + response2);
System.out.println("Response 2 cache response: " + response2.cacheResponse());
System.out.println("Response 2 network response: " + response2.networkResponse()); System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body)); }

上面的代码中

response2相应的request变成

request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();

我们看看运行结果



response2的cache response为null,network response依旧有数据。

相同的我们能够使用 FORCE_CACHE 强制仅仅要使用缓存的数据,但假设请求必须从网络获取才有数据。但又使用了FORCE_CACHE 策略就会返回504错误。代码例如以下,我们去okhttpclient的缓存,并设置request为FORCE_CACHE

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
File sdcache = getExternalCacheDir();
int cacheSize = 10 * 1024 * 1024; // 10 MiB
//client.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
new Thread(new Runnable() {
@Override
public void run() {
try {
execute();
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage().toString());
}
}
}).start();
} public void execute() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build(); Response response1 = client.newCall(request).execute();
if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1); String response1Body = response1.body().string();
System.out.println("Response 1 response: " + response1);
System.out.println("Response 1 cache response: " + response1.cacheResponse());
System.out.println("Response 1 network response: " + response1.networkResponse()); request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
Response response2 = client.newCall(request).execute();
if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2); String response2Body = response2.body().string();
System.out.println("Response 2 response: " + response2);
System.out.println("Response 2 cache response: " + response2.cacheResponse());
System.out.println("Response 2 network response: " + response2.networkResponse()); System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body)); }

取消操作

网络操作中,常常会使用到对请求的cancel操作,okhttp的也提供了这方面的接口,call的cancel操作。使用Call.cancel()能够马上停止掉一个正在运行的call。

假设一个线程正在写请求或者读响应。将会引发IOException,同一时候能够通过Request.Builder.tag(Object tag)给请求设置一个标签,并使用OkHttpClient.cancel(Object tag)来取消全部带有这个tag的call。

但假设该请求已经在做读写操作的时候,cancel是无法成功的,会抛出IOException异常。

public void canceltest() throws Exception {
Request request = new Request.Builder()
.url("http://httpbin.org/delay/2") // This URL is served with a 2 second delay.
.build(); final long startNanos = System.nanoTime();
final Call call = client.newCall(request); // Schedule a job to cancel the call in 1 second.
executor.schedule(new Runnable() {
@Override
public void run() {
System.out.printf("%.2f Canceling call.%n", (System.nanoTime() - startNanos) / 1e9f);
call.cancel();
System.out.printf("%.2f Canceled call.%n", (System.nanoTime() - startNanos) / 1e9f);
}
}, 1, TimeUnit.SECONDS); try {
System.out.printf("%.2f Executing call.%n", (System.nanoTime() - startNanos) / 1e9f);
Response response = call.execute();
System.out.printf("call is cancel:" + call.isCanceled() + "%n");
System.out.printf("%.2f Call was expected to fail, but completed: %s%n",
(System.nanoTime() - startNanos) / 1e9f, response);
} catch (IOException e) {
System.out.printf("%.2f Call failed as expected: %s%n",
(System.nanoTime() - startNanos) / 1e9f, e);
}
}

成功取消

取消失败

简单的对于OKHttp的使用就介绍到这里。下次将重点从源代码角度介绍整个OKHttp是怎样运转的。

上面部分的代码,我已经上传到github,各位看官有须要能够自行去下载源代码下载

OKHttp使用简单介绍的更多相关文章

  1. Https系列之一:https的简单介绍及SSL证书的生成

    Https系列会在下面几篇文章中分别作介绍: 一:https的简单介绍及SSL证书的生成二:https的SSL证书在服务器端的部署,基于tomcat,spring boot三:让服务器同时支持http ...

  2. [原创]关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  3. 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍

    一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析.它提供了大量高级的数据结构和对数据处理的方法. pandas 有两个主要的数据结构 ...

  4. 利用Python进行数据分析(4) NumPy基础: ndarray简单介绍

    一.NumPy 是什么 NumPy 是 Python 科学计算的基础包,它专为进行严格的数字处理而产生.在之前的随笔里已有更加详细的介绍,这里不再赘述. 利用 Python 进行数据分析(一)简单介绍 ...

  5. yii2的权限管理系统RBAC简单介绍

    这里有几个概念 权限: 指用户是否可以执行哪些操作,如:编辑.发布.查看回帖 角色 比如:VIP用户组, 高级会员组,中级会员组,初级会员组 VIP用户组:发帖.回帖.删帖.浏览权限 高级会员组:发帖 ...

  6. angular1.x的简单介绍(二)

    首先还是要强调一下DI,DI(Denpendency Injection)伸手获得,主要解决模块间的耦合关系.那么模块是又什么组成的呢?在我看来,模块的最小单位是类,多个类的组合就是模块.关于在根模块 ...

  7. Linux的简单介绍和常用命令的介绍

    Linux的简单介绍和常用命令的介绍 本说明以Ubuntu系统为例 Ubuntu系统的安装自行百度,或者参考http://www.cnblogs.com/CoderJYF/p/6091068.html ...

  8. iOS-iOS开发简单介绍

    概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的IOS程序.但是这里我想强调一下,前面的 ...

  9. iOS开发多线程篇—多线程简单介绍

    iOS开发多线程篇—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcod ...

随机推荐

  1. Android开发进度02

    1,今日:目标:创建第一个android项目,创建android虚拟机 2,昨天:完成eclipseandroid环境的搭建 3,收获:修改.xml文件,将出错地方解决 4,问题:版本问题

  2. 中山纪念中学培训杂题(难的都不在这里面qwq)

    来中山纪中半个月了,差不多就要结束了, 写一些之前考试能更正的题解吧,还有一些不是给人做的(比如IOI2018互测.. 备注:我不会的就没有放上来了,所有数学有关的基本上都死了. 所以这里的题目都是相 ...

  3. 关于Vue实例的生命周期(2)

     关于Vue实例的生命周期(2) 创建(create)->挂载(mount)->更新(update)->销毁(destory) 钩子函数触发事件 beforeCreate 在实例初始 ...

  4. Windows里正确安装Zookeeper以服务运行

    不多说,直接上干货! 为什么要在Win下来安装Zookeeper呢? 其实玩过大数据的人很清楚,在Linux下我更不说了.在win下,如Disconf .Dubbo等应用. 所以,它的应用是非常广的. ...

  5. SQL学习之使用order by 依照指定顺序排序或自己定义顺序排序

    我们通常须要依据客户需求对于查询出来的结果给客户提供自己定义的排序方式,那么我们通常sql须要实现方式都有哪些,參考很多其它资料总结例如以下(不完好的和错误望大家指出): 一.假设我们仅仅是对于在某个 ...

  6. 软工视频总结Part Three

    软件需求分析 任务 解决目标系统"做什么"问题 深入描写叙述软件的功能和性能 确定软件涉及到的约束和软件接口 定义软件的其它有效需求 特点 一致性.完整性.限时性.有效性.可验证性 ...

  7. [LeetCode] Longest Substring Without Repeating Characters 最长无重复字符的子串 C++实现java实现

    最长无重复字符的子串 Given a string, find the length of the longest substring without repeating characters. Ex ...

  8. POJ 3268 Dijkstra+priority_queue或SPFA

    思路:正向建边,一遍Dijkstra,反向建边,再一遍Dijkstra.ans加在一起输出最大值. (SPFA也行--) // by SiriusRen #include <queue> ...

  9. Codeforces 701E Connecting Universities 贪心

    链接 Codeforces 701E Connecting Universities 题意 n个点的树,给你2*K个点,分成K对,使得两两之间的距离和最大 思路 贪心,思路挺巧妙的.首先dfs一遍记录 ...

  10. transient修饰符的作用

    transient修饰符的作用: entity实体类: package com.baidu.entity; import com.fasterxml.jackson.annotation.JsonIg ...