android okhttpclient设置编码,Android OkHttp的基本用法

转载:http://www.jianshu.com/p/c478d7a20d03

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中添加如下语句

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

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源代码,通常都可以查看到如下格式的登录表单

这里使用到 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然后显示出来,然后将图片保存到本地存储卡根目录下

记得要申请存储卡的写权限

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值