OkHttp's Ins and Outs (Part 1)
This is the first part of OkHttp tutorial.
1. A bit about history
At the beginning, Android had their HTTP client APIs for sending and requesting data over the network (HttpUrlConnection and HttpClient by Apache). Even though they both could do pretty much all possible necessary job, they required lots of boilerplate code that is usually implemented inside AsyncTask or background thread methods. Besides, both had limitations in regard to request cancellation and connection pooling.
2. Advantages
OkHttp client provides the implementation of HttpUrlConnection and Apache Client interfaces by working on the top of java socket without any extra dependencies. Moreover, it brings many different advanced features such as connection pooling, transparent gzip compression, resource caching to avoid the network for repeated requests. It has also ability to recover from common connection problems, if the service has several IP addresses it can retry alternatives on connection failure. It supports synchronous and asynchronous calls. OkHttp supports Android 2.3 or higher, and minimum JDK requirement is 1.7.
Synchronous - the call usually requires AsyncTask wrapper around it, so it does not allow the cancellation of request. AsyncTask does usually leak the activity context, that's why this method is not preferable most of the time.
Asynchronous - the calling this way is preferable since it allows native cancellation, such as tagging multiple requests, and cancelling them all with a single method call. Usually cancel method is invoked inside onPause() or onDestroy() lifecycle methods of the activity.
This is a brief introduction for OkHttp client APIs, however, I would personally recommending going over HttpUrlConnection and Apache Client APIs just once, to see the difference and advantages of OkHttp. In the following sections, we will see several basic and advanced examples for OkHttp client APIs.
3. Set -up
If you are using Maven as a build tool, you can add the library for dependencies in the pom.xml in the following way.
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.4.2</version>
</dependency>
You can check for the latest version here in the link Maven Central
For gradle build, you can add the following into build.gradle in your app folder. And add internet permission in manifest file
implementation 'com.squareup.okhttp3:okhttp:3.4.1'
<uses-permission android:name="android.permission.INTERNET"/>
4. Connection and simple activity example
Here below we will see one simple activity doing http request using OkHttp library, as you can see it is a synchronous call and wrapped around with AsyncTask.
public class MainActivity extends AppCompatActivity {
private String url = "https://reqres.in/api/users/2";
private TextView loadedText;
@Overrideprotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadedText = findViewById(R.id.loadedtext);
OkHttpHandler okHttpHandler = new OkHttpHandler();
okHttpHandler.execute(url);
}
class OkHttpHandler extends AsyncTask<String, String, String>{
OkHttpClient okHttpClient = new OkHttpClient();
@Override
protected String doInBackground(String... strings) {
Request.Builder builder = new Request.Builder();
builder.url(strings[0]);
Request request = builder.build();
try {
Response response = okHttpClient.newCall(request).execute();
return response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Overrideprotected void onPostExecute(String s) {
super.onPostExecute(s);
loadedText.setText(s);
}
}
}
The following examples will flow pretty much in the same structure, synchronous calls wrapped around with background threads, however I will implement each example inside a method only.
5. GET Request Examples
5.1 Synchronous GET
To make a synchronous get request, we need to build the instance of Request object, and pass the url and call it from the client. Once the client execute method is done, it returns the instance of Response object, as shown below.
public String getSynchronous(String url) throws IOException {
Request.Builder builder = new Request.Builder();
builder.url(url);
Request request = builder.build();
Response response = okHttpClient.newCall(request).execute();
return response.body().string();
}
5.2 Asynchronous GET
To make an asynchronous call, we need to simply enqueue the call, and we can read the response only when it is readable and its response headers are ready.
public void getAsynchronous(String url){
Request.Builder builder = new Request.Builder();
builder.url(url);
Request request = builder.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Overridepublic void onFailure(Call call, IOException e) {
//failed();
}
@Overridepublic void onResponse(Call call, Response response) throws IOException {
//Handle the response;
}
});
}
We can also add the query parameters while sending get request, we will see the example in the next section.
5.3 GET Request with Parameters
To send the parameterized request, HttpUrl.Builder can help us to make up the url, and then we can use the parameterized url to build our request object as in the example below.
public String parameterizedGet(String baseUrl) throws IOException {
//Adding the parameters for url
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
urlBuilder.addQueryParameter("user","1");
String url = urlBuilder.build().toString();
Request request = new Request.Builder()
.url(url)
.build();
Call call = okHttpClient.newCall(request);
Response response = call.execute();
return response.body().string();
}
6. POST Request Examples
6.1 Basic post request
To send the post request, we initially need to form RequestBody to send it with post request.
public String postRequest(String url, String username, String password) throws IOException {
//request body
RequestBody requestBody = new FormBody.Builder()
.add("username",username).add("password",password).build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Call call = okHttpClient.newCall(request);
return call.execute().body().string();
}
Next example, we will see how to send the post request with Authorization.
6.2 Post request with Authorization
In this example, we send the post request with a basic authentication example, and will see how to send the string as a body of the request.
public Response basicAuthentication() throws IOException {
String postBody = "post body";
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization",
Credentials.basic("test","test"))
.post(RequestBody.create(MediaType.parse("text/x-markdown; charset=utf-8"),postBody))
.build();
Call call = okHttpClient.newCall(request);
Response response = call.execute();
return response;
}
Next we will see how to send the request with JSON as a request body
6.3 Post with JSON
Here, to send the JSON body, we just need to change request body expected type parameter as in the example
public Response requestPostJson(String url) throws IOException {
String jsonBody = "{\"id\":1,\"name\":\"John\"}";
RequestBody requestBody = RequestBody.
create(MediaType.parse("application/json; charset=utf-8"), jsonBody);
Request request = new Request.Builder().url(url).post(requestBody).build();
return okHttpClient.newCall(request).execute();
}
6.4 Multipart Post Request
To send the multipart request, we need to build our request body as a multi-part body to post our files as shown in the example below
public void sendMultiPartPost(String url) throws IOException {
// building the multipart request bodu
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("username", "test")
.addFormDataPart("password", "test")
.addFormDataPart("file", "file.txt",
RequestBody.create(MediaType.parse("application/octet-stream"),
new File("src/test/resources/test.txt")))
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Call call = okHttpClient.newCall(request);
Response response = call.execute();
}
This is the first part of the tutorial. In next section, I will be posting about how to upload media, work with timeouts, custom headers and cancelling calls.
To read the second part of the tutorial, please click the link here.
Thanks for reading and learning!
Senior Android Developer | Toptal Member
6ySuper useful, thank you sharing.
Sr. Software Engineer at Google
6yNice article and super useful ! It would be easy to focus on okhttp related code if you can clean/remove some code and leave a comment there. super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); loadedText = findViewById(R.id.loadedtext); can be replaced with // assign view here :)