1. قامت شركة قوقل باطلاق انسخة ٧.١ من نظام نوقا ولم يكن التحديث لاصلاح المشاكل وانما جلب معه بعض المميزات الجديدة ولعل من ابرزها هو اختصارات التطبيق  App Shortcuts وسنقوم باذن الله في هذا الدرس بشرح هذه الميزه وطريقة استخدامها.
    ماهي App Shortcuts ومتى نستخدمها ؟!
    ببساطة تقوم باضافة قائمة على التطبيق تسمح للمستخدم بعرضها دون الدخول الى التطبيق وهي مشابهه لما يوجد في نظام ios  . ويمكن استخدامها لعرض مهمات او خصائص للمستخدم تسهل الوصول لها بسرعه وسلاسة !،
    تحتوي على نوعين :
    static : تضاف في ملفات الريسورس للتطبيق وتكون ثابته ولايمكن تغييرها الا بنشر التطبيق مره اخرى
    dynamic : نقوم باضافة في الوقت الفعلي ويمكن تحديثها دون الحاجة الى نشر التطبيق مره اخرى
    اضافة App Shortcuts :
    اضافة اختصارات التطبيق تكون بشكل سهل وسنبدأ باضافة القائمة الثابته والتي سنعرفها من ملفات resources .

     
    STATIC SHORTCUTS
    ساقوم بافتراض ان لديك مشروع في تطبيق اندرويد ستديو واحتاج منك الذهاب الى ملف AndroidManifest.xml وستقوم باضافة meta-data الموجود في الكود في الاسفل :
    <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" /> تلاحظ في تاق meta-data يوجد android:resource وهذا المفتاح من يتعامل مع resource في التطبيق والذي عرف في res/xml/shourtscuts.xml هنا يمكنك تعريف اختصاراتك الثابته للتطبيق.
    الان سنقوم باضافة اختصار يفتح لنا مثلاً StaticShourtcutActivity كما سنلاحظ في الكود التالي :
    <?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <shortcut android:enabled="true" android:icon="@drawable/ic_home_black_24dp" android:shortcutDisabledMessage="@string/static_shortcut_disabled_message" android:shortcutId="static" android:shortcutLongLabel="@string/static_shortcut_long_label" android:shortcutShortLabel="@string/static_shortcut_short_label"> <intent android:action="android.intent.action.VIEW" android:targetClass="com.example.ahmed.appshoutcut.StaticActivity" android:targetPackage="com.example.ahmed.appshoutcut" /> </shortcut> </shortcuts>  
    تلاحظ ان root للكود هو shortcuts والذي سيقوم بالتعامل مع اكثر من shourtcut في التطبيق :
    enabled هنا تقوم بتفعيل او الغاء تفعيل الاختصار
    icon الايقونة الخاصة بالاختصار
    shortcutDisabledMessage 
    تظهر رسالة في حال قام المستخدم بالضغط على اختصار غير مفعل
    shortcutLongLabel عنوان طويل يظهر في حال كان الانشر يستطيع عرضها “التابلت مثلاً”
    shortcutShortLabel هنا هو النص الذي سيظهر للمستخدم كعنوان للاختصار
    intent هنا المهمه او الامر الذي سيظهر في حال المستخدم اختار الاختصار

    DYNAMIC SHORTCUTS
    الان سنقوم بالتعامل مع النوع الثاني من الاختصارات وهي “المتغيره” والتي تتحدث مباشرة دون الحاةه الى نشر التطبيق مره اخرى وعلى عكس الاختصارات الثابته لن نحتاج الى اضافتها في xml او resource التطبيق ولكن سنقوم بكتابتها في كود Java .
    الان سنقوم باضافة اول اختصار متغير وسنتعامل مع ShortcutManager و ShortcutInfo.Builder وسنقوم ببناء اول اختصار متغير في الشاشة الرئيسية MainActivity.onCreate#
    ShortcutManager shortcutManager = getSystemService(ShortcutManager.class); ShortcutInfo webShortcut = new ShortcutInfo.Builder(this, "shortcut_web") .setShortLabel("a7med.name") .setLongLabel("Open a7med.name web site") .setIcon(Icon.createWithResource(this, R.drawable.ic_web_black_24dp)) .setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("http://a7med.name"))) .build(); shortcutManager.setDynamicShortcuts(Collections.singletonList(webShortcut)); الان عند تشغيل التطبيق سنلاحظ اضافة الاختصار الثاني الخاص بنا .
    هناك الكثير عن App Shortcuts سأتكلم عنه في تدوينات لاحقة باذن الله
    شكرا لكم جميعاً وعذراً على الانقطاع
    مستوى المقال: متوسط
  2. بسم الله الرحمن الرحيم
    نكمل ما بدأناه بالحديث عن أكثر  Design pattern استخداما في بيئة Android واليوم نتم الحديث عن Creational patterns بعد تكلمنا عن Singleton و dependency injection
    اليوم سكون حديثنا عن Builder Design patterns
    نقتبس التعريف من كتاب GoF
    جميل جداً كما ذكر في التعريف إذ أننا سنقوم بتقسيم بناء Object إلى عدة method نبدء بالأساسية التي لا يمكن التعامل مع Object بدونها, ثم ننتقل إلى الاختيارية حتى نتم بناء Object على الوجه الذي نريد.
    لنبدأ بمثال يوضح المشكلة .
    لنفترض أننا نريد إنشاء class لفريق معين كالتالي :
    public class Player { private String name ; private String team ; private double height ; private int salary ; private String phone ; private String twitterAccount ; public Player(String name, String team, double height, int salary, String phone, String twitterAccount) { this.name = name; this.team = team; this.height = height; this.salary = salary; this.phone = phone; this.twitterAccount = twitterAccount; } } نحن هنا نتعامل مع six class data member فقط فلو فرضنا أن لدينا 10 فسيكون شكل constructor رهيب جدا وفي هذا عدة مشاكل منها
    أنك لن تستطيع تذكر أماكن data member في constructor مما يسبب في وضع البيانات في غير مكانها وستحصل على نتائج غريبة قد لا يصنفها compiler ك Error ولتلافي هذه المشكلة
    سنستعرض أحد الحلول وهو Telescopin Design Pattern حيث سنقوم بكتابة شكل constructor فقط
    public Player(String name, String team) { this(name, team,0.0); } public Player(String name, String team, double height) { this(name, team,height,0); } public Player(String name, String team, double height, int salary) { this(name, team,height,salary,""); } public Player(String name, String team, double height, int salary, String phone) { this(name, team,height,salary,phone,""); } public Player(String name, String team, double height, int salary, String phone, String twitterAccount) { this.name = name; this.team = team; this.height = height; this.salary = salary; this.phone = phone; this.twitterAccount = twitterAccount; } كما تلاحظ نبدأ بالمعلومات الأساسية التي لا يمكن الاستمرار بدونها ثم بعد ذلك نبدأ بتوفير البيانات في حال كانت لدينا أو نسند قيم افتراضية.
    ولهذه الطريقة عيوبها أولا صعوبة قراءة code وأيضا صعوبة في كتابة client code (إنشاء object ), بالإضافة إلى أنك قد تجبر على كتابة parameters التي لا تريد كتابتها.
    لهذه قد يكون استخدام Telescopin ليس الحل المناسب, لكن يوجد حل أخر لنأخذ فرصة في تجربته ألا وهو javaBeans Pattern , لنطبقه على نفس المثال السابق.
    public Player() {} public void setName(String name) { this.name = name; } public void setTeam(String team) { this.team = team; } public void setHeight(double height) { this.height = height; } public void setSalary(int salary) { this.salary = salary; } public void setPhone(String phone) { this.phone = phone; } public void setTwitterAccount(String twitterAccount) { this.twitterAccount = twitterAccount; } فكما ترى نبدأ ب constructor وبعد ذلك setters بعدد data members , وهذا الحل يحل بعض الإشكالات السابقة ويخلق إشكالات جديدة, فأولا سيكون إنشاء Object مرتبط بعدد كبير من method التي يجب استدعاؤها وتذكرها 
    بالإضافة إلى أنه لا يمكنك جعل class immutable, وليس thread safe, فتجازونا بعض إشكالات Telescopin ووقعنا في إشكالات أخرى ,فسنجمع بينهم في Patterm وهو Builder Design Pattern.
    لنعيد كتابة constructor بإستخدام نفس المثال
    public class Player { private String name ; private String team ; private double height ; private int salary ; private String phone ; private String twitterAccount ; public static class Builder { private final String name ; private final String team ; private double height = 0; private int salary = 0; private String phone = ""; private String twitterAccount = ""; public Builder(String name, String team) { this.name = name; this.team = team; } public Builder height(double height) { this.height = height; return this ; } public Builder salary(int salary) { this.salary = salary; return this ; } public Builder phone(String phone) { this.phone = phone; return this ; } public Builder twitterAccount(String twitterAccount) { this.twitterAccount = twitterAccount; return this ; } public Player build(){ return new Player(this); } } public Player(Builder builder) { name = builder.name; team = builder.team; height = builder.height; salary = builder.salary;; phone = builder.phone;; twitterAccount = builder.twitterAccount; } } في البداية قمنا ببناء inner class  سميناه Builder حيث سنقوم بداخله ببناء Object الخاص بنا وبعد ذلك نرجعه عن طريق دالة build التي تقوم بعمل return ل object الذي قمنا ببناءه, نبدأ بالمتغيرات الأساسية في Object وهي التي كانت final ولا تأخذ قيم افتراضية, ثم الاختيارية التي قد نستخدمها فنستدعي method الخاصة بها, أو لا نستخدمها فنسند فيه القيم الافتراضية, فيكون شكل client كالتالي
    Player player = new Player.Builder("Aziz", "Android") .height(10.2) .phone("0555555555") .salary(100) .build(); كما نلاحظ قمنا بكتابة client سهل القراءة وحتى الكتابة, ومرن وبسيط جدا.
    اذا ف Builder Pattern خيار جيد جداً حينما يكون عدد Parameters ليس بالقليل ويكون فيه عدد من Parameters اختيارية
     
    المراجع ومصادر :
    Effective Java (2nd Edition)
    https://sourcemaking.com/design_patterns/builder
    http://www.blackwasp.co.uk/gofpatterns.aspx
    مستوى المقال: محترف
  3. بسم الله الرحمن الرحيم
    نكمل ما بدأنا به في شرح design pattern الأكثر استخداما في بيئة Android
    اليوم بإذن الله سيكون حديثنا عن مفهوم Dependency Injection.
    تعريف wikipedia
    فما هو Inversion of Control ؟ التعريف من wikipedia  أيضا
    قد تكون عملية الترجمة غير مجدية أو أن التعريفات ليست واضحة عموما بإذن الله سنفصل الموضوع تفصيلا بسيطاً يجعله واضحا بإذن الله.
    ببساطة مفهوما Dependency Injection و Inversion of Control (IoC) بدون الخوض في التفاصيل تعنى بحذف dependencies من code
    ماذا نعني ب dependencies (الاعتمادية) ؟
    خذ هذا المثال
    public class MSWord { private ErrorCorrection corrector; public MSWord() { this.corrector = new ErrorCorrection(); } } نلاحظ أنه لكي أقوم بإنشاء Object من class MSWrod فأنا مضطر لإنشاء Object من  class ErrorCorrection ونقطة الاعتمادية هنا هي إنشاء Object
    لكي تقوم بتنفيذ Dependency Injection لابد أن تعمل Inject (حقن) object بحيث يأتي إلى class ك parameter  مبني, فتتم عملية الإسناد فقط
    بالمثال يتضح المقال, فهذه مثال ننفذ فيه Dependency Injection على نفس code السابق
    public class MSWord { private ErrorCorrection corrector; public MSWord(ErrorCorrection corrector) { this.corrector = corrector; } } ففي Main أو مكان تنفيذ code ستقوم بالتالي
    public static void main(String[] args) { ErrorCorrection corrector = new ErrorCorrection() MSWord word = new MSWord(corrector); } جميل جدا, الأمر نفسه بتمرير dependencies ك parameter سواء كان في constructor أو method, يأتي السؤال الأهم لماذا أستخدم هذا pattern ؟
    لنفترض أن لدينا class A ولديه subclass B ويحتاج object من class C
    public class C { String s ; C(String s){ this.s = s ; } } public class A { private C c ; A(String s){ this.c = new C(s); } } public class B extends A{ B(String s){ super(s); } } جميل, في حال تم تغيير constructor في class C فأنت مضطر لتغيير constructor في class A وجميع من يرث منه, فلو قلنا فرضاً أننا قررنا إضافة Strimg أخر لدى C
    public class C { String s ,s1; C(String s ,String s1 ){ this.s = s ; this.s1 = s1 ; } } public class A { private C c ; A(String s,String s1){ this.c = new C(s,s1); } } public class B extends A{ B(String s,String s1){ super(s,s1); } } فكما ترى اضطررنا لتغيير جميع classes نظرا لأننا غيرنا في class يعتمدون عليه, لكن ماذا لو طبقنا Dependency Injection على هؤلاء classes
    public class C { String s ; C(String s){ this.s = s ; } } public class A { private C c ; A(C c){ this.c = c ; } } public class B extends A{ B(C c){ super(c); } } لنغير في C و constructor الخاص بها ونرى ماذا يحدث.
    public class C { String s ,s1; C(String s,String s1){ this.s = s ; this.s1 = s1 ; } } public class A { private C c ; A(C c){ this.c = c ; } } public class B extends A{ B(C c){ super(c); } } نلاحظ الفائدة Dependency Injection حيث أن التغيير تم في مكان واحد فقط.
    من فوائد Dependency Injection
    له فوائد جدا كثيرة ستلاحظها أثناء الكتابة أو حين تقرأ عنه ومنها
    - قابلية التعديل - maintainability
    - قابلية الاختبار -  testability
    - قابلية الاستفادة من نفس code عوضاً عن إعادة كتابته - reusability
    - بالإضافة إلى أنه يقلل من coupling في code
     
    للاستزادة هنا بعض المراجع التي قرأت منها وفيها الكثير من المعلومات التي فضلت عدم إيرادها لجعل الموضوع أكثر بساطة
    https://en.wikipedia.org/wiki/Dependency_injection
    http://frogermcs.github.io/dependency-injection-with-dagger-2-introdution-to-di/
    http://stackoverflow.com/questions/3058/what-is-inversion-of-control
    مستوى المقال: محترف
  4. بسم الله الرحمن الرحيم
    بإذن الله ستكون هذه المقالة بداية لسلسلة من المقالات المتعلقة ب Design Patterns الأكثر أستخداما في بيئة Android.
    ونستهل هذه السلسلة ب Observer Design Pattern أو ما يسمى ب Publish-Subscribe (Pub-Sub) Pattern.
    في تعريف هذا Pattern في كتاب GoF :
    ولتبسيط التعريف نقول :
    عندما تريد تنبيه أو تحديث مجموعة objects عن حدوث تغيير في object أخر
     
    جميل جداً, دعنا نضرب مثالاً قبل أن نبدأ.
    - لدينا مدونة تنشر مقالات.
    - قمت أنت بالأشتراك في قائمة تقوم بتنبيهك في حال صدرت أي مقالة.
    - لم تعد مهتما بالمجال الذي تكتب هذه المدونة عنه, قمت بإلغاء الإشتراك منها.
    - قام مجموعة من أصدقائك بالإشتراك وإلغاء الإشتراك.
     
    المثال السابق هو ملخص لما للكود الذي سنقوم بكتابته في حال فهمك إياه فأنت قطعت شوط كبير في فهم هذا Design Pattern
    .
    بداية هذا هو UML الخاص بالكود الذي سنكتبه الان, سيتضح أكثر بعد كتابه الكود.

    جميل الان لنبدأ في كتابة الكود
    في البداية لدينا two interfaces الأول هو subjuct أو يمكنك أن تسميه puplisher والثاني observer أو يمكنك أن تسميه subscriber - إذا لم تكن تستخدم intrtfaces أثناء كتابتك لبرامجك فقد وضعت مرجع قد يفيدك في نهاية المقالة لمعرفة أهمية وأليه استخدام interfaces-
    public interface Subject { void addObserver(Observer o); void removeObserver(Observer o); void notifyObservers(); public void setUpdate(String article); public String getUpdate(); } public interface Observer { void Update (); } ليس هناك الكثير من التفاصيل في إنشاء هذين interfaces لكن سنبدأ في التعليق عند مرحلة  implementation
    دعنا نبدأ ب subjuct ونسوي له implementation في class Publisher
    public class Publisher implements Subject{ private List <Observer> observers ; String article; public Publisher() { observers = new ArrayList<>(); } @Override public void addObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { observers.remove(o); } @Override public void notifyObservers() { for(Observer ob : observers) ob.Update(); } @Override public String getUpdate() { return article; } @Override public void setUpdate(String article) { this.article = article ; notifyObservers(); } } في البداية قمنا بإنشاء List نستطيع أن نسميها قائمة المشتركين في هذا class الذي أفترضنا أنه مدونة لنشر المقالات, ومتغير String والذي هو عبارة عن المقالة التي نريد تنبيه متابعينا حال صدورها.
    لدينا ثلاث functions رئيسية لا يكاد يخلو Observer Design Pattern منها وهي :
         addObserver : ﻷضافة متابع جديد لهذا class أو كما يحلو لنا أن نسميه المدون
        removeObserver : لحذف متابع
         notifyObservers : لتنبيه المتابعين ونشر المقالة لهم ,وقد تختلف تصرفاتهم عندما يأتيهم التنبيه منهم يبدأ بقر ائتها  أو إهمالهما أو حفظها لديه لغرض معين أو غير ذلك.
    لننتقل الان ل classes التي قامت بعمل implementation ل Observer وهم لا يختلفون كثيرا في implementation
    public class Reader implements Observer{ private String article ; private Subject sub ; public Reader(Subject blog) { article = "" ; sub = blog ; sub.addObserver(this); } @Override public void Update() { article = sub.getUpdate(); System.out.println("You :"+article); } } public class Reader implements Observer{ private String article ; private Subject sub ; public Reader(Subject blog) { article = "" ; sub = blog ; sub.addObserver(this); } @Override public void Update() { article = sub.getUpdate(); System.out.println("You :"+article); } } class reader والذي افترضت حين بدأت بكتابة المقالة أنه أنت , وclass الأخر هو Friend والذي افترضت أنه صديقك
    كما تلاحظون في كلا classes  قمنا بعمل Override ل update  تحضر المقالة و تقرأها, وفي داخل Constructor قمنا بإنشاء المتغيرات الخاصة بنا والانضمام إلى List المتابعين الخاصين بالمدونة
    public class PupSub { public static void main(String[] args) { // TODO code application logic here Publisher pup = new Publisher(); new Reader(pup); new Friend(pup); pup.setUpdate("Art1"); pup.setUpdate("Art2"); pup.setUpdate("Art3"); } } في البداية قمنا بإنشاء قائمة المتابعين الخاصة بالمدونة وكانت فارغة قم أنشأنا متابع من Reader class والذي سبق وافترضنا أنه أنت, ثم Friend class والذي هو صديقك.
    كلاكما متابع لهذه المدونة والمدون قد وضعكما في قائمته ويقوم بإخباركم عن كل جديد في هذه المدونة فور وصوله وأنتما تقومان بقراءة ما يأتيكما فور ما يأتي.
    ثم نشر المدون ثلاث تدوينات عبر setUpdate التي تستدعي notifyObservers ثم تقوم هذه function باستدعاء Update الخاصة بكل class من المتابعين ويقومون بدورهم بتحديث
    التدوينات التي لديهم عن طريق استداعاء getUpdate الخاصة بالمدون.
     
    قد تجد صعوبة في فهم هذا Pattern وغيره في المرة الأولى وهذا طبيعي. عليك تطبيقة وفهم أجزاءه وبعد ذلك سيتضح لك.
    وأخيرا, لماذا أستخدم Observer Design Pattern ؟
    Observer Design Pattern يقلل من التداخل في الكود-Low Coupling- وهذا سيسهل عليك في حال رغبت في إضافة classes أو إزالتها, فجميع classes تعمل بشكل مستقل عن بعضها .
     
    المراجع:
    - http://informatic-ar.com/ال-coupling-وال-cohesion-في-تصميم-البرمجيات/
    - https://sourcemaking.com/design_patterns/observer
    - Head First Design Patterns
    - البرمجة باستخدام Interfaces
    مستوى المقال: محترف
  5. بسم الله الرحمن الرحيم
    نكمل ما بدأناه في الحديث عن design pattern التي يكثر استخدامها في بيئة android
    اليوم سيكون حديثنا عن Singleton
    هذا pattern يصنف ضمن Creational Patterns والتي تهتم بطرق إنشاء objct أو مجموعة objects والعلاقات التي بينها في حال كان لدينا أكثر من object.
    ونبدأ بتعريف هذا Pattern من كتاب GoF :
    إذا في Singleton  يجعلك متأكدا من أن class الذي بنيته باستخدام هذا pattern انشأ منه object اوحد فقط .
    وأول ما يخطر في بالك في حال كنت جديدا على هذا النمط, لماذا object اوحد فقط ؟ سيكون الجواب في نهاية المقالة بإذن الله
    بداية سنبدأ بكتابة مثال بسيط على  Singleton pattern بلغة java
    public class Singleton { private static Singleton singleton = null ; private Singleton() {} public static Singleton getSingleton() { if (singleton == null) singleton = new Singleton(); return singleton; } } يبدو واضحا من الوهلة الأولى أن class انف الذكر لا يمكن إنشاء أكثر من object منه.
    في private Constructor لا تقوم بإنشاء أي object كما أن data member التي لديك static لكنها private بمعنى لديك static data member لا تستطيع الوصول إليه إلا عن طريق method داخل class
    وهذه method تقوم بالتأكد فيما إذا كان لديك object تم إنشاؤه, والذي لن ينشأ غيره.
    لكن في الحقيقة لو استخدمنا نفس هذا implementation في multithreading فقد ينشأ أكثر من object, فلمنع هذا حدوث هذه المشكلة لدينا أكثر من حل,فمثلا نستخدم synchronized keyword  والتي
    ستعمل فقط مع thread واحده في نفس الوقت, لتفادي إنشاء أكثر من instance - وقد لا يكون أفضل حل-
    قدد تتعدد طرق implementation ولكن تشترك في شيء واحد وهو أنه لا يمكن أنشاء أكثر من object من هذا class
    طيب جميل جداً لان لنطبق هذا pattern على Android
    سنقوم بالتالي بناء دالة تتأكد من حالة network وترجع true في حال كان هناك اتصال وError في حال لم يكن.
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); if(info != null && info.isConnectedOrConnecting() && cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting()){ //your code } ستكرر هذه code في كل مكان تنوي فيه التحقق من حالة الشبكة,, وعندما تكرر code فيعتبر إشكال في تصميمه.
    إذا ماذا سنفعل ؟
    سنقوم بالتالي بناء App class , وهو class على مستوى التطبيق بمعنى يمكن لأي جزء من تطبيق أن يصل إليه, كيف ؟
    يكون لدينا class فيه static method لكل object لا نحتاج لتكراره في code ومن ثم نستدعيه عن طريق class .
    مثال
    public static boolean NetworkState(Context context){ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); return info != null && info.isConnectedOrConnecting() && cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting(); } في هذه الحالة يمكننا التحقق من حالة network بهذه الطريقة
    if(Application.NetworkState(Context context)){ //your code } وهذا يمنحنا ميزة سهولة التعديل maintainable  في حال أردنا تغيير طريقة عمل function كإظهار تنبيه معين.
    وقس على ذلك من المزايا , كما أن هذا المثال يمكن استخدامه مع عدد كبير من الحالات كإنشاء object من مكتبة retrofit والوصول له من أي مكان على مسوى التطبيق.
     
    لا ينبغي عمل subclass ل Singleton  class حيث سيتوجب عليك جعل Constructor public وبعد هذا التغيير لم يعد class يسمى Singleton حيث يمكن إنشاء instance منه.
    بالإضافة إلى أنك قد تكون جعلت static data member مما يعني أن subclass سيكون مشترك مع superclass في نفس data member وقد يؤدي إلى نتائج غير مرغوب فيها غالبا.
     
    نجيب على التساؤل الذي طرحناه في بداية المقالة لماذا object اوحد فقط ؟
    أتضح ولو بشكل جزئي من الأمثلة التي ذكرناها في بداية المقالة بعض فوائد Singleton, وهو أنه ستمر بك بعض الحالات لا تريد فيها أكثر من object وحيد تتعامل معه ومن هذه الحالات
    Toast كما ذكرنا ,و thread pools و caches و logging والقائمة تطول, فمتى ما رأيت أن class فيه static class or data member هي التي تحتاجها فقط فسيكون Singleton حل مناسب لك.
     
    المراجع:
    Head First Design Patterns
    http://www.javaworld.com/article/2073352/core-java/simply-singleton.html
    http://www.blackwasp.co.uk/gofpatterns.aspx
    http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples
    مستوى المقال: محترف
  6. يوجد العديد من التطبيقات التي تحتوي على ميزة مشاركة المواقع القريبة من المستخدم ولعل اكبر مثال على ذلك هو تطبيق واتس اب فهو يستخدم تقريباً نفس الفكرة المقدمة من قوقل وهي Place Picke وتتيح لك هذه الميزة السرعة في تحديد الاماكن القريبة من المستخدم بدون استخدام تقنيات مثل NearBy والتعقيدات واستهدام الخرايط .
    في هذا الدرس ستتعرف على طريقة مشاركة الاماكن بشكل سريع واسطر قليله جداً.
    بداية كل بداية في استخدام خدمات قوقل هو الحصول على API KEY  .
    الحصول على API KEY :
    ادخل الى هذه الرابط https://console.developers.google.com ثم قم باتباع الشرح الموجود اسفل الفيديو :
    الحصول على SHA1
    اضافة خدمات قوقل للتطبيق :
    في ملف gradel.bulide قم بكتابة هذا السطر المضلل :
    dependencies { compile 'com.google.android.gms:play-services-location:8.4.0' } الان الانتقال الى Activity :
    قم باضافة Button او اي شئ تريد من المستخدم اذا قام بالضغط عليه ان يقوم بنقله الى شاشة اختيار مكان قريب، وفي امر الضغط لهذا Button نقوم بكتابة هذا السطرين :
    PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder(); try { startActivityForResult(builder.build(MainActivity.this), PLACE_PICKER_REQUEST); } catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException e) { e.printStackTrace(); } الان اذا قام المستخدم بالضغط على Button سيتم نقله الى شاشة اختيار مكان قريب .
    لكن الان كيف اقوم باعادة النتائج اذا قام المستخدم بالاختيار  .
    اعادة النتائج :
    نحتاج الان اضافة دالة onActivityresult() لاعادة البيانات التي قام المستخدم باختيارها .
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PLACE_PICKER_REQUEST) { if (resultCode == RESULT_OK) { Place place = PlacePicker.getPlace(data, this); String place_name = String.format(getString(R.string.place_name), place.getName()); String place_addrress = String.format(getString(R.string.place_adress), place.getAddress()); name.setText(place_name); address.setText(place_addrress); } } } عند اعادة النتائج سنلاحظ استخدامنا لـPlace حيث سيحتوي على جميع بيانات الموقع:
    Place place = PlacePicker.getPlace(data, this); اهم البيانات التي يحتوي عليها Opject Place :
    لم اتطرق لبعض الدوال ،، فقط المهم منها الدالة وظيفتها getId اعادة رقم الموقع وهو رقم فريد getLatLng اعادة خطوط الطول والعرض للموقع الحالي getName اعادة اسم الموقع الحالي getPhoneNumber اعادة رقم الهاتف للموقع الحالي اذا كام متوفر getPlaceTypes اعادة نوع الموقع "مطعم او صراف .. الخ" النتيجة النهائية :
     

    مستوى المقال: متوسط
  7. كثير من مطوري الاندرويد يقومون باستخدام AsyncTask وخاصة عندما يريدون تنفيذ بعض الاكواد في thread منفصل, ولكن كثير منهم يتعامل مع هذا الكلاس بطريقة خاطئة ودون فهم لدورة حياة الاندرويد وما الذي يحدث بالضبط في الخلفية, في هذه المقالة سنوضح الخطأ الشائع وكيف تقوم بمعالجة المشكلة.
    الاستخدام الخاطئ
    الطريقة الشائعة والتي تجدها في معظم المواقع والتي ستجدها بالتاكيد في معظم مشاريع مطوري الاندرويد هي كالتالي:
    public class MainActivity extends Activity {     @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);   }     // Somewhere the AsyncTask is started     public class MyAsyncTask extends AsyncTask<Void, Void, String> {       @Override protected String doInBackground(Void... params) {       // Do work       return result;     }       @Override protected void onPostExecute(String result) {       Log.d("MyAsyncTask", "Received result: " + result);     }   } } المشكلة بالكود هي ان كلاس  AsyncTask مضمن بداخل الـ Activity وبالتالي اي تغيير في حالة الـ Activity والتي قامت باستدعاء الـ AsyncTask الموجود بداخلها قد يقتل عمل الـ AsyncTask, ولكن لن يتم ازالة الـ Activity من الذاكرة الا في حالة انتهاء الـ AsyncTask.
    الان لتتخيل معي المثال التالي: لدي اكتفتي واحدة وبداخلها AsyncTask وفي كل مرة اقوم باستدعاء الاكتفتي فانا استدعي AsyncTask جديد واي تغيير في حالة الاكتفتي ربما استدعي AsyncTask اخر, وكل واحد من الـ AsyncTask لديه عملية يجب عليه ان ينفذها قبل ان يُقتل وقبل ان يسمح للـ Activity بان تزال من الذاكرة.
    ماسيحدث بالمثال بالاعلى هو مشكلتين, الاولى هي مشكلة في الذاكرة memory issues والثانية هي انك ستفقد العمليات التي قام الـ AsyncTask بتنفيذها وستقوم بتكرار العملية اكثر من مرة.
    معالجة المشكلة
    لمعالجة المشكلة بالاعلى فالافضل ان تقوم باستخدام مبدأ الـ event bus وطريقة تنفيذه كالتالي:
    نقل الـ AsyncTask الى كلاس منفصل عن الـ  Activity. انشاء كلاس جديد يقوم بتخزين ناتج  AsyncTask عند اكتماله. ربط الـ الـAsyncTask بالـ Activity الخاصة بك عن طريق الـ bus. لذلك سنقوم بانشاء كلاس جديد تحت مبدأ الـ Singleton ويكون كالتالي:
     public class MyBus { private static final Bus BUS = new Bus();  public static Bus getInstance() { return BUS;    } } ولنفترض ان الـ AsyncTask سيقوم بارجاع String فقط عن اكتمال عمله, لذلك سنقوم بانشاء  كلاس جديد وليكن اسمه AsyncTaskResultEvent :
    public class AsyncTaskResultEvent { private String result; public AsyncTaskResultEvent(String result) { this.result = result; } public String getResult() { return result; } } نقوم بانشاء كلاس الـ AsyncTask والذي سيقوم بتنفيذ اي كود تريده:
    public class MyAsyncTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... params) { Random random = newRandom(); final long sleep = random.nextInt(10); try{ Thread.sleep(sleep * 1000); } catch(InterruptedException e) { e.printStackTrace(); } return"Slept for "+ sleep + " seconds"; } @Override protected void onPostExecute(String result) { MyBus.getInstance().post(newAsyncTaskResultEvent(result)); } } اخيرا سنقوم بربط الـ AsyncTask  مع الـ Activity ولكن يجب عليك بالغاء الربط بينهم في ميثود onDestroy حتى لانقع في نفس المشكلة من جديد:
    public class MainActivity extends Activity {   @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);     findViewById(R.id.button).setOnClickListener(newView.OnClickListener() {       @OverridepublicvoidonClick(View v) {         newMyAsyncTask().execute();       }     });     MyBus.getInstance().register(this);   }   @Override protected void onDestroy() {     MyBus.getInstance().unregister(this);     super.onDestroy();   }   @Subscribe public void onAsyncTaskResult(AsyncTaskResultEvent event) {     Toast.makeText(this, event.getResult(), Toast.LENGTH_LONG).show();   } } اخيراً
    هذه الطريقة ليست محصورة مع الـ AsyncTask بل تستطيع استخدامها مع اي امر اخر, فعلى سبيل المثال الـ services لديه نفس المشكلة اذا استخدمتها بطريقة خاطئة وحلها هو باستخدام الـ event bus.
    مستوى المقال: متوسط
  8. لا يخفى علينا جميعا أن التاريخ الهجري هو التاريخ المعتمد والرسمي في تعاملاتنا الحكومية وهو بداية هجرة النبي صلى الله عليه وسلم وقد نحتاج لاضافته في احد مشاريعنا لتحديد المواعيد أو شي اخر.
    ولكن لايوجد دعم رسمي للتاريخ الهجري في جافا القديمة ولكن تم ذلك في الإصدار الثامن الذي لم يعتمد في الاندرويد الا لبعض الapi .
    لذلك سنقوم باستخدام مكتبة JodaTime وتعتبر من أقوى المكتبات واسهلها في التعامل مع التواريخ والأوقات بجميع الصيغ.
    سنقوم بإذن الله في هذا الدرس بإنشاء تطبيق بسيط كما يظهر في الفيديو بالأسفل لتحويل التاريخ من ميلادي إلى هجري والعكس وأيضا حساب الايام المتبقية على رمضان .
    المتطلبات :
    ١ - كوب قهوة 
    ٢ - اندرويد ستديو ويفضل ان تقوم بالتحديث الي الاصدار 2 لتتمتع بالمحاكي السريع  انشئ مشروع جديد: بداية كل بداية وثورة تقنية هو انشاء مشروع جديد قم بتسمية المشروع كما تشاء وبعد ذلك قم باختيار Empty Activity .
    قم باضافة هذا السطر في gradle.builde وهو خاص بمكتبة JodaTime.
    dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' compile 'joda-time:joda-time:2.9.3' } تصميم واجهة التطبيق :
    سنقوم بتصميم واجهة بسيطة باستخدام Material Desing لعرض :
    - عرض تاريخ اليوم بالهجري.
    - المتبقي على شهر رمضان ،بعض المناسبات .
    - تحويل التاريخ من الميلادي للهجري.
    الشفرة البرمجية الخاصة بالواجهه :
    <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.ahmed.hijri.MainActivity"> <android.support.v7.widget.GridLayout android:id="@+id/choice_grid" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:padding="4dp" app:alignmentMode="alignBounds" app:columnCount="2" app:rowOrderPreserved="false" app:useDefaultMargins="true"> <android.support.v7.widget.CardView android:layout_width="0dp" android:layout_height="150dp" android:gravity="center" app:layout_columnWeight="1" app:layout_gravity="fill_horizontal"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorAccent" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="ميلادي" android:textColor="@color/md_white_1000" android:textSize="18sp" android:textStyle="bold" /> </LinearLayout> <TextView android:id="@+id/gey_date" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textColor="@color/md_grey_500" android:textSize="24sp" android:textStyle="bold" tools:text="April 20 2016" /> </LinearLayout> </android.support.v7.widget.CardView> <android.support.v7.widget.CardView android:layout_width="0dp" android:layout_height="150dp" android:gravity="center" app:layout_columnWeight="1" app:layout_gravity="fill_horizontal"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorAccent" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="هجري" android:textColor="@color/md_white_1000" android:textSize="18sp" android:textStyle="bold" /> </LinearLayout> <TextView android:id="@+id/hijri_date" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textColor="@color/md_grey_500" android:textSize="24sp" android:textStyle="bold" tools:text="April 20 2016" /> </LinearLayout> </android.support.v7.widget.CardView> <android.support.v7.widget.CardView android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:text="Tile3" app:layout_columnSpan="2" app:layout_columnWeight="1" app:layout_gravity="fill_horizontal" app:layout_rowWeight="1"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorAccent" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="متبقي على رمضان" android:textColor="@color/md_white_1000" android:textSize="18sp" android:textStyle="bold" /> </LinearLayout> <TextView android:id="@+id/ramadan_date" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/tv_heading" android:layout_marginTop="20dp" android:gravity="center" android:text="345" android:textColor="@color/md_grey_500" android:textSize="67sp" android:textStyle="bold" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/tv_heading" android:layout_marginBottom="20dp" android:gravity="center" android:text="يوم" android:textColor="@color/md_grey_500" android:textSize="17sp" android:textStyle="bold" /> </LinearLayout> </android.support.v7.widget.CardView> </android.support.v7.widget.GridLayout> <android.support.design.widget.FloatingActionButton android:id="@+id/action" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="15dp" android:src="@drawable/ic_date_range_black_24dp" /> </FrameLayout> كتابة الشفرة البرمجية للـActivity :
    قمنا سابقاً بانشاء Activity فارغ والان سنقوم بكتابة الاوامر الخاصة بمكتبة Joda وشرحها بشكل ميسر وبسيط . DateTime.now() هنا لعرض التاريخ الميلادي بصيغه كاملة مع الوقت.
    لكن لو فرضاً اردنا تخصيص الوقت بصيغه معينه تناسب التطبيق الخاص بنا . مثلا اريد التاريخ بهذه الصيغه :
    "الجمعة ٢٢ ابريل ٢٠١٦ ميلادي"
    ركز معي في الجدول التالي وقم بتحديد ماذا تريد ان تعرض :
    الرمز   شرح القيمة المستردة مثال G التقويم الحالي "هجري ، ميلادي ، الخ" نص AH,Ad C القرن الحالي رقم ٢٠ Y السنة الحالية في القرن سنة 1437 x نحتاجه اذا صادف ان السنة بدأت من نصف الاسبوع سنة 1437 w رقم الاسبوع في weekyear "المشروحة في الاعلى" رقم ٢٧ e رقم اليوم في الاسبوع رقم ٢ E اسم اليوم في الاسبوع نص الاثنين y  سنة  رقم  1437 D  رقم اليوم في السنة  رقم  ١١٤ M  رقم الشهر في السنة رقم   ٩ d  رقم اليوم في الشهر  رقم  ١١ a لمعرفة الوقت    نص  ص او م K  الساعة في اليوم (٠-١١)  رقم  ٠ h  رقم الساعة في نصف اليوم (١ - ١٢ )  رقم  ١٢ H  الساعة في اليوم ( ٠ - ٢٣ )  رقم  ١٣ k  الساعة صحيحة في اليوم ( ١ - ٢٤ )  رقم  ٢٤ m  الدقيقة في الساعة  رقم  ٣٠ s  الثانية في الدقيقة  رقم  ٥٥ S جزء من الثانية    رقم  ٤٥٦ z المنطقة الزمنية  نص  PST Z  المنطقة الزمنية بحسب ID  منطقة زمنية  SA/Ryadth
    الان ومن خلال اطلاعك على الجدول ستقوم بتحديد الصيغة وستكون بهذ الشكل :
    DateTime.now().toString("E dd MMMM YYYY G") حددت اليوم من  الاسبوع ثم اليوم من الشهر واسم الشهر وكذلك السنة وبعد ذلك اضفت نوع التقويم
    عرض التاريخ الهجري الحالي :
    الان درسنا يقوم على هذه النقطة وهو عرض التاريخ الهجري وسيكون بالاعتماد على التاريخ الميلادي الحالي :  DateTime dtIslamic = DateTime.now().withChronology(IslamicChronology.getInstance()); بهذا السطر فقط نستطيع عرض التاريخ الهجري وستقوم انت اخي المتابع معي بكتابة الصيغة التي تعجبك  . تحويل التواريخ :
    - من ميلادي الى هجري : DateTime date = new DateTime(year, monthOfYear + 1, dayOfMonth, , , ); DateTime dtIslamic = date.withChronology(IslamicChronology.getInstance()); result.setText(dtIslamic.toString("E dd MMMM yyyy G")); - من هجري الى ميلادي : بعض التلميحات لاستخدام JodaTime :
    - عرض عدد الايام المتبقية بين تاريخين : Days.daysBetween(new LocalDate(DateTime.now()), new LocalDate(dtIso)).getDays(); في الكود السابق كتبت اولاً التاريخ الحالي الذي ساقوم بالحساب ابتداءً منه وبعد ذلك كتبت تاريخ النهاية وستقوم المكتبة بحساب عدد الايام.
    ستجد في المثال المرفق طريقة عرض عدد الايام المتبقية على الشهر الفضيل عسى ان يبلغنا الله لافاقدين ولا مفقودين.
    قيس على المثال السابق "الشهور والاسابيع والايام والدقائق والثواني "
    - تحديد تاريخ معين والمنطقة الزمنية :
    تستطيع تحديد التاريخ والوقت والمنطقة الزمنية باستخدام المكتبة وتخصيصها. DateTime cestTime = new DateTime(2013, 6, 10, 2, , DateTimeZone.forID("Europe/Berlin")); - التحقق من هل التاريخ قبل او بعد التاريخ الحالي :
    توجد دالة تدعى isBefore وهي للتاكد هل التاريخ هذا قبل ام بعد وتستطيع مثلا استخدامها اذا اردت من المستخدم تحديد تاريخ مستقبلي مثلاً. التطبيق :
    https://github.com/ahmedoid/Hijri ختاماً :
    اتمنى اني وفقت في ايصال المعلومة بشكل بسيط وسلس وان شاء الله القادم افضل
    مستوى المقال: متوسط

عالم البرمجة

عالم البرمجة مقالات برمجة و دورات مجانية لإحتراف البرمجة هدفنا تبسيط البرمجة ونشرها بيد الكل بشكل ممتع ومتطور ومحدث بإستمرار لمواكبة جديد تطورات البرمجة الحديثة و المتقدمة بدون مقابل