开源框架OKHttp的使用01-基础
来源:互联网 发布:阿里云服务器能翻墙么 编辑:程序博客网 时间:2024/06/01 09:25
一、简介
Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient
尽管Google在大部分安卓版本中推荐使用HttpURLConnection,但是这个类相比HttpClient实在是太难用,太弱爆了。OkHttp是一个相对成熟的解决方案,据说Android4.4的源码中可以看到HttpURLConnection已经替换成OkHttp实现了。所以我们更有理由相信OkHttp的强大。使用时要求jdk及1.7以上。
下载:https://github.com/square/okhttp
okhttp内部依赖okio,需要同时导入okio
https://search.maven.org/remote_content?g=com.squareup.okio&a=okio&v=LATEST
也可以使用构建的方式进行导入,会自动从框架库中下载
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请求
基于Http的文件上传
文件下载
加载图片
支持请求回调,直接返回对象、对象集合
支持session的保持
三、使用示例
okhttp网络请求分为同步请求和异步请求。
异步请求执行方法:
Call call = client.newCall(request);call.enqueue(new Callback(){...});
异步请求数据示例
private void okhttpA(String url) { // 1.需要一个OkHttpClient对象,最好一个app中只实例化一个该对象。 OkHttpClient client = new OkHttpClient(); // 2.新建一个请求 Request request = new Request.Builder().url(url).build(); // 3.执行请求,获得响应的结果 Call call = client.newCall(request); // 4.加入调度 final TextView tv = new TextView(this); call.enqueue(new Callback() { @Override public void onResponse(Response response) throws IOException { if (response.isSuccessful()) { final String str = response.body().string(); runOnUiThread( new Runnable() { public void run() { tv.setText(str); } }); } else { throw new IOException("Unexpected code " + response); } } @Override public void onFailure(Request arg0, IOException arg1) { } }); }
同步请求执行方法:
Call call = client.newCall(request);call.execute();
同步请求数据示例
private String okhttpB(String url) throws IOException { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(url).build(); Call call = client.newCall(request); Response response = call.execute(); if (response.isSuccessful()) { return response.body().string(); } else { throw new IOException("Unexpected code " + response); } }
下面主要示例都以异步为主:
1.一般的get请求
private void okhttpGet(String url){ //1.需要一个OkHttpClient对象,最好一个app中只实例化一个该对象。 OkHttpClient client = new OkHttpClient(); //2.新建一个请求 Request request = new Request.Builder().url(url).build(); //3.执行请求,获得响应的结果 Call call = client.newCall(request); //4.加入调度 call.enqueue(new Callback() { @Override public void onResponse(Response arg0) throws IOException { // TODO Auto-generated method stub } @Override public void onFailure(Request arg0, IOException arg1) { // TODO Auto-generated method stub } }); }
2.post提交,提交各种类型数据
这种提交形式和服务器有关,有些服务器不支持这种数据处理。
①提交json类型字符串
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");private void okhttpPostWithJson(String url) { String json =""; //一个Json字符串 // 1.创建OkHttpClient OkHttpClient client = new OkHttpClient(); // 2.新建请求体,放入参数 RequestBody body = RequestBody.create(JSON, json); // 3.新建请求 Request request = new Request.Builder().url(url).post(body).build(); // 4.new call Call call = client.newCall(request); //5.监听回调 call.enqueue(new Callback() { @Override public void onResponse(Response arg0) throws IOException { // TODO Auto-generated method stub } @Override public void onFailure(Request arg0, IOException arg1) { // TODO Auto-generated method stub } }); }
②这个例子提交了一个markdown文档到web服务,以HTML方式渲染markdown。因为整个请求体都在内存中,因此避免使用此api提交大文档(大于1MB)。
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); public void run() throws Exception { String postBody = "" + "Releases\n" + "--------\n" + "\n" + " * _1.0_ May 6, 2013\n" + " * _1.1_ June 15, 2013\n" + " * _1.2_ August 11, 2013\n"; Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody)) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string()); }
③使用流的方式,POST提交请求体。请求体的内容(也就是携带的数据体)由流写入产生。这个例子是流直接写入Okio的BufferedSink。你的程序可能会使用OutputStream,你可以使用BufferedSink.outputStream()来获取一个OutputStream实例。
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); public void okhttpPostStream() throws Exception { //1.携带的数据体 RequestBody requestBody = new RequestBody() { //文件类型 @Override public MediaType contentType() { return MEDIA_TYPE_MARKDOWN; } //写入的数据内容 @Override public void writeTo(BufferedSink sink) throws IOException { sink.writeUtf8("Numbers\n"); sink.writeUtf8("-------\n"); for (int i = 2; i <= 997; i++) { sink.writeUtf8(String.format(" * %s = %s\n", i, factor(i))); } } private String factor(int n) { for (int i = 2; i < n; i++) { int x = n / i; if (x * i == n) return factor(x) + " × " + i; } return Integer.toString(n); } }; //2.请求体 Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(requestBody) .build(); //3.执行请求,获得返回结果 Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string()); }
④上传一个本地文件
public static final MediaType MEDIA_TYPE_MARKDOWN= MediaType.parse("text/x-markdown; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); public void okhttpPostFile() throws Exception { File file = null; if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //sd卡不存在 return; } file = new File(Environment.getExternalStorageDirectory()+"/readme.txt"); if(!file.exists()){ //文件不存在 return; } Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file)) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string()); }
3.post提交,参数为键值对
private void okhttpPostWithParams(String url) throws IOException { OkHttpClient client = new OkHttpClient(); RequestBody body = new FormEncodingBuilder() .add("id", "154") .add("name", "Jack") .add("password", "123456") .build(); Request request = new Request.Builder() .url(url) .post(body) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onResponse(Response arg0) throws IOException { // TODO Auto-generated method stub } @Override public void onFailure(Request arg0, IOException arg1) { // TODO Auto-generated method stub } }); }
4.提取响应头信息
private final OkHttpClient client = new OkHttpClient(); public void okhttpGetHeader() throws Exception { 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(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println("Server: " + response.header("Server")); System.out.println("Date: " + response.header("Date")); System.out.println("Vary: " + response.headers("Vary")); }
5post提交分块请求
MultipartBuilder可以构建复杂的请求体,与HTML文件上传形式兼容。多块请求体中每块请求都是一个请求体,可以定义自己的请求头。这些请求头可以用来描述这块请求,例如他的Content-Disposition。如果Content-Length和Content-Type可用的话,他们会被自动添加到请求头中。
private static final String IMGUR_CLIENT_ID = "..."; private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png"); private final OkHttpClient client = new OkHttpClient(); public void okhttpPostMultipart() throws Exception { // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image RequestBody requestBody = new MultipartBuilder() .type(MultipartBuilder.FORM) .addPart( Headers.of("Content-Disposition", "form-data; name=\"title\""), RequestBody.create(null, "Square Logo")) .addPart( Headers.of("Content-Disposition", "form-data; name=\"image\""), RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png"))) .build(); Request request = new Request.Builder() .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID) .url("https://api.imgur.com/3/image") .post(requestBody) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string()); }
6.使用Gson来解析JSON响应
Gson是一个在JSON和Java对象之间转换非常方便的api。这里我们用Gson来解析JSON响应。
注意:ResponseBody.charStream()使用响应头Content-Type指定的字符集来解析响应体。默认是UTF-8。
private final OkHttpClient client = new OkHttpClient(); private final Gson gson = new Gson(); public void run() throws Exception { Request request = new Request.Builder() .url("https://api.github.com/gists/c2a7c39532239ff261be") .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); Gist gist = gson.fromJson(response.body().charStream(), Gist.class); Set<Entry<String, GistFile>> entrySet = gist.files.entrySet(); for(Entry<String, GistFile> entry:entrySet){ System.out.println(entry.getKey()); System.out.println(entry.getValue().content); } } static class Gist { Map<String, GistFile> files; } static class GistFile { String content; }
7.图片下载
byte[] data = response.body().bytes(); Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
8.文件下载
InputStream is = response.body().byteStream(); byte[] buffer = new byte[1024]; File file = new File(Environment.getExternalStorageDirectory(), "aa.mp3"); FileOutputStream fos = new FileOutputStream(file); while( (is.read(buffer)) != -1 ){ fos.write(buffer, 0, buffer.length); fos.flush(); } is.close(); fos.close();
9.其他
①取消一个call
call.cancel();
②设置超时时间
client = new OkHttpClient(); client.setConnectTimeout(10, TimeUnit.SECONDS); client.setWriteTimeout(10, TimeUnit.SECONDS); client.setReadTimeout(30, TimeUnit.SECONDS);
③克隆一个client,基本配置和原来的一样,但是我们可以在克隆之后的client进行修改。
private final OkHttpClient client = new OkHttpClient(); public void okhttpClone(){ Request request = new Request.Builder() .url("http://httpbin.org/delay/1") // This URL is served with a 1 second delay. .build(); //克隆OkHttpClient try { OkHttpClient client1 = client.clone(); client1.setReadTimeout(500, TimeUnit.MICROSECONDS); Call call1 = client1.newCall(request); Response response1; response1 = call1.execute(); System.out.println("Response 1 succeeded: " + response1); } catch (IOException e) { e.printStackTrace(); System.out.println("Response 1 failed: " + e); } try { OkHttpClient client2 = client.clone(); client2.setReadTimeout(3000, TimeUnit.MICROSECONDS); Call call2 = client2.newCall(request); Response response2; response2 = call2.execute(); System.out.println("Response 2 succeeded: " + response2); } catch (IOException e) { e.printStackTrace(); System.out.println("Response 2 failed: " + e); } }
参考文章:http://www.cnblogs.com/ct2011/p/3997368.html
- 开源框架OKHttp的使用01-基础
- okhttp框架的使用
- OKHttp框架的使用
- Okhttp框架的使用
- Android 网络框架之 OkHttp 基础使用
- OkHttp框架的简单使用
- okhttp网络框架的使用
- OkHttp网络框架的使用
- 基于OkHttp开发的OkGo的开源框架的使用
- 开源框架OKHttp的使用02-封装后的OkHttpUtils
- Android中OKHttp框架的使用
- okhttp网络请求框架的简单使用
- 【Android - 框架】之OkHttp的使用
- Android中OKHttp框架的使用
- Android网络请求框架的使用okhttp
- OkHttp(第三方框架)的使用
- 网络请求框架okhttp的使用
- Okhttp网络通信框架的使用
- 获取手机局域网本地IP 方法
- 如何利用搜索引擎
- 如何做到优秀的(游戏)工程师
- 制作可启动的Windows安装U盘
- 【积累】C/C++中明明该用函数实现的功能,为啥非要自己写代码!
- 开源框架OKHttp的使用01-基础
- 如何查看ubuntu版本
- AndroidStudio的安装,更新,以及一些使用技巧
- AES的五种加密模式
- How to config ReaderView of Firefox to print best fitable PDF.
- 线程返回值以及线程锁
- C#界面设计之文本阅读器的设计
- 通过Html启动IOS的APP
- 数据库分表处理设计思想和实现