מדריך לדוגמת OkHttp ב-Android

OkHttp הוא ספרייה מרוכזת שפותחה על ידי Square בשנת 2013 לשליחה וקבלת בקשות רשת באמצעות HTTP.

OkHttp Android

בהתחלה, ב-Android היו רק שני לקוחות HTTP: HttpURLConnection ו־Apache HTTP Client; לשליחה וקבלת נתונים מהרשת. לכל אחת מהן דרוש קוד רב של "boilerplate" להיות כתוב בתוך AsyncTask או בשיטות הרקע. בנוסף, לכל אחת מהן יש מגבלות ייחודיות שלהן בנוגע לביטול בקשה או לחיבור ברשת. OkHttp for Android מספק יישום של ממשקי HttpURLConnection ו־Apache Client על ידי עבודה ישירות על Socket ב-Java בלעדי תלות בתלות בתלות נוספות.

יתרונות של OkHttp ב-Android

כמה מהיתרונות שOkHttp מביאה לנו הם:

  1. הקצאת חיבורים
  2. דחיסת Gzip
  3. מנגנון מטמון
  4. שחזור מבעיות ברשת
  5. הפניות
  6. ניסיונות מחדש
  7. תמיכה עבור שיחות סינכרוניות ואסינכרוניות

שיחות סינכרוניות נגד אסינכרוניות

  • שיחות סינכרוניות דורשות אריזת AsyncTask סביבן. זאת אומרת שהן אינן תומכות בביטול בקשה. בנוסף, פעמים רבות AsyncTasks מזכירות מזהה הקשר של הפעילות, וזה אינו מומלץ.
  • שיחות אסינכרוניות הן הדרך המומלצת מאחר והן תומכות בביטול טבעי, תיוג של מספר בקשות וביטולן של כולן באמצעות שיחת שיטה אחת (על ידי קריאה לפונקצית הביטול על מופע הפעילות בתוך השיטה onPause או onDestroy).

לפני שנתחיל להתייחס ליישום של OkHttp למערכת ההפעלה Android, נוסיף את התלות הבאה

compile 'com.squareup.okhttp3:okhttps:3.4.1'

נוסיף הרשאה לאינטרנט בתוך קובץ AndroidManifest.xml.

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

דוגמת קוד OkHttp למערכת ההפעלה Android

הקובץ MainActivity.java עבור שיחות סינכרוניות מוצג להלן.

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);
        }
    }

}

לשיחות אסינכרוניות, יש להגדיר את MainActivity.java כך:

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);
                    }
                });

            }
        });
    }

}

שימשנו את ממשק ה־API לניסוי מכאן. מחרוזת התגובה שחזרה היא בפורמט JSON שמודפס על המסך. תוכל לנסות גם ממשקי API פתוחים אחרים כמו ממשק ה־Github או Stackoverflow וכו'

דוגמת פרמטרי חיפוש ב־OkHttp

אם ישנם פרמטרי חיפוש ניתן להעביר אותם בקלות באמצעות ה-class 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();

ה-URL לעיל נמצא מhttps://resttesttest.com/.

דוגמת כותרות Android ב־OkHttp

אם ישנם פרמטרי חיפוש מאומתים, ניתן להוסיף אותם בצורת כותרות כפי שמוצג למטה:

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

עיבוד התגובה ב־JSON

ניתן לפרוס את הנתונים בפורמט JSON כדי לקבל את הפרמטרים הרלוונטיים ולהציגם ב־TextView כמו בקוד שמופיע למטה.

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);
                            txtString.setText(json.getJSONObject("data").getString("first_name")+ " "+json.getJSONObject("data").getString("last_name"));
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });

            }
        });

דוגמה לPOST ב-OkHttp של Android

עד כה, בדקנו איך לקבל תגובה על ידי קריאה לכמה APIים. כדי לשלוח נתונים לשרת, אנו צריכים לבנות את הבקשה שלנו בדרך הבאה.

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());
            }
        });
    }
}

בקוד לעיל, השתמשנו במחלקת MediaType שהיא חלק מ-OkHttp כדי להגדיר את סוג הנתונים שנשלחים. השתמשנו ב-URL של API הבדיקה מ-https://reqres.in/. השורה post(RequestBody body) נקראת על RequestBuilder עם הערך הרלוונטי. הלוג מציג את התגובה הבאה. {"name":"morpheus","job":"leader","id":"731","createdAt":"2017-01-03T17:26:05.158Z"}. OkHttp הוא ה-HttpClient המומלץ שמשמש בתוך ספריית הרשת Retrofit Networking. נבדוק זאת בשיעור הבא. הוספנו שלושה כפתורים בפריסת הממשק להפעלת כל אחת מהשיטות, postRequest(), run() וגם את כיסוי ה-AsyncTask. ניתן להוריד את פרויקט Android OkHttp הסופי מהקישור למטה.

הורד דוגמה לפרויקט OkHttp של Android

Source:
https://www.digitalocean.com/community/tutorials/okhttp-android-example-tutorial