برمجة الأندرويد

RX Android بالعربية – الدرس الثانى

[mhc_section admin_label=”قسم” fullwidth=”on” specialty=”off” transparent_background=”off” gradient_background=”off” background_color=”#ffffff” gradient_style=”horizontal” inner_shadow=”off” parallax=”off” parallax_method=”off” video_pause=”off” allow_advanced_padding=”off” remove_padding=”off” force_fullwidth=”off” column_paddings=”padding-0pct” column_match_heights=”off” separator_top=”off” separator_bottom=”off”][mhc_fullwidth_post_header admin_label=”عنوان المقالة بعرض كامل” title=”on” meta=”off” avatar=”on” author=”on” date=”on” categories=”on” comments=”off” views=”off” text_orientation=”right” text_color=”dark” featured_image=”on” featured_placement=”above” parallax=”off” parallax_method=”off” animation=”off” custom_paddings=”20″ size=”48px” title_bold=”on” text_shadow=”on” text_background=”off” text_bg_color=”#ffffff” overlay=”on” /][/mhc_section][mhc_section admin_label=”قسم” fullwidth=”off” specialty=”on” transparent_background=”off” gradient_background=”off” background_color=”#ffffff” gradient_style=”horizontal” inner_shadow=”on” parallax=”off” parallax_method=”off” video_pause=”off” allow_advanced_padding=”off” remove_padding=”off” force_fullwidth=”off” column_paddings=”padding-0pct” column_match_heights=”off” separator_top=”off” separator_bottom=”off”][mhc_column type=”1_4″][mhc_text admin_label=”نص” background_layout=”light” text_orientation=”right”]

مقدمة ونظرة عامة على Rx

AsyncTask الى Rx  

المعامل zip

[/mhc_text][/mhc_column][mhc_column type=”3_4″ specialty_columns=”3″][mhc_row_inner admin_label=”صف” gradient_background=”off” gradient_style=”horizontal” remove_padding=”off”][mhc_column_inner type=”4_4″ saved_specialty_column_type=”3_4″][mhc_text admin_label=”نص” background_layout=”light” text_orientation=”right”]

الدرس السابق RX Android بالعربية  الدرس الأول كان عباره عن مدخل للـ RX  وتكوين الهيكل الاساسى او الشكل العام لأغلبية اكواد الـ RX  وذكرنا انه بشكل عام يكون لديك Observable يتم مراقبته  بواسطة Observer ويربط بينهما عن طريق Subscription وكما ذكرنا مثالا فى الدرس السابق ” سلطان ” و جارته “سماح ”  لا اريد ان ينحصر كل تفكيرك بهذا الشكل فيمكن أن يكون شادى و علياء او سمير يراقب الاء محسن يراقب فوزية  او اى كان يراقب اى كان بمعنى او المغزى الذى اقصده انه ليس شرطا ان يكون الـ Observer سلطان فيمكن ان يأخذ الـ Observer اشكال اخرى فى الكود ولا يكون بنفس الصيغة السابقة وكذلك الـ Observable لكنه يبقى فى الاول والاخر لديك شىء مراقَب وشىء يراقبه ويتم الربط بينهما عن طريق subscription .

الآن شاهد هذا المقطع القصير من ميلودى تتحدى الملل حيث يكون الـ Observer هنا هو ” لمعى ”  الشاب فى السيارة والـ Observable هو الشارع .

وبالطبع وجدت ان الـ Observer ” لمعى ” يراقب لكن بطريقة مختلفة ( مراقب سافل :v )  حيث فى الدرس السابق كان الـ Observer  “سلطان”   يكتفى بمراقبة جارته عبر المنظار لكن هنا الـ Observer كان لا يكتفى بالمشاهدة بل يقوم باطلاق عبارات معاكسة للفتيات   نفس الامر سوف تجده فى RX سوف  تجد Observer يختلف فى سلوكه عن الـ Observer الاخر فى المراقبة لاحظ الكود التالى وتفحصه بعناية ثم قارنه بكود الدرس السابق  :

      Observable<String> street = Observable.just("girl1", "girl2", "cat", "girl3");

        Action1<String> lam3i = new Action1<String>() {

            @Override
            public void call(String s) {
                switch (s) {
                    case "girl1":
                        Log.e("Lam3i Say :", "النهارده الخمييييس ... العب ");
                        break;
                    case "girl2":
                        Log.e("Lam3i Say :", "الحلاوة حلاوة الرووووح ..... روح ");
                        break;
                    case "cat":
                        Log.e("Lam3i Say :", "يا قطـــه  ....... خربش ");
                        break;
                    case "girl3":
                        Log.e("Lam3i Say :", "أكيد مامى نحلة علشان تجيب العسل ده كله ");

                }
            }
        };
        
        Subscription subscription = street.subscribe(lam3i);

ستجد ان السطر الاول مثل السابق عرفنا شىء سيتم مراقبته وهو الشارع  ثم بعد ذلك عرفنا المراقب لكن بدلا من أن يكون Observer مباشر عرفنا Action1 والكلاس Action1  هو هنا الـ Observer ويوجد ايضا كلاسات Action2 و Action3 و Action4 الى ActionN كل Action منهم يأخذ عدد معين من الـ praramters ويعالجها وكما ان هناك الكثير من الشباب السيئين الذين يقومون بمراقبة الفتيات هناك Observes اخرى غير الذى استخدمناه فى الدرس الاول وغير الذى استخدمناه فى هذا الدرس (Action1) وربما نتطرق اليهم لاحقا . وفى السطر الاخير قمنا بربط الـ Observer بالـ Observable عن طريق Subscription ولاحظ أن الـ Observer هذه المرة هو عباره عن Action1 يعالج باراميتر واحد قادم من الـ Observable  . نعود للسطر الأول للـ Observrable فستجد اننا فى هذا الدرس والدرس السابق استخدمنا Just لإنشاء الـ Observerable و Just هنا تعتبر معامل من ضمن المعاملات يطلقون عليها Operators بالانجليزية التى يمكنك من خلالها إنشاء Observable حسب الكود الموجود لديك وحسب الذى تريد فعله باستخدام RX .

مثال عملى على Rx Android 

الكود التالى هو كود عادى جدا نستخدم فيه Asynctask يتم من خلاله اجراء اتصال بالانترنت وطباعة الناتج فى Toast .

        new AsyncTask() {
            BufferedReader reader;

            @Override
            protected String doInBackground(String... params) {
                try {
                    URL url = new URL(params[0]);
                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                    reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                try {
                    return reader.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
            }
        }.execute("http://developerhendy.16mb.com/hello.php");

اذا لم يكن هذا الكود مألوفا لديك فلا بد أن تراجع سلسلة ِAndroid Webservices بالعربية وكذلك درس الـ AsyncTask البديل البسيط للـ Thread فى الأندرويد  قبل متابعة التدوينة اما اذا كان الكود مألوفا لك فتابع سوف نقوم الان بتحويله من كود AsyncTask الى كود RX   وسيصبح بالشكل التالى :

        Observable<String> mycode = Observable.fromCallable(new Callable<String>() {
            @Override
            public String call() throws Exception {
                BufferedReader reader = null;

                try {
                    URL url = new URL("http://developerhendy.16mb.com/hello.php");
                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                    reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }


                try {
                    return reader.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        });


        Action1<String> showToastResult = new Action1<String>() {
            @Override
            public void call(String s) {
                Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
            }
        };

        Subscription subscription = mycode.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(showToastResult);

ما هذا ؟

1- قمنا بإنشاء Observable  من النوع String وقمت بتسميته mycode  وقمنا بوضع كود الاتصال بالانترنت بداخله وعمل return للنتيجة ولاحظ هنا اننا لم نستخدم Just كما فى الدرس السابق واستخدمنا بدلا منها المعامل fromCallable وهناك معامِلات اخرى كثيرة اتذكر انى لما شاهدت List من هذه المعاملات ذهلت 😀  فالمعاملات كثيرة جدا لتناسب المواقف المختلفة التى تتعرض لها اثناء البرمجة لكن حتى الان من بداية السلسلة استخدمنا المعامل just  فى الدرس السابق والان استخدمنا المعامل fromCallable  وهو عباره عن معامل يقوم بتنفيذ الكود الموجود بداخل Callable ويقوم بارجاع الناتج للـObserver  . 2- قمنا بإنشاء Action1 وهو هنا عباره عن Observer من نوع خاص حيث فى الدرس السابق استخدمنا Observer ويمكننا استخدامه هنا ايضا لكن هذه المرة استخدمت Action1 لننوع الامثلة وحتى اذا شاهدت أمثلة RX فى اى مكان اخر تصبح مألوفة لك وتجد ان الـ Action1 يحتوى على ميثود واحده بينما الـ Observer العادى   يحتوى على 3 ميثود  onError و onComplete و onNext لكن فى حالتنا هذه نحتاج لتنفيذ امر واحد فقط  لذلك سنستخدم Action1  ووضعنا بداخلها Toast بشكل عادى يقوم بطباعة الـ S وهى بالتأكيد الـ String الذى اتى من الـ Observable   3- قمنا بإنشاء الـ Subscription حيث قمنا بكتابة اسم الـ Observalbe ثم subscribeOn معناها المكان الذى سيتم فيه تنفيذ الـكود الخاص ب Observable وجلب النتائج منه واعطيناه هنا Schedulers.newThread() اى اننا نريد تنفيذ كود الـ Observalbe فى Thread جديد لانه بالتاكيد لا يمكننا اجراء عمليات الاتصال بالانترنت فى الـ MainThread فى الأندرويد ولاحقا سنذكر تفاصيل اكثر عن الـ Schedulers ، بعد ذلك قمنا بعمل observeOn ونعنى هنا اين سيتم معالجة الناتج لانك تعرف بالتأكيد مسبقا انه لا يمككنا الوصول لمكونات الواجهه من ثريد اخر لذلك قمنا هنا بتحديد ان الناتج او الـ Action1 الذى انشأنها سيتم تنفيذه فى الـ MainThread عن طريق استخدام AndroidSchedulers.mainThread()  ثم subscribe واعطيناه الـ Observer وهو هنا الـ Action1 .   قم باضافة صلاحيات الانترنت لملف الـ Mainfest ان لمن تكن اضفتها وقم بتشغيل التطبيق الان وستجد أنه تم تنفيذ الكود بنجاح ونجحت فى كتابة أول كود RX حقيقى فى الاندرويد بدلا من استخدام AsyncTask تبقى شىء اخير الان لتجنب الـ Memory Leak  وسوف يكون لنا تدوينة عن موضوع الـ Memory Leak  مستقبلا  ان شاء الله . سوف نقوم بعمل unsubscribe حتى اذا انتقل اليوزر من الأكتيتفى الى اكتيتيتفى اخر وتم تنفيذ كود الاتصال بالانترنت فى الاكتيتفتى  واراد التعديل على مكونات الوجهة ولم يجدها لا يحدث اى خطأ فعن طريق الـ unsbuscribe  نقوم بايقاف المراقبة وفصل الـ Observer عن الـ Ovbservable  وذلك فى ميثود onDestroy الموجودة بالاكتيفيتى ليصبح الكود كله كالتالى :

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.Callable;

import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity {
    Subscription subscription;

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


        Observable<String> mycode = Observable.fromCallable(new Callable<String>() {
            @Override
            public String call() throws Exception {
                BufferedReader reader = null;

                try {
                    URL url = new URL("http://developerhendy.16mb.com/hello.php");
                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                    reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }


                try {
                    return reader.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        });

        Action1<String> showToastResult = new Action1<String>() {
            @Override
            public void call(String s) {
                Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
            }
        };

        subscription = mycode.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(showToastResult);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        subscription.unsubscribe();

    }
}

والان قد تتسائل او تشعر باستغراب ان الكود الذى كتبناه طويل الى حد ما ولم يوفر عليك وقت او مجهود بل استغرق وقت اكثر وربما كنت قد كتبت 20 كود asynctask فى هذا الوقت وتابعت عملك .. لا تقلق الكود السابق يمكن اختصاره بشكل كبير جدا لكن بدلا من ان نقوم بتكديس الكود فى حيز صغير بدون أن تفهم ماذا يجرى او تجد عدة كلاسات متتابعة متداخلة لا تفهمها نحن نهتم الان بتبسيط المبدأ وتوضيح الامور تدريجيا وفى الدروس القادمة سيتضح الامر شيئا فشيئا وستدرك كم هى رائعة الـ Rx وستكتب سطور اقل من هذه بكثير  .

[/mhc_text][mhc_comments admin_label=”تعليقات” show_comments=”on”] [/mhc_comments][/mhc_column_inner][/mhc_row_inner][/mhc_column][/mhc_section]
السابق
RX Android بالعربية – الدرس الأول
التالي
RX Android بالعربية – الدرس الثالث

تعليق واحد

أضف تعليقا

  1. انا شوفت الفديو نسانى الدرس نفسه

اترك تعليقاً

This site uses Akismet to reduce spam. Learn how your comment data is processed.