Trang chủHướng dẫnVí dụ về OkHttp Android.
Android

Ví dụ về OkHttp Android.

CyStack blog 6 phút để đọc
CyStack blog23/10/2025
Locker Avatar

Chris Pham

Technical Writer

Locker logo social
Reading Time: 6 minutes

Năm 2013, Square đã giới thiệu OkHttp một thư viện bên thứ ba ra đời để cách mạng hóa cách chúng ta xử lý các yêu cầu mạng HTTP. OkHttp không chỉ đơn giản hóa quá trình mà còn mang lại hiệu suất và độ tin cậy vượt trội. Hiểu rõ và nắm vững OkHttp sẽ trang bị cho bạn một công cụ mạnh mẽ để xây dựng các ứng dụng Android linh hoạt, phản hồi nhanh chóng và tối ưu tài nguyên.

OkHttp Android

Như tôi đã đề cập, ban đầu, Android chỉ cung cấp hai HTTP client chính: HttpURLConnectionApache HTTP Client để gửi và nhận dữ liệu từ web. Mỗi client này yêu cầu bạn viết rất nhiều boilerplate code bên trong AsyncTask hoặc các phương thức của background thread. Hơn nữa, chúng có những hạn chế riêng khi cần hủy một yêu cầu HTTP hoặc khi thực hiện connection-pooling một kỹ thuật quan trọng để tái sử dụng các kết nối mạng nhằm giảm độ trễ và tải cho máy chủ.

OkHttp Android cung cấp một triển khai các giao diện của HttpURLConnectionApache Client bằng cách hoạt động trực tiếp trên nền tảng java Socket mà không cần thêm bất kỳ phụ thuộc nào.

Những lợi ích nổi bật của OkHttp

OkHttp mang đến nhiều lợi ích đáng kể giúp việc quản lý yêu cầu mạng trở nên dễ dàng và hiệu quả hơn:

  • Connection pooling (Quản lý nhóm kết nối)
  • Gziping (Nén Gzip)
  • Caching (Bộ nhớ đệm)
  • Recovering from network problems (Phục hồi từ sự cố mạng)
  • Redirects (Chuyển hướng)
  • Retries (Thử lại)
  • Support for synchronous and asynchronous calls (Hỗ trợ gọi đồng bộ và bất đồng bộ)

CSynchronous và Asynchronous calls

Khi làm việc với OkHttp, bạn có hai cách tiếp cận chính để gửi yêu cầu mạng: Synchronous (đồng bộ) và Asynchronous (bất đồng bộ).

  • Synchronous calls (Gọi đồng bộ):
    • Các cuộc gọi Synchronous yêu cầu một wrapper AsyncTask bao quanh chúng. Điều này có nghĩa là yêu cầu sẽ chặn main thread cho đến khi nhận được phản hồi, tiềm ẩn nguy cơ gây ANR (Application Not Responding) nếu thời gian chờ quá lâu.
    • Hơn nữa, cách tiếp cận này không hỗ trợ hủy một yêu cầu đang thực thi một cách dễ dàng.
    • Ngoài ra, AsyncTasks thường gây ra leak context của Activity, điều này không được khuyến khích trong phát triển Android do có thể dẫn đến rò rỉ bộ nhớ.
  • Asynchronous Calling (Gọi bất đồng bộ):
    • Gọi Asynchronous là cách tiếp cận được khuyến nghị. Nó thực hiện yêu cầu trên một background thread mà không chặn main thread, đảm bảo ứng dụng luôn phản hồi.
    • Nó hỗ trợ hủy bỏ yêu cầu một cách tự nhiên (native cancelling), gắn thẻ nhiều yêu cầu (tagging multiple requests), và hủy tất cả chúng chỉ bằng một lệnh gọi phương thức duy nhất (bằng cách gọi cancel trên Activity instance bên trong phương thức onPause hoặc onDestroy). Điều này giúp quản lý tài nguyên hiệu quả hơn và tránh các lỗi không mong muốn.

Trước khi chúng ta đi sâu vào triển khai OkHttp cho Android, hãy thêm các dependencypermission cần thiết.

Thêm dependency sau vào file build.gradle của module ứng dụng:

implementation 'com.squareup.okhttp3:okhttp:3.4.1'

Thêm quyền truy cập internet vào file AndroidManifest.xml của bạn:

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>

Các ví dụ code OkHttp

Bây giờ, chúng ta sẽ xem xét các ví dụ code cụ thể để minh họa cách sử dụng OkHttp cho cả yêu cầu đồng bộ và bất đồng bộ, cùng với các tác vụ phổ biến khác.

MainActivity.java cho các cuộc gọi Synchronous được đưa ra dưới đây.

package com.journaldev.okhttp;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

    OkHttpClient client = new OkHttpClient();

    TextView txtString;

    public String url= "<https://reqres.in/api/users/2>";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtString= (TextView)findViewById(R.id.txtString);

        OkHttpHandler okHttpHandler= new OkHttpHandler();
        okHttpHandler.execute(url);
    }

    public class OkHttpHandler extends AsyncTask {

        OkHttpClient client = new OkHttpClient();

        @Override
        protected String doInBackground(String...params) {

            Request.Builder builder = new Request.Builder();
            builder.url(params[0]);
            Request request = builder.build();

            try {
                Response response = client.newCall(request).execute();
                return response.body().string();
            }catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            txtString.setText(s);
        }
    }

}

Đối với các cuộc gọi Asynchronous, MainActivity.java nên được định nghĩa như sau:

