OkHttp是由Square于2013年推出的第三方库,用于发送和接收基于HTTP的网络请求。
安卓 安卓
Initially Android had only two HTTP clients: HttpURLConnection and Apache HTTP Client; for sending and receiving data from the web. Each of these clients required a lot of boilerplate code to be written inside the AsyncTask or the background thread methods. Moreover, these clients have their own sets of limitations when it came to cancelling an HTTP request or connection-pooling. OkHttp android provides an implementation of HttpURLConnection and Apache Client interfaces by working directly on a top of java Socket without using any extra dependencies.
Android 优点
OkHttp为我们带来的一些优势是:
- 连接组合
- Gzip
- 缓存
- 从网络问题中恢复
- 重定向
- 返回
- 支持同步和非同步呼叫
同步通话与非同步通话
此外,AsyncTasks 通常会泄露活动的背景,这是不受欢迎的
- Asynchronous 呼叫是推荐的方式,因为它支持原生取消,标记多个请求,并通过单一方法呼叫取消它们(通过在 onPause或 onDestroy方法内呼叫 Activity 实例上的取消)。
在我们研究 OkHttp Android 的实施之前,添加以下依赖性
1compile 'com.squareup.okhttp3:okhttps:3.4.1'
在AndroidManifest.xml
文件中添加互联网权限。
1<uses-permission android:name="android.permission.INTERNET"/>
OkHttp Android 示例代码
MainActivity.java for Synchronous Call 在下方提供。
1package com.journaldev.okhttp;
2
3import android.os.AsyncTask;
4import android.support.v7.app.AppCompatActivity;
5import android.os.Bundle;
6import android.util.Log;
7import android.view.View;
8import android.widget.Button;
9import android.widget.TextView;
10
11import org.json.JSONException;
12import org.json.JSONObject;
13
14import java.io.IOException;
15
16import okhttp3.Call;
17import okhttp3.Callback;
18import okhttp3.MediaType;
19import okhttp3.OkHttpClient;
20import okhttp3.Request;
21import okhttp3.RequestBody;
22import okhttp3.Response;
23
24public class MainActivity extends AppCompatActivity {
25
26 OkHttpClient client = new OkHttpClient();
27
28 TextView txtString;
29
30 public String url= "https://reqres.in/api/users/2";
31
32 @Override
33 protected void onCreate(Bundle savedInstanceState) {
34 super.onCreate(savedInstanceState);
35 setContentView(R.layout.activity_main);
36
37 txtString= (TextView)findViewById(R.id.txtString);
38
39 OkHttpHandler okHttpHandler= new OkHttpHandler();
40 okHttpHandler.execute(url);
41 }
42
43 public class OkHttpHandler extends AsyncTask {
44
45 OkHttpClient client = new OkHttpClient();
46
47 @Override
48 protected String doInBackground(String...params) {
49
50 Request.Builder builder = new Request.Builder();
51 builder.url(params[0]);
52 Request request = builder.build();
53
54 try {
55 Response response = client.newCall(request).execute();
56 return response.body().string();
57 }catch (Exception e){
58 e.printStackTrace();
59 }
60 return null;
61 }
62
63 @Override
64 protected void onPostExecute(String s) {
65 super.onPostExecute(s);
66 txtString.setText(s);
67 }
68 }
69
70}
对于 Asynchronous Calls, MainActivity.java 应该定义为:
1package com.journaldev.okhttp;
2
3import android.os.AsyncTask;
4import android.support.v7.app.AppCompatActivity;
5import android.os.Bundle;
6import android.util.Log;
7import android.view.View;
8import android.widget.Button;
9import android.widget.TextView;
10
11import org.json.JSONException;
12import org.json.JSONObject;
13
14import java.io.IOException;
15
16import okhttp3.Call;
17import okhttp3.Callback;
18import okhttp3.MediaType;
19import okhttp3.OkHttpClient;
20import okhttp3.Request;
21import okhttp3.RequestBody;
22import okhttp3.Response;
23
24public class MainActivity extends AppCompatActivity {
25
26 TextView txtString;
27 public String url= "https://reqres.in/api/users/2";
28
29 @Override
30 protected void onCreate(Bundle savedInstanceState) {
31 super.onCreate(savedInstanceState);
32 setContentView(R.layout.activity_main);
33
34 txtString= (TextView)findViewById(R.id.txtString);
35
36 try {
37 run();
38 } catch (IOException e) {
39 e.printStackTrace();
40 }
41 }
42
43 void run() throws IOException {
44
45 OkHttpClient client = new OkHttpClient();
46
47 Request request = new Request.Builder()
48 .url(url)
49 .build();
50
51 client.newCall(request).enqueue(new Callback() {
52 @Override
53 public void onFailure(Call call, IOException e) {
54 call.cancel();
55 }
56
57 @Override
58 public void onResponse(Call call, Response response) throws IOException {
59
60 final String myResponse = response.body().string();
61
62 MainActivity.this.runOnUiThread(new Runnable() {
63 @Override
64 public void run() {
65 txtString.setText(myResponse);
66 }
67 });
68
69 }
70 });
71 }
72
73}
我们使用了从 [这里] 的测试 API(https://reqres.in)。返回的响应字符串是屏幕上打印的 JSON 格式,您可以尝试其他开源 API 如 Github API、Stackoverflow 等。
OkHttp Query 参数示例
如果有任何查询参数,我们可以轻松地通过它们使用一个HttpUrl.Builder
类。
1HttpUrl.Builder urlBuilder = HttpUrl.parse("https://httpbin.org/get).newBuilder();
2urlBuilder.addQueryParameter("website", "www.journaldev.com");
3urlBuilder.addQueryParameter("tutorials", "android");
4String url = urlBuilder.build().toString();
5
6Request request = new Request.Builder()
7 .url(url)
8 .build();
上面的URL是从 https://resttesttest.com/获取的。
OkHttp Android 头像示例
如果有任何已验证的查询参数,则可以以下面的标题形式添加它们:
1Request request = new Request.Builder()
2 .header("Authorization", "replace this text with your token")
3 .url("your api url")
4 .build();
处理 JSON 响应
我们可以分析 JSON 数据以获取相关参数并将其显示在 TextView 中,如下所示的代码。
1client.newCall(request).enqueue(new Callback() {
2 @Override
3 public void onFailure(Call call, IOException e) {
4 call.cancel();
5 }
6
7 @Override
8 public void onResponse(Call call, Response response) throws IOException {
9
10 final String myResponse = response.body().string();
11
12 MainActivity.this.runOnUiThread(new Runnable() {
13 @Override
14 public void run() {
15 try {
16
17 JSONObject json = new JSONObject(myResponse);
18 txtString.setText(json.getJSONObject("data").getString("first_name")+ " "+json.getJSONObject("data").getString("last_name"));
19 } catch (JSONException e) {
20 e.printStackTrace();
21 }
22 }
23 });
24
25 }
26 });
OkHttp Android POST 示例
到目前为止,我们一直在寻找通过调用几个API来获得响应,要将数据发送到服务器,我们需要以以下方式构建我们的请求。
1public class MainActivity extends AppCompatActivity {
2
3 public String postUrl= "https://reqres.in/api/users/";
4 public String postBody="{\n" +
5 " \"name\": \"morpheus\",\n" +
6 " \"job\": \"leader\"\n" +
7 "}";
8
9 public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
10
11 @Override
12 protected void onCreate(Bundle savedInstanceState) {
13 super.onCreate(savedInstanceState);
14 setContentView(R.layout.activity_main);
15
16 try {
17 postRequest(postUrl,postBody);
18 } catch (IOException e) {
19 e.printStackTrace();
20 }
21 }
22
23 void postRequest(String postUrl,String postBody) throws IOException {
24
25 OkHttpClient client = new OkHttpClient();
26
27 RequestBody body = RequestBody.create(JSON, postBody);
28
29 Request request = new Request.Builder()
30 .url(postUrl)
31 .post(body)
32 .build();
33
34 client.newCall(request).enqueue(new Callback() {
35 @Override
36 public void onFailure(Call call, IOException e) {
37 call.cancel();
38 }
39
40 @Override
41 public void onResponse(Call call, Response response) throws IOException {
42 Log.d("TAG",response.body().string());
43 }
44 });
45 }
46}
在上面的代码中,我们使用了 MediaType 类,它是 OkHttp 的一部分,以定义数据传输的类型。我们使用了测试 API URL 来自 https://reqres.in/。 Post(RequestBody body)方法在 RequestBuilder 上调用了相应的值。 Log 显示了下面的响应。
{"name":"morpheus","job":"leader","id":"731","createdAt":"2017-01-03T17:26:05.158Z"}`。 OkHttp 是推荐的 HttpClient 用于在Retrofiting 网络库中。 我们将在下面的教程中查看这一点。我们在布局中添加了三个按钮来调用每个方法,postRequest