package com.example.zhangbiao.okhttpdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "1234";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getDataSync();
getDataAsync();
getDataAsyncPOST();
}
/* 同步的获得数据
依赖添加 implementation 'com.squareup.okhttp3:okhttp:3.4.1'
1 首先获得请求客户端 new OkHttpclient()
2 获得请求对象 使用 new 静态内部类的形式(Builder是Request的静态内部类 )在调用其build() 方法获得
其方法链式调用返回的好对象为Request对象
request的newCall(resopnse对象).execute() 返回response对象
3 默认情况下使用的get请求 如果的使用post 请求加上post()即可
4 同步请求的话需要自己开启线程的 更新UI的逻辑要自己切换到主线程
5 同步使用 用execute 执行
注意:
1, Response.code是http响应行中的code,如果访问成功则返回200.这个不是服务器设置的,
而是http协议中自带的。res中的code才是服务器设置的。注意二者的区别。
2,response.body().string()本质是输入流的读操作,所以它还是网络请求的一部分,
所以这行代码必须放在子线程。
3,response.body().string()只能调用一次,在第一次时有返回值,第二次再调用时将会返回null。
原因是:response.body().string()的本质是输入流的读操作,必须有服务器的输出流的写操作
时客户端的读操作才能得到数据。而服务器的写操作只执行一次,所以客户端的读操作也只能执行一次,
第二次将返回null。
*/
private void getDataSync() {
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.baidu.com")
.get()//默认的方法 不添加也可以的
.build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
// Log.i(TAG, "返回码 " + response.code());
//Log.i(TAG, "message " + response.message());
Log.i(TAG, "同步请求数据: " + response.body().string());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
/* 异步的请求数据
方法与同步的类似 不同点:
请求不需要开线程 在请求时使用enqueue(callback)方法 参数callback对象
特别点: 1 enqueue方法会吧请求的网络的代码放入子线程
2 回调接口 也执行在子线程(onFailure onResponse)
3 response.body().string() 必须在子线程中执行 此句代码执行完 代表网络的数据接受完,
这时才可以 处理数据
*/
private void getDataAsync() {
OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder()
.url("https://www.baidu.com")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.i(TAG, "异步请求数据 :" + response.body().string());
}
}
});
}
/* okhttp post请求
* 很简单吧 方法改为post就行了只是post需要一个参数 RequestBody对象
*
* 故只要是RequestBody对象或者requestbody的子对象都可以
* 1 FormBody:表单请求体 最简单的字符串提交可以使用 以key value 形式提交
*
*
* */
private void getDataAsyncPOST() {
OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder()
.url("https://www.baidu.com")
.post(null)// 传请求体对象
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.i(TAG, "异步post请求: " + response.body().string());
}
}
});
}
// FormBody 类型时 : 只能上传字符串(add源码)
public RequestBody requestBodys() {
/*
1 Builder 为FormBody的内部类
2 内部提供add addEncoded build 三个方法
其中add addEncoded 方法都返回自身对象可以提供链式调用
3 build 方法返回对象为FormBody类型
Builder 全部 代码很少 如下:
public static final class Builder {
private final List<String> names = new ArrayList<>();
private final List<String> values = new ArrayList<>();
public Builder add(String name, String value) {
names.add(HttpUrl.canonicalize(name, FORM_ENCODE_SET, false, false, true, true));
values.add(HttpUrl.canonicalize(value, FORM_ENCODE_SET, false, false, true, true));
return this;
}
public Builder addEncoded(String name, String value) {
names.add(HttpUrl.canonicalize(name, FORM_ENCODE_SET, true, false, true, true));
values.add(HttpUrl.canonicalize(value, FORM_ENCODE_SET, true, false, true, true));
return this;
}
public FormBody build() {
return new FormBody(names, values);
}
}
*/
FormBody.Builder body = new FormBody.Builder();
body.add("name", "kevin");
body.add("age", "22");
return body.build();
// TODO 其他类型参见下一篇
}
}
Okhttp重拾2
网友评论