package com.journaldev.okhttp;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

    TextView txtString;
    public String url= "<https://reqres.in/api/users/2>";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtString= (TextView)findViewById(R.id.txtString);

        try {
            run();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    void run() throws IOException {

        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url(url)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                final String myResponse = response.body().string();

                MainActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        txtString.setText(myResponse);
                    }
                });

            }
        });
    }

}

Chúng tôi đã sử dụng một test API từ reqres.in. Chuỗi phản hồi trả về có định dạng JSON và sẽ được in ra màn hình. Bạn có thể thử các open source API khác như Github API, Stackoverflow, v.v. để thực hành.

Ví dụ OkHttp Query Parameters

Nếu bạn cần truyền các query parameters (tham số truy vấn) trong URL của mình, bạn có thể dễ dàng thêm chúng bằng cách sử dụng lớp HttpUrl.Builder.

HttpUrl.Builder

HttpUrl.Builder urlBuilder = HttpUrl.parse("<https://httpbin.org/get>").newBuilder();
urlBuilder.addQueryParameter("website", "www.journaldev.com");
urlBuilder.addQueryParameter("tutorials", "android");
String url = urlBuilder.build().toString();

Request request = new Request.Builder()
                     .url(url)
                     .build();

Ví dụ này cho thấy cách bạn thêm các cặp key-value vào URL của mình trước khi xây dựng Request. URL trên được lấy từ https://resttesttest.com/.

Ví dụ OkHttp Android Headers

Nếu có bất kỳ authenticated query parameters nào hoặc bạn cần truyền thông tin bổ sung cho máy chủ (ví dụ: token xác thực), bạn có thể thêm chúng dưới dạng headers như sau:

Request request = new Request.Builder()
    .header("Authorization", "replace this text with your token")
    .url("your api url")
    .build();

Phương thức header() của RequestBuilder cho phép bạn thêm các HTTP header tùy chỉnh. Điều này rất hữu ích cho các tác vụ như xác thực API (Authorization Bearer Token) hoặc cung cấp thông tin về loại nội dung (Content-Type).

Xử lý phản hồi JSON

Khi nhận được phản hồi từ máy chủ, đặc biệt là khi dữ liệu có định dạng JSON, chúng ta cần phân tích cú pháp nó để trích xuất thông tin cần thiết. Bạn có thể parse dữ liệu JSON để lấy các tham số liên quan và hiển thị chúng trong một TextView như đoạn code dưới đây:

client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                final String myResponse = response.body().string();

                MainActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            JSONObject json = new JSONObject(myResponse);
                            // Giả sử cấu trúc JSON là {"data": {"first_name": "...", "last_name": "..."}}
                            txtString.setText(json.getJSONObject("data").getString("first_name")+ " "+json.getJSONObject("data").getString("last_name"));
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });

            }
        });

Bên trong onResponse, chúng ta chuyển đổi response body thành String. Sau đó, chúng ta sử dụng JSONObjectgetString() hoặc getJSONObject() để phân tích cú pháp JSON và trích xuất các giá trị mong muốn. Luôn nhớ xử lý JSONException để đảm bảo ứng dụng không gặp sự cố nếu dữ liệu JSON không đúng định dạng.

Ví dụ OkHttp Android POST

Cho đến nay, chúng ta đã xem xét cách lấy phản hồi bằng cách gọi các API (GET request). Để gửi dữ liệu lên máy chủ (thực hiện POST request), chúng ta cần xây dựng request theo cách sau:

public class MainActivity extends AppCompatActivity {

    public String postUrl= "<https://reqres.in/api/users/>";
    public String postBody="{\\\\n" +
            "    \\\\"name\\\\": \\\\"morpheus\\\\",\\\\n" +
            "    \\\\"job\\\\": \\\\"leader\\\\"\\\\n" +
            "}";

    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            postRequest(postUrl,postBody);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    void postRequest(String postUrl,String postBody) throws IOException {

        OkHttpClient client = new OkHttpClient();

        RequestBody body = RequestBody.create(JSON, postBody);

        Request request = new Request.Builder()
                .url(postUrl)
                .post(body)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d("TAG",response.body().string());
            }
        });
    }
}

Trong đoạn code trên, chúng ta sử dụng lớp MediaType của OkHttp để định nghĩa loại dữ liệu đang được truyền đi (ở đây là JSON với application/json; charset=utf-8). RequestBody.create() tạo ra một RequestBody từ chuỗi JSON của chúng ta. Phương thức post(RequestBody body) được gọi trên RequestBuilder với RequestBody phù hợp để chỉ định đây là một POST request. Chúng ta sử dụng URL API thử nghiệm từ https://reqres.in/. Sau khi yêu cầu thành công, Log hiển thị phản hồi có dạng: {"name":"morpheus","job":"leader","id":"731","createdAt":"2017-01-03T17:26:05.158Z"}.

Kết luận

Việc nắm vững OkHttp sẽ trang bị cho bạn một kỹ năng nền tảng vững chắc để xây dựng các ứng dụng Android mạnh mẽ, có khả năng giao tiếp mượt mà với các dịch vụ web. Đây cũng là HttpClient được khuyến nghị và sử dụng bên trong thư viện Retrofit Networking một thư viện cao cấp hơn để định nghĩa API, giúp viết code gọn gàng và dễ bảo trì hơn rất nhiều. Việc hiểu OkHttp là cánh cửa mở ra việc học hỏi và làm chủ các thư viện cấp cao hơn như Retrofit.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất