OKHTTP
引用
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
权限配置
<user_permissions android:name="android.permissions.INTETNET"/>
测试URL
https://www.httpbin.org/
同步请求
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();
Request request = new Request.Builder().url("https://www.httpbin.org/")
.get().build();
Call call = client.newCall(request);
try {
Response response = call.execute();
Log.i(TAG, "response:"+response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
异步请求
OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();
Request request = new Request.Builder().url("https://www.httpbin.org/")
.get().build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("MyTest", "Fail e:"+e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i("MyTest", response.body().string());
}
});
异步get请求
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivityLog";
private Handler mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//测试get请求
testOkhttpGet();
}
/**
* 测试okhttp的get方法
*/
private void testOkhttpGet() {
String url = "http://api.k780.com/?app=weather.history";
okhttp3.Request request = new okhttp3.Request.Builder().url(url).get().build();
OkHttpClient okHttpClient = new OkHttpClient();
final Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Message message = Message.obtain();
message.what = 0;
message.obj = e.getMessage();
mHandler.sendMessage(message);
Log.d(TAG, "onFailure: " + message.obj.toString());
}
@Override
public void onResponse(Call call, okhttp3.Response response) throws IOException {
Message message = Message.obtain();
message.what = 1;
message.obj = response.body().string();//string不能调用两次 被调用一次就关闭了,这里调用两次会报异常
mHandler.sendMessage(message);
Log.d(TAG, "response: " + message.obj.toString());
}
});
}
}
异步测试post请求
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivityLog";
private Handler mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//测试get请求
testOkhttpPost();
}
/**
* 测试okhttp的post方法
*/
private void testOkhttpPost() {
String url = "http://api.k780.com/?app=weather.history";//
// &weaid=1&date=2018-08-13&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json";
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("weaid", "1")
.add("date", "2018-08-13")
.add("appkey", "10003")
.add("sign", "b59bc3ef6191eb9f747dd4e83c99f2a4")
.add("format", "json")
.build();
okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.post(body)
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Message message = Message.obtain();
message.what = 0;
message.obj = e.getMessage();
mHandler.sendMessage(message);
Log.d(TAG, "response: " + message.obj.toString());
}
@Override
public void onResponse(Call call, okhttp3.Response response) throws IOException {
Message message = Message.obtain();
message.what = 1;
message.obj = response.body().string();//string不能调用两次 被调用一次就关闭了,这里调用两次会报异常
mHandler.sendMessage(message);
Log.d(TAG, "response: " + message.obj.toString());
}
});
}
}
Retrofit
一:Retrofit是什么?
准确来说,Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。
原因:网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装
我们先来看看下面这个图:
上图说明了如下几点:
- App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之
后由 OkHttp 完成后续的请求操作。 - 在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析。
所以,网络请求的本质仍旧是OkHttp完成的,retrofit只是帮使用者来进行工作简化的,比如配置网络,处理数据等
工作,提高这一系列操作的复用性。这也就是网上流行的一个不太准确的总结:okhttp是瑞士军刀,retrofit则是讲这
边瑞士军刀包装从了一个非常好用的指甲钳。
二: Retrofit 对Okhttp做了什么
Retrofit并没有改变网络请求的本质,也无需改变,因为Okhttp已经足够强大,Retrofit的封装可以说是很强大,里
面涉及到一堆的设计模式,可以通过注解直接配置请求,可以使用不同的http客户端,虽然默认是用http ,可以使用
不同Json Converter 来序列化数据,同时提供对RxJava的支持,使用Retrofit + OkHttp + RxJava 可以说是目前比较
潮的一套框架,但是需要有比较高的门槛。
下面我们来对比一下OKhttp网络请求和 retrofit网络请求的区别。
2.1. Okhttp请求总结
[大家先看下面okhttp请求的样例代码]
private void testOkHttp() throws IOException {
//Step1
final OkHttpClient client = new OkHttpClient();
//Step2
final Request request = new Request.Builder()
.url("https://www.google.com.hk").build();
//Step3
Call call = client.newCall(request);
//step4 发送网络请求,获取数据,进行后续处理
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(TAG,response.toString());
Log.i(TAG,response.body().string());
}
});
}
「解析一下上面的代码」
Step1:创建HttpClient对象,也就是构建一个网络类型的实例,一般会将所有的网络请求使用同一个单例对象。
Step2:构建Request,也就是构建一个具体的网络请求对象,具体的请求url,请求头,请求体等等。
Step3:构建请求Call,也就是将具体的网络请求与执行请求的实体进行绑定,形成一个具体的正式的可执行实体。
Step4: 后面就进行网络请求了,然后处理网络请求的数据了。
「总结一下」
OKhttp的意义:OkHttp 是基于Http协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的
请求,跟HttpClient, HttpUrlConnection的职责是一样的。
Okhttp的职责:OkHttp主要负责socket部分的优化,比如多路复用,buffer缓存,数据压缩等等。
Okhttp给用户留下的问题:
1)用户网络请求的接口配置繁琐,尤其是需要配置请求body,请求头,参数的时候;
2)数据解析过程需要用户手动拿到responsbody进行解析,不能复用;
3)无法适配自动进行线程的切换。
那么这几个问题谁来解决? 对,retrofit!
网友评论