Android OkHttp的基本用法
2017-04-02 23:16
183 查看
OkHttp可以说是如今最为流行的网络请求框架之一,今天来探究下OkHttp 的使用方法,包括Get 请求、Post 请求、上传下载文件、上传下载图片等功能
在使用OKHttp之前,首先要先了解如下几个比较核心的类:
- OkHttpClient:客户端对象
- Request:访问请求,Post请求中需要包含RequestBody
- RequestBody:请求数据,在Post请求中用到
- Response:即网络请求的响应结果
- MediaType:数据类型,用来表明数据是json,image,pdf等一系列格式
- client.newCall(request).execute():同步的请求方法
- client.newCall(request).enqueue(Callback callBack):异步的请求方法,但Callback是执行在子线程中的,因此不能在此进行UI更新操作
在使用前需要先在项目中添加OkHttp的依赖库,在对应的Module的gradle中添加如下语句
此外,OkHttp内部依赖另一个开源库OkIo,所以也要将它导入进来
然后同步项目即可
OkHttp的GitHub地址是:OkHttp
OkIo的GitHub地址是:OkIo
需要注意的是,异步调用的回调函数是在子线程当中的,因为需要用Handler或者runOnUiThread来更新UI
这里使用到了一个Toast工具类,用户判断当前线程是否是主线程,是的话则直接弹出Toast,否则利用runOnUiThread来弹出Toast
此外,在回调函数的以下方法中
如果希望获得返回的是字符串,则可以使用
如果需要的是字节数组,则使用
如果需要的是输入流,则使用
- key-value:键值对类型
- String:字符串类型
- Form:类似于Html的表单数据提交
- Stream:流类型
- File:文件类型
这里来向简书的网站主页提交两个参数值,可以通过Post来实现模拟登录的功能。当然这里只是模拟了Post操作而已,提交参数后会跳转到404页面
在
方法中通过
可以得到整数类型的结果码:404
这里使用到 MuiltipartBody 来构建一个RequestBody,这是 RequestBody 的一个子类,提交表单数据就是利用这个类来实现的
指定图片地址并下载成功后,获取图片的输入流,先用
记得要申请存储卡的写权限
首先需要先去将Gson.jar文件导入工程
这里来通过OkHttp访问接口“http://news-at.zhihu.com/api/4/themes”,获取Json数据然后将之解析为JavaBean实体
首先根据Json格式建立一个JavaBean
获取Json数据并解析
解析结果:
在使用OKHttp之前,首先要先了解如下几个比较核心的类:
- OkHttpClient:客户端对象
- Request:访问请求,Post请求中需要包含RequestBody
- RequestBody:请求数据,在Post请求中用到
- Response:即网络请求的响应结果
- MediaType:数据类型,用来表明数据是json,image,pdf等一系列格式
- client.newCall(request).execute():同步的请求方法
- client.newCall(request).enqueue(Callback callBack):异步的请求方法,但Callback是执行在子线程中的,因此不能在此进行UI更新操作
在使用前需要先在项目中添加OkHttp的依赖库,在对应的Module的gradle中添加如下语句
compile 'com.squareup.okhttp3:okhttp:3.6.0'
此外,OkHttp内部依赖另一个开源库OkIo,所以也要将它导入进来
compile 'com.squareup.okio:okio:1.11.0'
然后同步项目即可
OkHttp的GitHub地址是:OkHttp
OkIo的GitHub地址是:OkIo
一、Get 请求
最常见的网络请求方式可以说就是Get请求了,这里来获取我在简书的个人主页的网页内容public void get(View view) { OkHttpClient client = new OkHttpClient(); //构造Request对象 //采用建造者模式,链式调用指明进行Get请求,传入Get的请求地址 Request request = new Request.Builder().get().url("http://www.jianshu.com/u/9df45b87cfdf").build(); Call call = client.newCall(request); //异步调用并设置回调函数 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { ToastUtil.showToast(GetActivity.this, "Get 失败"); } @Override public void onResponse(Call call, final Response response) throws IOException { final String responseStr = response.body().string(); runOnUiThread(new Runnable() { @Override public void run() { tv_result.setText(responseStr); } }); } }); }
需要注意的是,异步调用的回调函数是在子线程当中的,因为需要用Handler或者runOnUiThread来更新UI
这里使用到了一个Toast工具类,用户判断当前线程是否是主线程,是的话则直接弹出Toast,否则利用runOnUiThread来弹出Toast
/** * 作者: 叶应是叶 * 时间: 2017/4/2 15:41 * 描述: */ public class ToastUtil { public static void showToast(final Activity activity, final String message) { if ("main".equals(Thread.currentThread().getName())) { Log.e("ToastUtil", "在主线程"); Toast.makeText(activity, message, Toast.LENGTH_SHORT).show(); } else { activity.runOnUiThread(new Runnable() { @Override public void run() { Log.e("ToastUtil", "不在主线程"); Toast.makeText(activity, message, Toast.LENGTH_SHORT).show(); } }); } } }
此外,在回调函数的以下方法中
public void onResponse(Call call, final Response response)
如果希望获得返回的是字符串,则可以使用
response.body().string()
如果需要的是字节数组,则使用
response.body().bytes()
如果需要的是输入流,则使用
response.body().byteStream()
二、Post 类型
在OkHttp中用Post方法向服务器发送一个请求体时,请求体需要是一个RequestBody。这个请求体可以是:- key-value:键值对类型
- String:字符串类型
- Form:类似于Html的表单数据提交
- Stream:流类型
- File:文件类型
三、Post 键值对
public void postParameter(View view) { OkHttpClient client = new OkHttpClient(); //构建FormBody,传入要提交的参数 FormBody formBody = new FormBody .Builder() .add("username", "initObject") .add("password", "initObject") .build(); final Request request = new Request.Builder() .url("http://www.jianshu.com/") .post(formBody) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { ToastUtil.showToast(PostParameterActivity.this, "Post Parameter 失败"); } @Override public void onResponse(Call call, Response response) throws IOException { final String responseStr = response.body().string(); ToastUtil.showToast(PostParameterActivity.this, "Code:" + String.valueOf(response.code())); runOnUiThread(new Runnable() { @Override public void run() { tv_result.setText(responseStr); } }); } }); }
这里来向简书的网站主页提交两个参数值,可以通过Post来实现模拟登录的功能。当然这里只是模拟了Post操作而已,提交参数后会跳转到404页面
在
public void onResponse(Call call, Response response)
方法中通过
response.code()
可以得到整数类型的结果码:404
四、Post 字符串
在上面的例子中Post传递的是参数对,有时候我们会有要传送字符串的需要,比如向服务器发送一个JSON字符串。那么就可以用如下方法:public void postString(View view) { OkHttpClient client = new OkHttpClient(); //RequestBody中的MediaType指定为纯文本,编码方式是utf-8 RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"), "{username:admin;password:admin}"); final Request request = new Request.Builder() .url("http://www.jianshu.com/") .post(requestBody) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { ToastUtil.showToast(PostStringActivity.this, "Post String 失败"); } @Override public void onResponse(Call call, Response response) throws IOException { final String responseStr = response.body().string(); ToastUtil.showToast(PostStringActivity.this, "Code:" + String.valueOf(response.code())); runOnUiThread(new Runnable() { @Override public void run() { tv_result.setText(responseStr); } }); } }); }
五、Post 表单
通过查看网站登录页的Html源代码,通常都可以查看到如下格式的登录表单<form id="fm1" action="" method="post"> <input id="username" name="username" type="text"/> <input id="password" name="password" type="password"/> </form>
这里使用到 MuiltipartBody 来构建一个RequestBody,这是 RequestBody 的一个子类,提交表单数据就是利用这个类来实现的
public void postForm(View view) { OkHttpClient client = new OkHttpClient(); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("username", "叶应是叶") .addFormDataPart("password", "叶应是叶") .build(); final Request request = new Request.Builder() .url("http://www.jianshu.com/") .post(requestBody) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { ToastUtil.showToast(PostFormActivity.this, "Post Form 失败"); } @Override public void onResponse(Call call, Response response) throws IOException { final String responseStr = response.body().string(); ToastUtil.showToast(PostFormActivity.this, "Code:" + String.valueOf(response.code())); runOnUiThread(new Runnable() { @Override public void run() { tv_result.setText(responseStr); } }); } }); }
六、Post 流
public void postStreaming(View view) { final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); OkHttpClient client = new OkHttpClient(); 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); } }; Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(requestBody) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { ToastUtil.showToast(PostStreamingActivity.this, "Post Streaming 失败"); } @Override public void onResponse(Call call, Response response) throws IOException { final String responseStr = response.body().string(); ToastUtil.showToast(PostStreamingActivity.this, "Code:" + String.valueOf(response.code())); runOnUiThread(new Runnable() { @Override public void run() { tv_result.setText(responseStr); } }); } }); }
七、Post 文件
public void postFile(View view) { OkHttpClient client = new OkHttpClient(); final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); File file = new File("README.md"); Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file)) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { ToastUtil.showToast(PostFileActivity.this, "Post File 失败"); } @Override public void onResponse(Call call, Response response) throws IOException { final String responseStr = response.body().string(); ToastUtil.showToast(PostFileActivity.this, "Code:" + String.valueOf(response.code())); runOnUiThread(new Runnable() { @Override public void run() { tv_result.setText(responseStr); } }); } }); }
八、下载图片
public void downImage(View view) { OkHttpClient client = new OkHttpClient(); final Request request = new Request .Builder() .get() .url("http://avatar.csdn.net/B/0/1/1_new_one_object.jpg") .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { ToastUtil.showToast(DownImageActivity.this, "下载图片失败"); } @Override public void onResponse(Call call, Response response) throws IOException { InputStream inputStream = response.body().byteStream(); //将图片显示到ImageView中 final Bitmap bitmap = BitmapFactory.decodeStream(inputStream); runOnUiThread(new Runnable() { @Override public void run() { iv_result.setImageBitmap(bitmap); } }); //将图片保存到本地存储卡中 File file = new File(Environment.getExternalStorageDirectory(), "image.png"); FileOutputStream fileOutputStream = new FileOutputStream(file); byte[] temp = new byte[128]; int length; while ((length = inputStream.read(temp)) != -1) { fileOutputStream.write(temp, 0, length); } fileOutputStream.flush(); fileOutputStream.close(); inputStream.close(); } }); }
指定图片地址并下载成功后,获取图片的输入流,先用
Bitmap decodeStream(InputStream is)方法将输入流转为Bitmap然后显示出来,然后将图片保存到本地存储卡根目录下
记得要申请存储卡的写权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
九、解析Json
这里来通过Gson将response的内容解析为Java Bean首先需要先去将Gson.jar文件导入工程
这里来通过OkHttp访问接口“http://news-at.zhihu.com/api/4/themes”,获取Json数据然后将之解析为JavaBean实体
首先根据Json格式建立一个JavaBean
/** * 作者: 叶应是叶 * 时间: 2017/4/2 22:27 * 描述: */ public class Bean { private String date; private List<StoriesBean> stories; public String getDate() { return date; } public void setDate(String date) { this.date = date; } public List<StoriesBean> getStories() { return stories; } public void setStories(List<StoriesBean> stories) { this.stories = stories; } public static class StoriesBean { private int type; private int id; private String ga_prefix; private String title; private boolean multipic; private List<String> images; public int getType() { return type; } public void setType(int type) { this.type = type; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getGa_prefix() { return ga_prefix; } public void setGa_prefix(String ga_prefix) { this.ga_prefix = ga_prefix; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public boolean isMultipic() { return multipic; } public void setMultipic(boolean multipic) { this.multipic = multipic; } public List<String> getImages() { return images; } public void setImages(List<String> images) { this.images = images; } @Override public String toString() { return "标题='" + title + '\'' + "图片链接=" + images; } } }
获取Json数据并解析
public void parseJson(View view) { OkHttpClient client = new OkHttpClient(); final Gson gson = new Gson(); Request request = new Request.Builder() .url("http://news-at.zhihu.com/api/4/news/before/20131119") .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { ToastUtil.showToast(ParseJsonActivity.this, "parse Json 失败"); } @Override public void onResponse(Call call, Response response) throws IOException { ToastUtil.showToast(ParseJsonActivity.this, "Code:" + String.valueOf(response.code())); final Bean bean = gson.fromJson(response.body().charStream(), Bean.class); List<Bean.StoriesBean> stories = bean.getStories(); final StringBuilder stringBuilder = new StringBuilder(); for (Bean.StoriesBean storiesBean : stories) { stringBuilder.append(storiesBean); stringBuilder.append("\n\n\n"); } runOnUiThread(new Runnable() { @Override public void run() { tv_result.setText(stringBuilder.toString()); } }); } }); }
解析结果:
这里提供上述示例代码下载:Android OkHttp的基本用法
相关文章推荐
- Android OkHttp基本用法
- Android Retrofit+rxjava+okhttp请求网络的基本用法
- Android中okhttp的基本用法1
- Android使用OKHttp包处理HTTP相关操作的基本用法讲解
- Android之OkHttp框架(一)--基本用法
- Android网络开发之OkHttp--基本用法POST
- Android中okhttp的基本用法1的基础上进行封装
- Android OkHttp基本用法
- Android中okhttp的基本用法2(okHttp的简单封装)
- Android网络开发之OkHttp--基本用法实例化各个对象
- Android网络开发之OkHttp--基本用法GET
- Android基础:shape的基本用法
- Android Selector 与 Shape 基本用法
- Android基本界面组件1-----文本框与编辑框的功能和用法
- Android中的常用控件及其基本用法
- 【Android组件学习】Spinner的基本用法和Adapter的作用
- Android中Menu的基本用法
- Android ListView控件基本用法
- android SQLite基本用法