تنفيذ مكتبة Java SDK

يحتوي نظام Android الأساسي على عدد كبير من مكتبات Java المشتركة التي يمكن تضمينها اختياريًا في مسار فئة التطبيقات باستخدام علامة <uses-library> في بيان التطبيق. ترتبط التطبيقات بهذه المكتبات، لذا تعامل معها مثل بقية واجهة برمجة تطبيقات Android من حيث التوافق ومراجعة واجهة برمجة التطبيقات ودعم الأدوات. ومع ذلك، لاحظ أن معظم المكتبات لا تملك هذه الميزات.

يساعد نوع الوحدة النمطية java_sdk_library في إدارة المكتبات من هذا النوع. يمكن لمصنعي الأجهزة استخدام هذه الآلية لمكتبات Java المشتركة الخاصة بهم، للحفاظ على التوافق مع الإصدارات السابقة لواجهات برمجة التطبيقات الخاصة بهم. إذا كانت الشركات المصنعة للأجهزة تستخدم مكتبات Java المشتركة الخاصة بها من خلال علامة <uses-library> بدلاً من مسار bootclass، فيمكن لـ java_sdk_library التحقق من أن مكتبات Java هذه مستقرة لواجهة برمجة التطبيقات.

تنفذ java_sdk_library واجهات برمجة تطبيقات SDK الاختيارية للاستخدام بواسطة التطبيقات. تقوم المكتبات التي يتم تنفيذها من خلال java_sdk_library في ملف البناء الخاص بك ( Android.bp ) بتنفيذ العمليات التالية:

  • يتم إنشاء مكتبات بذرة لتشمل stubs ، stubs.system ، و stubs.test . يتم إنشاء مكتبات الجذور هذه من خلال التعرف على التعليقات التوضيحية @hide و @SystemApi و @TestApi .
  • يدير java_sdk_library ملفات مواصفات واجهة برمجة التطبيقات (مثل current.txt ) في دليل فرعي لواجهة برمجة التطبيقات. يتم فحص هذه الملفات مقابل أحدث التعليمات البرمجية للتأكد من أنها أحدث الإصدارات. إذا لم تكن كذلك، فستتلقى رسالة خطأ تشرح كيفية تحديثها. قم بمراجعة جميع تغييرات التحديث يدويًا للتأكد من مطابقتها لتوقعاتك.

    لتحديث كافة واجهات برمجة التطبيقات، استخدم m update-api . للتحقق من تحديث واجهة برمجة التطبيقات (API)، استخدم m checkapi .
  • يتم فحص ملفات مواصفات واجهة برمجة التطبيقات (API) مقابل أحدث إصدارات Android المنشورة للتأكد من أن واجهة برمجة التطبيقات (API) متوافقة مع الإصدارات السابقة مع الإصدارات السابقة. تضع وحدات java_sdk_library المقدمة كجزء من AOSP إصداراتها التي تم إصدارها مسبقًا في prebuilts/sdk/<latest number> .
  • فيما يتعلق بفحص ملفات مواصفات واجهة برمجة التطبيقات، يمكنك القيام بأحد الأمور الثلاثة التالية:
    • السماح للفحوصات بالمضي قدما. (لا تفعل أي شيء.)
    • قم بتعطيل عمليات التحقق بإضافة ما يلي إلى java_sdk_library :
      unsafe_ignore_missing_latest_api: true,
    • قم بتوفير واجهات برمجة التطبيقات الفارغة لوحدات java_sdk_library الجديدة عن طريق إنشاء ملفات نصية فارغة باسم module_name.txt في دليل version/scope/api .
  • إذا تم تثبيت مكتبة التنفيذ لوقت التشغيل، فسيتم إنشاء ملف XML وتثبيته.

كيف يعمل java_sdk_library

تقوم java_sdk_library المسماة X بإنشاء ما يلي:

  1. نسختان من مكتبة التنفيذ: مكتبة واحدة تسمى X وأخرى تسمى X.impl . تم تثبيت Library X على الجهاز. مكتبة X.impl موجودة فقط إذا كان الوصول الصريح إلى مكتبة التنفيذ مطلوبًا من خلال وحدات نمطية أخرى، مثل الاستخدام في الاختبار. لاحظ أن الوصول الصريح نادرًا ما يكون مطلوبًا.
  2. يمكن تمكين النطاقات وتعطيلها لتخصيص الوصول. (على غرار معدّلات الوصول إلى الكلمات الأساسية في Java، يوفر النطاق العام نطاقًا واسعًا من الوصول؛ ويحتوي نطاق الاختبار على واجهات برمجة التطبيقات المستخدمة في الاختبار فقط.) لكل نطاق مُمكّن، تقوم المكتبة بإنشاء ما يلي:
    • وحدة مصدر كعب الروتين (من نوع وحدة droidstubs ) - تستهلك مصدر التنفيذ وتخرج مجموعة من مصادر كعب الروتين مع ملف مواصفات API.
    • مكتبة بذرة (من نوع وحدة java_library ) - هي النسخة المترجمة من بذرة. إن libs المستخدمة لتجميع هذا ليست هي نفسها التي تم توفيرها إلى java_sdk_library ، مما يضمن عدم تسرب تفاصيل التنفيذ إلى قاعدة بيانات API.
    • إذا كنت بحاجة إلى مكتبات إضافية لتجميع كعب الروتين، فاستخدم خصائص stub_only_libs و stub_only_static_libs لتوفيرها.

