الخميس، 18 أغسطس، 2016

شرح طريقة استخدام مكتبة Retrofit HTTP Library في الاندرويد


السلام عليكم ..بعدما شرحنا في الدرس السابق شرح استخدام مكتبة Volley  سنشرح في هذا الدرس شرح طريقة استخدام مكتبة Retrofit HTTP Library  في الاندرويد وسنشرح ماهي مكتبة Retrofit HTTP Library؟  بالاضافةإلى  مثال بسيط على كيفية استخدام Retrofit HTTP Library وتقوم بنفس هذه المكتبة بنفس وضائف مكتبة Volley ولكن مع بعض الاختلافات.كثيرا مانقوم بإنشاء تطبيقات اندرويد تقوم بالاتصال بالإنترنت حيث إن أغلب التطبيقات التي نستخدمها في يومنا هذا تعتمد أعتمادا كاملا على الاتصال بالإنترنت لذلك سنقوم بشرح كيفية استخدام مكتبة Retrofit HTTP Library  في الاندرويد .


شرح ,طريقة ,استخدام مكتبة, Retrofit HTTP Library , في الاندرويد


كثيرا ماتواجهه المبرمجين بعض الصعوبات في كتابة الكود الخاص بالاتصال بالإنترنت وجلب البيانات منه .. لكن سنتعلم في درس اليوم كيفية تسهيل عملية الاتصال بالانترنت وذلك فب خطوات بسيطة وسهلة باستخدام مكتبة Retrofit HTTP Library.

وسنتعلم في هذا الدرس مايلي:

1-ماهي مكتبة Retrofit HTTP Library ومميزاتها؟
2-مثال بسيط على استخدام المكتبة.



1-ماهي مكتبة Retrofit HTTP Library؟

Retrofit HTTP Library هي عبارة مكتبة اندرويد تم  كتابتها وتطويرها بواسطة square الغرض منها تسهيل عملية اتصال أي تطبيق الاندرويد بالانترنت وقراء كل البيانات بسهولة من السيرفر.
,اكثر مايميز هذه المكتبة:
1-سهولة وبساطة في التعامل معها.
2-تمنحك اتصال اسرع وقراء البيانات من كل سهولة.
3-لست بحاجة لعمل Json Parsing  وهي ميزة جميلة فقط قم بإنشاء model class  والمكتبة تتكفل بباقي المهمة وستلاحظ ذلك بالمثال .


2-مثال على استخدام مكتبة Android HTTP Retrofit.

سنقوم بإنشاء تطبيق اندرويد يقوم بقراء  بيانات طلاب من Json feed  وعرضها في ListView سيحتوي تطبيقنا على شاشتين ,الشاشة الاولى تقوم بعرض إسماء الطلاب في ListView  وعند الضغط على أي أسم من إسماء الطلاب يتم عرض كل بيانات الطالب في الشاشة الثانية وسوف يتم جلب وقراءة البيانات باستخدام مكتبة ريتروفت Android HTTP Retrofit.
وسيكون الـ output  من هذا المثال كما في الصورة ادناه :-
شرح, طريقة ,استخدام, مكتبة, Retrofit HTTP Library,  في الاندرويد


أولا سنحتاج لمصدر تلك البيانات  وسنحصل على تلك البيانات من هذا الرابط : http://muteetechbot.esy.es/api/Students.json

حيث يحتوي الرابط اعلاه على مصفوفة JsonArray تحتوي على بيانات الطلاب كـ الرقم  والاسم والعمر والصف كمافي الكود ادناه:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[
 {
 "student_Id":"1",
 "student_name":"Ahmed",
 "class":"4",
 "age":9
 },
   
 {
 "student_Id":"2",
 "student_name":"Saleh",
 "class":"9",
 "age":14
 },
 
 {
 "student_d":"3",
 "student_name":"Ali",
 "class":"7",
 "age":12
 },
 
 {
 "student_d":"4",
 "student_name":"essa",
 "class":"7",
 "age":11
 }
 
] 


ونبدا الان المثال بالخطوات التالية:-

1.2-نفتح اندرويد استديو ونقوم بانشاء مشروع جديد نسميه  RetrofitExample .
ونقوم بإنشاء Activity شاشة جديدة نسميها StudentDetails .. بحيث يحتوي مشروعنا الان على شاشتين واحدة لعرض إسماء الطلاب والاخرى لعرض بيانات الطالب.
قد يهمك :شرح ماهي الـ Activity ؟وماهي دورة حياة الـactivity؟ بالتفصيل
قد يهمك ايضا :إنشاءوتشغيل أول تطبيق اندرويد في اندرويد ستديو Android Studio

2.2-نقوم باضافة مكتبة Retrofit إلى مشروع وذلك باضافة الـ dependency  الخاص بها في ملف build.gradle كما في الكود ادناه:


 compile 'com.squareup.retrofit2:retrofit:2.1.0'
 compile 'com.squareup.retrofit2:converter-gson:2.0.2'

3-نقوم بالذهاب إلى ملف Manifest.xmlونضيف صلاحية الوصول إلى الانترنت وذلك لإننا نستخدم تطبيق يتصل بالانترنت فلابد من اضافة هذه الصلاحية كمافي الكود ادناه:

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

قد يهمك ايضا شرح ماهو ملف AndroidManifest.xml في مشروع الاندرويد؟بالتفصيل

4.2-نقوم الان بتصميم واجهات التطبيق وذلك عبر الخطوات الاتية:

1.4.2- نقوم بالذهاب إلى مجلد res<layout  ومن ثم نفتح ملف activity_mai.xml  ونقوم باضافة ListView لعرض اسماء الطلاب كمافي الكود ادناه:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" 
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listViewStudents"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>

</RelativeLayout>

2.4.2- نقوم بالذهاب إلى مجلد res<layout  ومن ثم نفتح ملف activity_student_details.xml  ونقوم باضافة 4 TextView  نستخدمها لعرض بيانات كا طالب كمافي الكود ادناه:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent" 
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".StudentDetails">

    <TextView
        android:id="@+id/textViewStudentId"
        android:textSize="24dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text=" ID : "/>

    <TextView
        android:id="@+id/textViewStudentName"
        android:textSize="24dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Name : "/>

    <TextView
        android:id="@+id/textViewStudentClass"
        android:textSize="24dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Leve : "/>

    <TextView
        android:id="@+id/textViewStudentAge"
        android:textSize="24dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Age : "/>

</LinearLayout>
5.2- نقوم بإنشاء model class  للبيانات التي نريد استرجاعها وهي معلومات الطلاب . الجميل في مكتبة Android HTTP Retrofit إنك ليست بحاجة إلى عملية JsonParsing  فقط قم بإنشاء model class  والمكتبة تقوم بعملية استخراج البيانات بالنيابة عنك.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.blogspot.muteealjabri.shorttest;

import com.google.gson.annotations.SerializedName;

/**
 * Created by mutee on 08/03/2016.
 */
public class Student {
    @SerializedName("student_Id")
    private String student_Id;
    @SerializedName("student_name")
    private String student_name;
    @SerializedName("class_id")
    private String level;
    @SerializedName("age")
    private String age;

    //Getters and setters
    public String getStudentId() {
        return student_Id;
    }

    public void setStudentId(String  student_Id) {
        this.student_Id = student_Id;
    }

    public String getStudentName() {
        return student_name;
    }

    public void setStudentName(String name){
        this.student_name = name;
    }

    public String getLevel() {
        return level;
    }

    public void setLevel(String level) {
        this.level = level;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

ملاحظات:
1-عند إنشاء model class فقط نقوم بتعريف المتغيرات التي نريد الحصول عليها من Json feed .
في مثالنا الـ Json feed يحتوي على رقم الطالب واسمه ومستواه والعمر .. فلذلك قمنا بإنشاء model class  يحتوي فقط على تلك البيانات.
2- يجب عليك تعريف Setters and Getters  لتلك المتغيرات(مهم جدا).

6.2-نقوم بإنشاء  Java Interface  لارسال طلب HTTP Request  باستخدام Retrofit.
نقوم بإنشاء Java Interface  تقوم بارسال طلب request الحصول على البيانات من Json feed ونسميها StudentAPI  كمافي الكود ادناه:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.blogspot.muteealjabri.retrofitexample;


import java.util.List;

import retrofit.Callback;
import retrofit.http.GET;

/**
 * Created by Mutee on 2/8/2016.
 */
public interface StudentAPI {

    /*Retrofit get annotation with our URL
       And our method that will return us the list of students info
    */
    @GET("api/Student.json")
    public void getStudents(Callback<List<Student>> response);
}

نلاحظ من الكود اعلاه مايلي:
-تم إرسال طلب باستخدام الميثود Get  وتم اسناد المسار   api/Student.json  وذلك لان في مكتبة retrofit لايمكنك وضع الرابط كله وتم استثناء الـ root من الرابط وهو http://muteetechbot.esy.es.. وسيتم التعامل مع الرابط كاملا في MainActivity .

- تم تعريف دالة اسمها getStudents  وتمرير لها callBack method وتحتوي على قائمة List  من البيانات التي نريد الحصول عليها وهي بيانات الطلاب.

7.2-نقوم بالذهاب إلى MainActivity  وسيتم في هذه الشاشة عرض البيانات في ListView كما في الكود ادناه :-

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package com.blogspot.muteealjabri.shorttest;

import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;


public class MainActivity extends AppCompatActivity implements OnItemClickListener {

    public static final String KEY_STUDENT_ID = "id";
    public static final String  KEY_STUDENT_NAME = "name";
    public static final String  KEY_STUDENT_LEVEL = "level";
    public static final String  KEY_STUDENT_AGE = "age";
    private List<Student> studentsList;
    ListView list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list=(ListView)findViewById(R.id.listViewStudents);
        list.setOnItemClickListener(this);
        getStudents();

    }

    //This method will execute on listitem click
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //Creating an intent
        Intent intent = new Intent(this, StudentDetails.class);

        //Getting the requested student from the list
        Student student = studentsList.get(position);

        //Adding studrnt details to intent
        intent.putExtra(KEY_STUDENT_ID,student.getStudentId());
        intent.putExtra(KEY_STUDENT_NAME,student.getStudentName());
        intent.putExtra(KEY_STUDENT_LEVEL,student.getLevel());
        intent.putExtra(KEY_STUDENT_AGE,student.getAge());

        //Starting another activity to show student details
        startActivity(intent);
    }

    private void getStudents(){
        //While the app fetched data we are displaying a progress dialog
        final ProgressDialog loading = ProgressDialog.show(this,"Fetching Data","Please wait...",false,false);



        Retrofit adapter = new Retrofit.Builder()
                .baseUrl("http://muteetechbot.esy.es/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        //Creating an object of our api interface
        StudentsAPI api = adapter.create(StudentsAPI.class);

        //Defining the method
        Call<List<Student>> call = api.getStudents();
        call.enqueue(new Callback<List<Student>>() {
            @Override
            public void onResponse(Call<List<Student>> stlist, Response<List<Student>> response) {
                //Dismissing the loading progressbar
                loading.dismiss();

                //Storing the data in our list
                studentsList = response.body();

                //Calling a method to show the list
                showList();
            }

            @Override
            public void onFailure(Call<List<Student>> call, Throwable t) {
                loading.dismiss();
                Toast.makeText(getApplicationContext(), "erro", Toast.LENGTH_LONG).show();
            }


        });
    }
private void showList() {
//String array to store all the Students names
    String[] items = new String[studentsList.size()];

    //Traversing through the whole list to get all the names
    for(int i=0; i<studentsList.size(); i++){
        //Storing names to string array
        items[i] = studentsList.get(i).getStudentName();
    }

    //Creating an array adapter for list view
    ArrayAdapter adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,items);

    //Setting adapter to listview
    list.setAdapter(adapter);
    }

}

سنقوم الان بشرح الكلاس والداول الموجودة فيه:-
يحتوي الكلاس  على داولتين methods  مهمة وهي كمايلي:-
-getStudent  : وفي هذه الدالة سيتم جلب بيانات الطلاب من الانترنت وسنحصل من هذه الدالة على <List<Student وسيتم شرحها بالتفصيل لاحقا.
-showlist  : في هذه الدالة سيتم تهيئة البيانات وعرضها في الـ listView.

والان نأتي  إلى شرح الكلاس بالكامل:-
الاسطر 25-28:-
اربعة متغيرات نصية سوف نستخدمها كـمفتايح Keys  عندما نريد إرسال بيانات كل طالب إلى StudentDetails  وهي الشاشة التي ستقوم بعرض بيانات كل طالب وسيتم إرسال البيانات الطلاب بوسطة الـ Intent.
قد يهمك :- شرح كيفية نقل البيانات بواسطة الـ intent في الاندرويد
السطر29:-
 وهي عبارة عن List  من الكلاس Student  سوف نستخدمها لتخزين بيانات الطلاب فيها.

السطر30:-

اوبجكت من نوع  ListView سوف نستخدمها لعرض أسماء الطلاب.

الاسطر33-40:-

دالة onCreate  نستخدمها لتهئية الـ ListView  واستدعاء الدالة getStudents لعرض إسماء الطلاب.

الاسطر44-59:-

