Okhttp入门使用一
1.okhttp介绍:
目前最新android 网络请求底部封装就是okhttp,github链接 :https://github.com/square/okhttp
2.比较常见的http请求是 get 、post、delete、put;
一个比较好的http超文本协议简单知识:
http://www.jianshu.com/p/e544b7a76dac
3.从最开始的发送get请求
对了,记得添加Internet权限;
我们看一下原文:
Download a file, print its headers, and print its response body as a string.The string() method on response body is convenient and efficient for small documents. But if the response body is large (greater than 1 MiB), avoid string() because it will load the entire document into memory. In that case, prefer to process the body as a stream.
下载一个文件,打印请求头信息,利用string()并打印响应体;
这个string()方法响应体是非常方便高效低于体积小的文件,而如果响应体(超过1MB = 1024*1024)避免使用string();
因为string()方法会加载实体文件到内存,通常这种情况下,选择将请求返回的数据用stream传输。
发送 Sync GET 请求:
run1.java
注意在Activity调用的时候,需要在子线程当中调用:
onCreate()当中调用
效果如下:
效果.png需要注意的几个地方:
content_type: 标识请求、响应 格式 ,通常为text或者json;这里是 text/plain;
last_modified:上次修改的地方,通常,我们需要经常请求网络,在请求资源是判断资源是否有修改;
connected :连接状态;
ETag:值包含几种,last_modified、if_none_match、if_modified_since(新浪貌似使用Etag是这种);
Accept-ranges:通常单位是byte,还要一个配套: max-length 表示存货时间(单位s);
请求结果是 android机器人和OKHTTP拼接字。
异步 Get
Download a file on a worker thread, and get called back when the response is readable. The callback is made after the response headers are ready. Reading the response body may still block. OkHttp doesn't currently offer asynchronous APIs to receive a response body in parts.
下载一个文档在 工作线程(一般认为在子线程),获取回调当响应可读,这个是在响应头已经准备好,读取响应体依旧在{}当中,okhttp当接受响应体不通常提供异步Api;
调用的方法不是之前的 execute()方法,而是enqueue();这里我的理解是 enqueue将请求加入请求队列;当队列当中有新的请求,闲置时去执行;当调用enqueue()方法时,在其回调方法中做处理;
run2.pngGet方式,添加请求头
对于想要额外添加的请求头来说,Request也是可以的
Typically HTTP headers work like aMap: each field has one value or none. But some headers permit multiple values, like Guava'sMultimap. For example, it's legal and common for an HTTP response to supply multipleVaryheaders. OkHttp's APIs attempt to make both cases comfortable.
When writing request headers, useheader(name, value)to set the only occurrence ofnametovalue. If there are existing values, they will be removed before the new value is added. UseaddHeader(name, value)to add a header without removing the headers already present.
When reading response a header, useheader(name)to return thelastoccurrence of the named value. Usually this is also the only occurrence! If no value is present,header(name)will return null. To read all of a field's values as a list, useheaders(name).
特别的Http header工作像一个map集合,每一个常量key对应着value值(或者是null);但一些header允许多值,像Guava Multimap(sorry,我没接触过).举个栗子,这是合法且比较常见提供辅助、多变的header对于Http响应,okhttp Apis尝试让所有例子都适合;
当写请求头时,使用 header(name,value)去设置key-value;如果存在值,那么在新添加的值将会覆盖之前的,使用addHeader(name,value)去添加header不会覆盖之前已经存在的;
当正在读响应头,使用header(name)将将会返回最新的value值,通常当且仅当发送;如果没有值,那么header将会return null,得到name的列表使用headers(name);
run3.png
Post请求 、带参String
Use an HTTP POST to send a request body to a service. This example posts a markdown document to a web service that renders markdown as HTML. Because the entire request body is in memory simultaneously, avoid posting large (greater than 1 MiB) documents using this API.
使用一个Http post发送一个请求体到后台,这个post一个markdown文档到后台使markdown当中html(注:markdown是一个类似于notepad软件),因为实体请求体同时在内存,同时注意避免提交超过1MB文件使用这个Api;
postString.java
desc: 请求体当中, Request默认是Get方法发送请求,如果是Post则需要在代码中指出,且需要RequBody(content_type,content);
Post,Stream-字节流
Here we POST a request body as a stream. The content of this request body is being generated as it's being written. This example streams directly into the Okio buffered sink. Your programs may prefer anOutputStream, which you can get from Buffered Sink.outputStream().
我们将 尝试Post 请求体 当中Stream,请求体的内容写入的时候生成,下面的栗子中Stream流到 okio缓存区,我们的通常在代码中更偏爱使用OutputStream类,你也可以从缓存区得到该类 ;不同的是在构建RequestBody方式不同,这次将直接创建RequeBody;
postStreamPost 文件
It's easy to use a file as a request body.
这很容易使用一个文件当中requestBody
目前我这边File是虚构的,所以程序会报错;如果是sdcard,记得读写权限;
postFilePost 表单提交
Use FormBody.Builder to build a request body that works like an HTMLtag. Names and values will be encoded using an HTML-compatible form URL encoding.
使用FormBody.Builder构建请求体就像Html tag,name-vale将会使用html编译编码
postFormGet请求, 使用Gjson解析数据
在正式显示代码之前安利下 android studio插件,GsonFormat,可以生成实体bean;怎么使用呢?在Settings搜索,点击安装,重新打开as,就可以开始使用,使用也很简单;
安装gsonFormatGson is a handy API for converting between JSON and Java objects. Here we're using it to decode a JSON response from a GitHub API.
Note that ResponseBody.charStream() uses theContent-Type response header to select which charset to use when decoding the response body. It defaults toUTF-8if no charset is specified.
Gson是一个很方便Api为转换Json到Java对象,这里我们使用它去解码Json 从一个github api;请注意 ResponseBody.charStream()使用 Content-type(headers的一种)去选择格式,但解码返回的数据,它默认使用utf-8如果没有指定解码格式;
post2Json缓存 Response
To cache responses, you'll need a cache directory that you can read and write to, and a limit on the cache's size. The cache directory should be private, and untrusted applications should not be able to read its contents!
It is an error to have multiple caches accessing the same cache directory simultaneously. Most applications should cal lnew OkHttpClient() exactly once, configure it with their cache, and use that same instance everywhere. Otherwise the two cache instances will stomp on each other, corrupt the response cache, and possibly crash your program.
Response caching uses HTTP headers for all configuration. You can add request headers likeCache-Control: max-stale=3600and OkHttp's cache will honor them. Your webserver configures how long responses are cached with its own response headers, likeCache-Control: max-age=9600. There are cache headers to force a cached response, force a network response, or force the network response to be validated with a conditional GET.
为了缓存返回的数据,我们需要缓存目录包含可读可写,并指定缓存大小,缓存目录应该私有,并且不信任的App没权限访问;
如果同时多个缓存访问 同一个缓存目录将会出错,大多数应用应该调用new OkHttpClient()一次;配置缓存,使用同一个实例对象;否则两个缓存实例对象将会妨碍对方,中断缓存,并且程序有可能crash(崩溃掉);
所有配置为了缓存数据使用Https headers,我们可以添加请求头 比如 cache-control : max-stale = 3600,并okHttp's缓存将遵守(max-stale :单位秒,说明缓存数据 可保持在1h之内有效);我们的服务器后台设置多久缓存Response 通过自己的响应头部信息,如理cache-control max-age = 9600(同上)。那将缓存头部强制缓存数据,强制 网络,或者强制网络回馈通过GET方法有效;
缓存Response response1 response2To prevent a response from using the cache, useTo prevent it from using the network, use CacheConrtol.FORCE_CACHE. Be warned: if you use CacheControl.FORCE_CACHE and the response requires the network, OkHttp will return a 504 Unsatisfiable Request response.
为了阻止数据从缓存读取,使用ForceNecWork即可,注意,如果使用强制使用缓存并且Response要求网络,okhttp将返回504状态码;
取消请求 (Canceling a call)
Use Call.cancel() to stop an ongoing call immediately. If a thread is currently writing a request or reading a response, it will receive anIOException. Use this to conserve the network when a call is no longer necessary; for example when your user navigates away from an application. Both synchronous and asynchronous calls can be canceled.
使用Call.cancel()去停止一个不间断请求,如果一个线程写一个请求或者读取返回数据,它将接受到一个IOEception,使用它保存网络当请求不在需要,举个栗子,当我们的使用者导航到一个App,所以同步和异步请求会被取消;
取消请求设置超时TimeOuts
Use timeouts to fail a call when its peer is unreachable. Network partitions can be due to client connectivity problems, server availability problems, or anything between. OkHttp supports connect,read, and write timeouts.
使用超时来应对失败的请求当它无法到达,网络问题可能是几部分 客户端连接问题,服务器不在有效期,或者介于两者之间。okhttp支持连接,读取和写入超时;
超时请求配置 per-call configuration
All the HTTP client configuration lives in OkHttpClient including proxy settings, timeouts, and caches. When you need to change the configuration of a single call, callOkHttpClient.newBuilder(). This returns a builder that shares the same connection pool, dispatcher, and configuration with the original client. In the example below, we make one request with a 500 ms timeout and another with a 3000 ms timeout.
所有的http客户端配置在okhttpClient包含代理设置,超时和缓存,当我们需要改变配置来进行单次请求,调用okHttpClient.newBuilder(),这返回一个建造者,分享相同的连接池,分发器和配置和初始的client,在下面的栗子中,我们使一个请求设置500ms超时,而另外一个设置3000ms超时;
改变配置信息处理授权(Handing authentication)
OkHttp can automatically retry unauthenticated requests. When a response is401 Not Authorized, anAuthenticatoris asked to supply credentials. Implementations should build a new request that includes the missing credentials. If no credentials are available, return null to skip the retry.
UseResponse.challenges()to get the schemes and realms of any authentication challenges. When fulfilling aBasicchallenge, useCredentials.basic(username, password)to encode the request header.
okhttp可以自动充实不需要证明的请求,当响应码是401代表没有授权,一个证明者需要提供资质,实现应该build一个新的请求且包含失去的证明。如果证书是存在,return null 去跳过重复请求。
使用Response.challenges() 去获取模式和实时任何证书变更。当令人满意一个基本的改变,使用Credentials.basic(username,password)去解码请求头;
授权操作