إذا كانت java_sdk_library تسمى " X "، ويتم تجميعها مقابل " X "، فارجع إليها دائمًا بهذه الطريقة ولا تقم بتعديلها. سيحدد البناء مكتبة مناسبة. للتأكد من أن لديك المكتبة الأكثر ملاءمة، افحص جذورك لمعرفة ما إذا كان البناء قد أدى إلى حدوث أخطاء. قم بإجراء أي تصحيحات ضرورية باستخدام هذا التوجيه:

  • تأكد من أن لديك مكتبة مناسبة من خلال النظر إلى سطر الأوامر وفحص أي من العناصر المدرجة هناك لتحديد نطاقك:
    • النطاق واسع جدًا: تحتاج المكتبة المعتمدة إلى نطاق معين من واجهات برمجة التطبيقات. ولكنك ترى واجهات برمجة التطبيقات (APIs) المضمنة في المكتبة والتي تقع خارج هذا النطاق، مثل واجهات برمجة تطبيقات النظام المضمنة في واجهات برمجة التطبيقات العامة.
    • النطاق ضيق للغاية: لا تتمتع المكتبة المعتمدة بإمكانية الوصول إلى كافة المكتبات المطلوبة. على سبيل المثال، تحتاج المكتبة المعتمدة إلى استخدام واجهة برمجة تطبيقات النظام ولكنها تحصل على واجهة برمجة التطبيقات العامة بدلاً من ذلك. يؤدي هذا عادةً إلى حدوث خطأ في الترجمة نظرًا لأن واجهات برمجة التطبيقات المطلوبة مفقودة.
  • لإصلاح المكتبة، قم بأحد الإجراءات التالية فقط:
    • قم بتغيير sdk_version لتحديد الإصدار الذي تحتاجه. أو
    • حدد المكتبة المناسبة بشكل صريح، مثل <X>.stubs أو <X>.stubs.system .

استخدام java_sdk_library X

يتم استخدام مكتبة التنفيذ X عند الرجوع إليها من apex.java_libs . ومع ذلك، نظرًا لقيود Soong، عند الإشارة إلى المكتبة X من وحدة java_sdk_library أخرى داخل نفس مكتبة APEX، يجب استخدام X.impl بشكل صريح ، وليس المكتبة X .

عند الإشارة إلى java_sdk_library من مكان آخر، يتم استخدام مكتبة بذرة. يتم تحديد مكتبة بذرة وفقًا لإعداد خاصية sdk_version للوحدة النمطية. على سبيل المثال، الوحدة النمطية التي تحدد sdk_version: "current" تستخدم بذرة النظام العامة، بينما الوحدة النمطية التي تحدد sdk_version: "system_current" تستخدم بذرة النظام. إذا لم يتم العثور على تطابق تام، فسيتم استخدام أقرب مكتبة كعب روتين. ستوفر java_sdk_library التي توفر واجهة برمجة التطبيقات العامة فقط العناصر العامة للجميع.

بناء التدفق باستخدام مكتبة Java SDK
الشكل 1. بناء التدفق باستخدام مكتبة Java SDK

الأمثلة والمصادر

يجب أن تكون خصائص srcs و api_packages موجودة في java_sdk_library .

java_sdk_library {
        name: "com.android.future.usb.accessory",
        srcs: ["src/**/*.java"],
        api_packages: ["com.android.future.usb"],
    }

توصي AOSP (ولكنها لا تتطلب) بأن تقوم مثيلات java_sdk_library الجديدة بتمكين نطاقات واجهة برمجة التطبيقات (API) التي تريد استخدامها بشكل صريح. يمكنك أيضًا (اختياريًا) ترحيل مثيلات java_sdk_library الموجودة لتمكين نطاقات واجهة برمجة التطبيقات (API) التي ستستخدمها بشكل صريح:

java_sdk_library {
         name: "lib",
         public: {
           enabled: true,
         },
         system: {
           enabled: true,
         },
         …
    }

لتكوين مكتبة impl المستخدمة لوقت التشغيل، استخدم كافة خصائص java_library العادية، مثل hostdex و compile_dex و errorprone .