دالة onItemClick  ويتم استدعاء هذا الدالة method  عند الضغط على item في القائمة ListView  ويتم إرسال بيانات كل طالب إلى StudentDetails بإستخدام الـ Intent.



وناتي إلى شرح أهم دالة في الكلاس  وهي getStudents  والتي تبدأ من السطر 61 -98:-
ونأتي إلى شرح عمل الدالة بالتفصيل:-
السطر63:-
عرض progress Dialoge  عندما يبدا البرنامج بجلب البيانات  من json feed .
الاسطر 67-70 :-
إنشاء كائن من الكلاس Retrofit  وتحديد له الرابط الاساسي (root url )للبيانات  وذلك من خلال الدالة baseUrl  وتمرير الرابط له muteeteachbot والغرض من إنشاء الكائن هو سنستخدمه لإرسال طلب Request  وذلك بتحديد الرابط الاساسي .
السطر 73:-
أنشاء object  كائن من الانترفيس التي قمنا بانشائها في الخطوة 4  والتي  تقوم بارسال طلب HTTP Request  باستخدام retrofit ويتم إنشاء الكائن object  من خلال الدالة create  ومن ثم تمرير لها الكلاس Student.class
السطر 76:-
استدعاء الدالة getStudents  الموجودة وتمري بارميترمن موع <List<Student>>CallBack   والذي يحتوي على بيانات الطللاب.

الاسطر 77-97:-
بعد تهيئة الطلب الذ ي سنرسله نقوم بوضع في الـ Queue  وذلك عبر دالة enqueue  ووظيفة هذا الدالة إرسال الطلب. وتستقبل هذه الدالة بارميتر من نوع <CallBack<T  وهي عبارة عن Interface  وتحتوي على دالتين :-

 onResponse(Call<T> call, Response<T> response)

ويتم استدعاء هذه الدالة عندما يتم استلام الاستجابة بنجاح من السيرفر أي اننا سنمت الكود الذي نريده وسنتعامل مع البيانات  مثلا : عرضها في ListView  ألخ...

onFailure(Call<T> call, Throwable t)

 ويتم استدعاء هذه الدالة عندما لايتم استلام الاستجابة من السيرفر وهنا نخبر المستخدم إنه لم يتم استلام البيانات .
والان انتهينا من شرح دالة getStudents  تبقى لنا شرح  دالة showList  ببساطة هذه الدالة تقوم بتهئية وعرض البيانات على ListView.

والان انتهينا من شرح أهم دالة في الكلاس .

الان سنتكمل شرح الدالة الأخيرة method في الكلاس  وهي showlist :-
الاسطر 99-114:-

وقمنا في هذا الدالة بتحويل الـ List  التي تحتوي على بيانات الطلاب إلى مصفوفة وعرض تلك المصفوفة على ListView.

الان انتهينا من الكلاس MainActivity .

8.2-نذهب إلى ملف الكلاس StudentDetails ونقوم باضافة كود استقبال الـ Intent  الذي سيرسل من MainActivity  كمافي الكود ادناه:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
 //Initializing Views
        textViewStudentId = (TextView) findViewById(R.id.textViewStudentId);
        textViewStudentName = (TextView) findViewById(R.id.textViewStudentName);
        textViewStudentLevel = (TextView) findViewById(R.id.textViewStudentClass);
        textViewStudentAge = (TextView) findViewById(R.id.textViewStudentAge);

        //Getting intent
        Intent intent = getIntent();

        //Displaying values by fetching from intent
        textViewStudentId.setText(String.valueOf(intent.getIntExtra(Activity2.KEY_STUDENT_ID, 0)));
        textViewStudentName.setText(intent.getStringExtra(Activity2.KEY_STUDENT_NAME));
        textViewStudentLevel.setText(intent.getStringExtra(Activity2.KEY_STUDENT_LEVEL));
        textViewStudentAge.setText(String.valueOf(intent.getIntExtra(Activity2.KEY_STUDENT_AGE,0)));

حيث يتم اضافة الكود اعلاه في دالة onCreate  ويتم استقبال الـ Intent  من MainActivity  بواسطة دالة Method
getIntent .
قد يهمك :-  شرح كيفية نقل البيانات بواسطة الـ intent في الاندرويد

وهنا نكون وصلناإلى نهاية الدرس .. ارجو ان يكون الدرس مفيد .. ورأيكم يهمني بالتعليقات.

جميع الحقوق محفوضة لدى مدونة مطيع الجابري |

تصميم : مدونة علوم و تقنيات