שרת proxy לממשקי ה-API החדשים

בשיעור הזה נסביר איך ליצור מחלקת משנה של המחלקות המופשטות CompatTab ו-TabHelper ואיך להשתמש בממשקי API חדשים. האפליקציה יכולה להשתמש בהטמעה הזו במכשירים שמופעלת בהם גרסת פלטפורמה שתומכת בהן.

הטמעה של כרטיסיות באמצעות ממשקי API חדשים

המחלקות הקונקרטיות של CompatTab ו-TabHelper שמשתמשות בממשקי API חדשים יותר הן הטמעה של proxy. מכיוון שהמחלקות המופשטות שהוגדרו בשיעור הקודם משקפות את ממשקי ה-API החדשים (מבנה המחלקה, חתימות של שיטות וכו'), המחלקות הקונקרטיות שמשתמשות בממשקי ה-API החדשים האלה משמשות כפרוקסי לקריאות לשיטות ולתוצאות שלהן.

אתם יכולים להשתמש ישירות בממשקי API חדשים יותר במחלקות הקונקרטיות האלה – ולא לגרום לקריסה במכשירים קודמים – בגלל טעינת מחלקות עצלה. הכיתות נטענות ועוברות אתחול בגישה הראשונה – יצירת מופע של הכיתה או גישה לאחד מהשדות או השיטות הסטטיים שלה בפעם הראשונה. לכן, כל עוד לא יוצרים מופעים של ההטמעות הספציפיות ל-Honeycomb במכשירים עם גרסאות קודמות של Android, מכונת ה-VM של Dalvik לא תזרוק חריגות מסוג VerifyError.

מומלץ להשתמש במוסכמת שמות טובה להטמעה הזו, ולהוסיף את רמת ה-API או את שם הקוד של גרסת הפלטפורמה שמתאימים לממשקי ה-API שנדרשים על ידי המחלקות הקונקרטיות. לדוגמה, אפשר לספק את ההטמעה של הכרטיסייה המקורית באמצעות המחלקות CompatTabHoneycomb ו-TabHelperHoneycomb, כי הן מסתמכות על ממשקי API שזמינים ב-Android 3.0 (רמת API‏ 11) ואילך.

תרשים מחלקות להטמעה של כרטיסיות ב-Honeycomb.
איור 1. דיאגרמת מחלקות להטמעה של כרטיסיות ב-Honeycomb.

הטמעה של CompatTabHoneycomb

CompatTabHoneycomb הוא ההטמעה של המחלקה המופשטת CompatTab ש-TabHelperHoneycomb משתמש בה כדי להפנות לכרטיסיות בודדות. ‫CompatTabHoneycomb מעביר את כל הקריאות לשיטות לאובייקט ActionBar.Tab שהוא מכיל.

מתחילים להטמיע את CompatTabHoneycomb באמצעות ממשקי ה-API החדשים של ActionBar.Tab:

Kotlin

class CompatTabHoneycomb internal constructor(val activity: Activity, tag: String) :
        CompatTab(tag) {
    ...
    // The native tab object that this CompatTab acts as a proxy for.
    private var mTab: ActionBar.Tab =
            // Proxy to new ActionBar.newTab API
            activity.actionBar.newTab()

    override fun setText(@StringRes textId: Int): CompatTab {
        // Proxy to new ActionBar.Tab.setText API
        mTab.setText(textId)
        return this
    }

    ...
    // Do the same for other properties (icon, callback, etc.)
}

Java

public class CompatTabHoneycomb extends CompatTab {
    // The native tab object that this CompatTab acts as a proxy for.
    ActionBar.Tab mTab;
    ...

    protected CompatTabHoneycomb(FragmentActivity activity, String tag) {
        ...
        // Proxy to new ActionBar.newTab API
        mTab = activity.getActionBar().newTab();
    }

    public CompatTab setText(int resId) {
        // Proxy to new ActionBar.Tab.setText API
        mTab.setText(resId);
        return this;
    }

    ...
    // Do the same for other properties (icon, callback, etc.)
}

הטמעה של TabHelperHoneycomb

TabHelperHoneycomb הוא ההטמעה של המחלקה המופשטת TabHelper שמעבירה קריאות לשיטות אל ActionBar בפועל, שמתקבל מ-Activity שכלול בה.

מטמיעים את TabHelperHoneycomb, מעבירים את הקריאות לשיטות ל-API של ActionBar:

Kotlin

class TabHelperHoneycomb internal constructor(activity: FragmentActivity) : TabHelper(activity) {

    private var mActionBar: ActionBar? = null

    override fun setUp() {
        mActionBar = mActionBar ?: mActivity.actionBar.apply {
            navigationMode = ActionBar.NAVIGATION_MODE_TABS
        }
    }

    override fun addTab(tab: CompatTab) {
        // Tab is a CompatTabHoneycomb instance, so its
        // native tab object is an ActionBar.Tab.
        mActionBar?.addTab(tab.getTab() as ActionBar.Tab)
    }
}

Java

public class TabHelperHoneycomb extends TabHelper {
    ActionBar actionBar;
    ...

    protected void setUp() {
        if (actionBar == null) {
            actionBar = activity.getActionBar();
            actionBar.setNavigationMode(
                    ActionBar.NAVIGATION_MODE_TABS);
        }
    }

    public void addTab(CompatTab tab) {
        ...
        // Tab is a CompatTabHoneycomb instance, so its
        // native tab object is an ActionBar.Tab.
        actionBar.addTab((ActionBar.Tab) tab.getTab());
    }

    // The other important method, newTab() is part of
    // the base implementation.
}

כדאי לקרוא גם על