java_sdk_library {
        name: "android.test.base",

        srcs: ["src/**/*.java"],

        errorprone: {
          javacflags: ["-Xep:DepAnn:ERROR"],
        },

        hostdex: true,

        api_packages: [
            "android.test",
            "android.test.suitebuilder.annotation",
            "com.android.internal.util",
            "junit.framework",
        ],

        compile_dex: true,
    }

لتكوين مكتبات كعب الروتين، استخدم الخصائص التالية:

  • merge_annotations_dirs و merge_inclusion_annotations_dirs .
  • api_srcs : قائمة الملفات المصدر الاختيارية التي تعد جزءًا من واجهة برمجة التطبيقات (API) ولكنها ليست جزءًا من مكتبة وقت التشغيل.
  • stubs_only_libs : قائمة مكتبات Java الموجودة في مسار الفصل عند إنشاء بذرة.
  • hidden_api_packages : قائمة أسماء الحزم التي يجب إخفاؤها من واجهة برمجة التطبيقات.
  • droiddoc_options : وسيطة إضافية لـ metalava .
  • droiddoc_option_files : يسرد الملفات التي يمكن الرجوع إليها من داخل droiddoc_options باستخدام $(location <label>) ، حيث يكون <file> مُدخلًا في القائمة.
  • annotations_enabled .

java_sdk_library عبارة عن java_library ، ولكنها ليست وحدة droidstubs وبالتالي لا تدعم جميع خصائص droidstubs . تم أخذ المثال التالي من ملف بناء مكتبة android.test.mock .

java_sdk_library {
        name: "android.test.mock",

        srcs: [":android-test-mock-sources"],
        api_srcs: [
            // Note: The following aren’t APIs of this library. Only APIs under the
            // android.test.mock package are taken. These do provide private APIs
            // to which android.test.mock APIs reference. These classes are present
            // in source code form to access necessary comments that disappear when
            // the classes are compiled into a Jar library.
            ":framework-core-sources-for-test-mock",
            ":framework_native_aidl",
        ],

        libs: [
            "framework",
            "framework-annotations-lib",
            "app-compat-annotations",
            "Unsupportedappusage",
        ],

        api_packages: [
            "android.test.mock",
        ],
        permitted_packages: [
            "android.test.mock",
        ],
        compile_dex: true,
        default_to_stubs: true,
    }

الحفاظ على التوافق مع الإصدارات السابقة

يتحقق نظام البناء مما إذا كانت واجهات برمجة التطبيقات قد حافظت على التوافق مع الإصدارات السابقة من خلال مقارنة أحدث ملفات واجهة برمجة التطبيقات مع ملفات واجهة برمجة التطبيقات التي تم إنشاؤها في وقت الإنشاء. تقوم java_sdk_library بإجراء فحص التوافق باستخدام المعلومات المقدمة بواسطة prebuilt_apis . يجب أن تحتوي جميع المكتبات التي تم إنشاؤها باستخدام java_sdk_library على ملفات API في أحدث إصدار من api_dirs في prebuilt_apis . عندما تقوم بإصدار الإصدار، يمكن الحصول على قوائم الملفات ومكتبات بذرة واجهة برمجة التطبيقات (API) من خلال إنشاء dist باستخدام PRODUCT=sdk_phone_armv7-sdk .

الخاصية api_dirs هي قائمة بأدلة إصدار API في prebuilt_apis . يجب أن تكون أدلة إصدار API موجودة على مستوى دليل Android.bp .

prebuilt_apis {
       name: "foo",
       api_dirs: [
           "1",
           "2",
             ....
           "30",
           "current",
       ],
    }

قم بتكوين الدلائل باستخدام بنية version / scope /api/ ضمن دليل prebuilts. يتوافق version مع مستوى واجهة برمجة التطبيقات (API) ويحدد scope ما إذا كان الدليل عامًا أم نظامًا أم اختبارًا.

  • version / scope يحتوي على مكتبات جافا.
  • يحتوي version / scope /api على ملفات API .txt . قم بإنشاء ملفات نصية فارغة باسم module_name .txt و module_name -removed.txt هنا.
     ├── 30
          │   ├── public
          │   │   ├── api
          │   │   │   ├── android.test.mock-removed.txt
          │   │   │   └── android.test.mock.txt
          │   │   └── android.test.mock.jar
          │   ├── system
          │   │   ├── api
          │   │   │   ├── android.test.mock-removed.txt
          │   │   │   └── android.test.mock.txt
          │   │   └── android.test.mock.jar
          │   └── test
          │       ├── api
          │       │   ├── android.test.mock-removed.txt
          │       │   └── android.test.mock.txt
          │       └── android.test.mock.jar
          └── Android.bp