بناء تطبيق Android. مهمة مع النجمة



مرحبا يا هبر! في فصل الصيف ، تحدثت في Summer Droid Meetup مع تقرير حول إنشاء تطبيق Android. يمكن العثور على نسخة الفيديو هنا: habr.com/ru/company/funcorp/blog/462825 . بالنسبة لأولئك الذين يحبون قراءة المزيد ، كتبت للتو هذه المقالة.

إنه يتعلق بما هو عليه - تطبيق Android. سوف نجمع بطرق مختلفة Hello، world!: ابدأ من وحدة التحكم ونرى ما يحدث تحت غطاء أنظمة البناء ، ثم عد إلى الماضي ، وتذكر Maven وتعرف على حلول Bazel و Buck الحديثة. وأخيرا ، كل هذا قابل للمقارنة.

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

  • لديه بالتأكيد مشاكل في التجميع التدريجي ، على الرغم من أنه يمكنه رؤية تقدم في هذا الاتجاه ؛
  • يفعل سيئة مع مشاريع متجانسة كبيرة جدا.
  • يحدث أن يبدأ شيطان لفترة طويلة جدا ؛
  • مطالبين على الجهاز الذي يعمل عليه.

APK


بادئ ذي بدء ، تذكر ما يتكون تطبيق Android من: التعليمات البرمجية المترجمة والموارد و AndroidManifest.xml.



توجد المصادر في ملف classes.dex (قد يكون هناك العديد من الملفات ، اعتمادًا على حجم التطبيق) بتنسيق dex خاص يمكن أن يعمل معه جهاز Android الظاهري. اليوم هو ART ، على الأجهزة القديمة - Dalvik. بالإضافة إلى ذلك ، يمكنك العثور على مجلد lib ، حيث يتم ترتيب المصادر الأصلية في مجلدات فرعية. سيتم تسميتها اعتمادًا على بنية المعالج الهدف ، على سبيل المثال x86 ، الذراع ، إلخ. إذا كنت تستخدم exoplayer ، فمن المحتمل أن يكون لديك lib. ومجلد aidl ، الذي يحتوي على واجهات الاتصالات interprocess. سيكونون في متناول يدي إذا كنت بحاجة إلى الوصول إلى خدمة تعمل في عملية أخرى. يتم استخدام هذه الواجهات في Android نفسها وداخل GooglePlayServices.

توجد العديد من الموارد غير المترجمة مثل الصور في مجلد res. يتم دمج جميع الموارد المترجمة ، مثل الأنماط والخطوط وما إلى ذلك ، في ملف resource.arsc. في مجلد الأصول ، كقاعدة عامة ، يضعون كل ما لا يتلاءم مع الموارد ، على سبيل المثال ، الخطوط المخصصة.

بالإضافة إلى كل هذا ، يحتوي ملف APK على AndroidManifest.xml. في ذلك ، نحن تصف المكونات المختلفة للتطبيق ، مثل النشاط ، الخدمة ، أذونات مختلفة ، إلخ. إنها تكمن في شكل ثنائي ، ومن أجل النظر إلى الداخل ، يجب أولاً تحويلها إلى ملف قابل للقراءة من قبل الإنسان.

CONSOLE


الآن بعد أن عرفنا ما يتكون التطبيق منه ، يمكننا أن نحاول بناء Hello، world! من وحدة التحكم باستخدام الأدوات التي يوفرها Android SDK. هذه خطوة مهمة جدًا في فهم كيفية عمل أنظمة الإنشاء ، لأنها تعتمد جميعًا على هذه الأدوات المساعدة بدرجة أو بأخرى. منذ كتابة المشروع في Kotlin ، نحتاج إلى برنامج التحويل البرمجي لسطر الأوامر. من السهل التنزيل بشكل منفصل.

يمكن تقسيم تجميع التطبيق إلى الخطوات التالية:

  • قم بتنزيل وفك ضغط جميع المكتبات التي يعتمد عليها المشروع. في حالتي ، فهذه هي مكتبة التوافق الوراء appcompat ، والتي بدورها تعتمد على appcompat-core ، لذلك نقوم بضخها أيضًا ؛
  • توليد R.java. تحتوي هذه الفئة الرائعة على معرفات جميع الموارد في التطبيق ويتم استخدامها للوصول إليها في التعليمات البرمجية ؛
  • نقوم بتجميع المصادر إلى bytecode وترجمتها إلى Dex ، لأن جهاز Android الظاهري لا يعرف كيفية العمل مع bytecode المعتاد ؛
  • نحن نحزم كل شيء في ملف APK ، لكن أولاً نحاذي جميع الموارد غير القابلة للضغط ، مثل الصور ، بالنسبة لبداية الملف. يسمح هذا لسعر زيادة ضئيلة جدًا في حجم ملف APK لتسريع أعماله بشكل كبير. وبالتالي ، يمكن للنظام مباشرة تعيين الموارد لذاكرة الوصول العشوائي (RAM) باستخدام وظيفة mmap ().
  • التوقيع على التطبيق. هذا الإجراء يحمي سلامة APK ويؤكد التأليف. وبفضل هذا ، على سبيل المثال ، يمكن لـ Play Market التحقق من بناء التطبيق بواسطتك.

بناء النصي
function preparedir() { rm -r -f $1 mkdir $1 } PROJ="src/main" LIBS="libs" LIBS_OUT_DIR="$LIBS/out" BUILD_TOOLS="$ANDROID_HOME/build-tools/28.0.3" ANDROID_JAR="$ANDROID_HOME/platforms/android-28/android.jar" DEBUG_KEYSTORE="$(echo ~)/.android/debug.keystore" GEN_DIR="build/generated" KOTLIN_OUT_DIR="$GEN_DIR/kotlin" DEX_OUT_DIR="$GEN_DIR/dex" OUT_DIR="out" libs_res="" libs_classes="" preparedir $LIBS_OUT_DIR aars=$(ls -p $LIBS | grep -v /) for filename in $aars; do DESTINATION=$LIBS_OUT_DIR/${filename%.*} echo "unpacking $filename into $DESTINATION" unzip -o -q $LIBS/$filename -d $DESTINATION libs_res="$libs_res -S $DESTINATION/res" libs_classes="$libs_classes:$DESTINATION/classes.jar" done preparedir $GEN_DIR $BUILD_TOOLS/aapt package -f -m \ -J $GEN_DIR \ -M $PROJ/AndroidManifest.xml \ -S $PROJ/res \ $libs_res \ -I $ANDROID_JAR --auto-add-overlay preparedir $KOTLIN_OUT_DIR compiledKotlin=$KOTLIN_OUT_DIR/compiled.jar kotlinc $PROJ/java $GEN_DIR -include-runtime \ -cp "$ANDROID_JAR$libs_classes"\ -d $compiledKotlin preparedir $DEX_OUT_DIR dex=$DEX_OUT_DIR/classes.dex $BUILD_TOOLS/dx --dex --output=$dex $compiledKotlin preparedir $OUT_DIR unaligned_apk=$OUT_DIR/unaligned.apk $BUILD_TOOLS/aapt package -f -m \ -F $unaligned_apk \ -M $PROJ/AndroidManifest.xml \ -S $PROJ/res \ $libs_res \ -I $ANDROID_JAR --auto-add-overlay cp $dex . $BUILD_TOOLS/aapt add $unaligned_apk classes.dex rm classes.dex aligned_apk=$OUT_DIR/aligned.apk $BUILD_TOOLS/zipalign -f 4 $unaligned_apk $aligned_apk $BUILD_TOOLS/apksigner sign --ks $DEBUG_KEYSTORE $aligned_apk 


وفقًا للأرقام ، اتضح أن التجميع النظيف يستغرق 7 ثوانٍ ، والتجمع التدريجي لا يتخلف عنه ، لأننا لا نقوم بتخزين أي شيء مؤقتًا وإعادة بناء كل شيء في كل مرة.

مخضرم


تم تطويره من قبل اللاعبين في Apache Software Foundation لبناء مشاريع Java. بناء التكوينات لذلك موصوفة في XML. جمعت Ant المراجعات المبكرة من Maven ، والآن تحولت إلى أحدث إصدار مستقر.

إيجابيات مافن:

  • وهو يدعم القطع التجميعية للتخزين المؤقت ، على سبيل المثال يجب أن يكون الإنشاء التزايدي أسرع من النظافة ؛
  • قادرة على حل تبعيات الطرف الثالث. أي عندما تحدد تبعية على مكتبة تابعة لجهة خارجية في التكوين Maven أو Gradle ، فلا داعي للقلق بشأن ما تعتمد عليه ؛
  • هناك مجموعة من الوثائق التفصيلية ، لأنها كانت موجودة في السوق لبعض الوقت.
  • ويمكن أن تكون آلية بناء مألوفة إذا جئت مؤخرًا إلى عالم تطوير Android من الخلفية.

سلبيات مافن:

  • يعتمد على إصدار Java المثبت على الجهاز الذي يتم التجميع عليه ؛
  • يتم الآن دعم المكون الإضافي لنظام Android من قِبل مطوري الطرف الثالث: شخصيًا ، أعتبر هذا عائقًا كبيرًا ، لأنهم في يوم ما قد يتوقفون عن القيام بذلك ؛
  • لا يعد XML مناسبًا لوصف تكوينات الإنشاء بسبب التكرار والإجهاد ؛
  • حسنًا ، وكما سنرى لاحقًا ، يعمل بشكل أبطأ من Gradle ، على الأقل في مشروع اختبار.

للبناء ، نحتاج إلى إنشاء pom.xml ، والذي يحتوي على وصف لمشروعنا. في الرأس ، يرجى الإشارة إلى المعلومات الأساسية حول القطع الأثرية التي تم جمعها ، بالإضافة إلى إصدار Kotlin.

بناء التكوين pom.xml
 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>myapplication</artifactId> <version>1.0.0</version> <packaging>apk</packaging> <name>My Application</name> <properties> <kotlin.version>1.3.41</kotlin.version> </properties> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>com.google.android</groupId> <artifactId>android</artifactId> <version>4.1.1.4</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> <executions> <execution> <id>compile</id> <phase>process-sources</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>com.simpligility.maven.plugins</groupId> <artifactId>android-maven-plugin</artifactId> <extensions>true</extensions> <configuration> <sdk> <platform>28</platform> <buildTools>28.0.3</buildTools> </sdk> <failOnNonStandardStructure>false</failOnNonStandardStructure> </configuration> </plugin> </plugins> </build> </project> 


من حيث الأرقام ، كل شيء ليس وردية للغاية. يستغرق التجميع النظيف حوالي 12 ثانية ، في حين أن التجميع الإضافي - 10. يعني هذا أن Maven يعيد بطريقة ما استخدام القطع الأثرية من التجميعات السابقة ، أو في رأيي ، من المرجح أن يمنع المكون الإضافي لبناء مشروع Android من القيام بذلك.

الآن يستخدمون كل هذا ، أعتقد ، أولاً ، أن منشئي البرنامج المساعد هم الرجال من البساطة. لا يمكن العثور على مزيد من المعلومات الموثوقة حول هذه المشكلة.

بازل


اخترع المهندسون في أحشاء Google Bazel لبناء مشاريعهم ونقلوها مؤخرًا نسبيًا إلى مصدر مفتوح. لوصف builds-configs الثعبان الشبيه بـ Skylark أو Starlark ، كلا الاسمين لهما مكان. يتم تجميعها باستخدام أحدث إصدار مستقر.

إيجابيات بازيل:

  • دعم لغات البرمجة المختلفة. إذا كنت تعتقد أن الوثائق ، فهو يعرف كيفية جمع مشاريع لـ ios أو Android أو حتى الواجهة الخلفية ؛
  • يمكن تخزين التحف التي تم جمعها سابقا
  • قادرة على العمل مع تبعيات مخضرم.
  • Bazel لديه دعم رائع للمشاريع الموزعة. يمكنه تحديد مراجعات محددة لمستودعات git على أنها تبعيات ، وسيقوم بإفراغها وتخزينها مؤقتًا أثناء عملية الإنشاء. لدعم قابلية التوسع ، يمكن لـ Bazel ، على سبيل المثال ، توزيع أهداف متعددة على خوادم البناء المستندة إلى مجموعة النظراء ، والتي تسمح لك ببناء مشاريع ضخمة بسرعة.

سلبيات بازيل:

  • يصعب الحفاظ على كل هذا السحر ، لأن تكوينات البناء مفصلة للغاية وتصف التجميع بمستوى منخفض ؛
  • من بين أمور أخرى ، يبدو أن بازيل تتطور الآن بنشاط. لهذا السبب ، لا يتم جمع بعض الأمثلة ، ويمكن لتلك الأمثلة التي يتم جمعها استخدام الوظيفة القديمة ، والتي تم تمييزها على أنها مهجورة ؛
  • تترك الوثائق الآن أيضًا الكثير مما هو مرغوب فيه ، خاصة عند مقارنته بـ Gradle
  • في المشروعات الصغيرة ، قد يستغرق الاحماء وتحليل التكوينات وقتًا أطول من التجميع نفسه ، وهو أمر غير جيد ، في رأيي.

من الناحية النظرية ، يتكون تكوين Bazel الأساسي من مساحة عمل ، حيث نصف كل أنواع الأشياء العالمية للمشروع ، و BUILD ، الذي يحتوي على أهداف للتجميع مباشرة.
دعونا وصف مساحة العمل. نظرًا لأن لدينا مشروع Android ، فإن أول شيء نقوم بتكوينه هو Android SDK. أيضًا ، يتم استيراد قاعدة لإلغاء تحميل التكوينات هنا. بعد ذلك ، نظرًا لأن المشروع مكتوب في Kotlin ، يجب علينا تحديد القواعد اللازمة لذلك. نحن هنا نفعل ذلك ، في اشارة الى مراجعة محددة مباشرة من مستودع بوابة.

WORKSPACE
 android_sdk_repository( name = "androidsdk", api_level = 28, build_tools_version = "28.0.3" ) load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") # # KOTLIN RULES # RULES_KOTLIN_VERSION = "990fcc53689c8b58b3229c7f628f843a60cb9f5c" http_archive( name = "io_bazel_rules_kotlin", url = "https://github.com/bazelbuild/rules_kotlin/archive/%s.zip" % RULES_KOTLIN_VERSION, strip_prefix = "rules_kotlin-%s" % RULES_KOTLIN_VERSION ) load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_register_toolchains") kotlin_repositories() kt_register_toolchains() 


الآن دعونا نبدأ في بناء.

أولاً ، نستورد قاعدة تجميع Kotlin ونصف ما نريد جمعه. في حالتنا ، هذا هو تطبيق Android ، لذلك نستخدم android_binary ، حيث نقوم بتعيين البيان ، والحد الأدنى من SDK ، إلخ. يعتمد تطبيقنا على المصدر ، لذلك نذكرهم في deps وننتقل إلى ما هم عليه وأين يمكن العثور عليهم. يعتمد الرمز أيضًا على الموارد ومكتبة appcompat. بالنسبة إلى الموارد ، نستخدم الهدف المعتاد لتجميع مصادر android ، لكننا نقوم بتعيين الموارد له فقط دون فئات java. ونصف بعض القواعد التي تستورد مكتبات الطرف الثالث. يذكر أيضًا appcompat_core ، والذي يعتمد عليه appcompat.

BUILD
 load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") android_binary( name = "app", custom_package = "com.example.myapplication", manifest = "src/main/AndroidManifest.xml", manifest_values = { "minSdkVersion": "15", }, deps = [ ":lib", ], ) kt_android_library( name = "lib", srcs = glob(["src/main/java/**/*"]), deps = [ ":res", ":appcompat", ], ) android_library( name = "res", resource_files = glob(["src/main/res/**/*"]), manifest = "src/main/AndroidManifest.xml", custom_package = "com.example.myapplication", ) aar_import( name = "appcompat", aar = "libs/appcompat.aar", deps = [ ":appcompat_core", ] ) aar_import( name = "appcompat_core", aar = "libs/core.aar", ) 


في أرقام مثل هذا المشروع الصغير ، يبدو كل شيء محزنًا. أكثر من نصف دقيقة لبناء نظيف مرحبا ، العالم! - كثير وقت البناء الإضافي هو أيضا بعيد عن الكمال.

يستخدم Bazel من قِبل منشئي المحتوى (Google) في بعض مشاريعهم ، بما في ذلك الخوادم ، وكذلك Dropbox و Huawei ، اللذان يجمعان تطبيقات الجوال لهما. و Dagger 2 سيئ السمعة يذهب أيضا إلى Bazel.

باك


تم اختراعه من قبل الهاربين من Google إلى Facebook. لقد استخدم Python لوصف التكوينات ، ثم انتقل إلى Skylark المذكورة اليوم. هو ذاهب ، فجأة ، باستخدام نظام النملة.

باك الايجابيات:

  • يدعم لغات البرمجة المختلفة ويمكنه بناء Andriod و iOS ؛
  • يمكن تخزين التحف التي تم جمعها سابقا
  • قام Buck بتنفيذ تطبيق dex الخاص به ، والذي يعمل بشكل أسرع من التطبيق القياسي وتوقف مع البرنامج الخفي. حتى أنها توفر الوقت على التهيئة dex. المهندسين حقا الأمثل كثيرا. على سبيل المثال ، لا يقوم Buck بتجميع التعليمات البرمجية التي تعتمد على المكتبة إذا لم تتغير الواجهة عند تغيير الأجزاء الداخلية للمكتبة. وبالمثل بالنسبة للموارد: إذا لم تتغير المعرفات ، فعند تغيير الموارد ، لا يتم إعادة تجميع الكود.
  • هناك مكون إضافي يمكنه إخفاء باك خلف تهيئة Gredlovsky. أي تحصل على شيء مثل مشروع Gradle العادي ، والذي تم بناؤه بالفعل من خلال Buck.

سلبيات باك:

  • من الصعب الحفاظ عليها مثل Bazel. أي من الضروري هنا أيضًا وصف القواعد ذات المستوى المنخفض التي تصف عملية التجميع بوضوح ؛
  • من بين أمور أخرى ، لا يستطيع باك حل تبعيات مافن من تلقاء نفسه.

لذا ، ماذا التكوين التجمع ل Hello ، العالم! من خلال باك؟ في ما يلي وصف لملف تكوين واحد ، حيث نشير إلى أننا نريد إنشاء مشروع Android يتم توقيعه باستخدام مفتاح تصحيح. سيعتمد التطبيق بالمثل على المصدر - lib في صفيف deps. التالي يأتي الهدف مع إعدادات التوقيع. أستخدم مفتاح الخصم الذي يأتي مع Android SDK. بعد ذلك مباشرة يتبع الهدف ، والذي سيجمع مصادر Kotlin بالنسبة لنا. مثل Bazel ، يعتمد على مكتبات الموارد والتوافق.

وصفنا لهم. هناك هدف منفصل للموارد في باك ، لذلك الدراجات ليست مفيدة. فيما يلي قواعد مكتبات الجهات الخارجية التي تم تنزيلها.

BUILD
 android_binary( name = 'app', manifest = 'src/main/AndroidManifest.xml', manifest_entries = { 'min_sdk_version': 15, }, keystore = ':debug_keystore', deps = [ ':lib', ], ) keystore( name = 'debug_keystore', store = 'debug.keystore', properties = 'debug.keystore.properties', ) android_library( name = 'lib', srcs = glob(['src/main/java/*.kt']), deps = [ ':res', ':compat', ':compat_core', ], language = 'kotlin', ) android_resource( name = 'res', res = "src/main/res", package = 'com.example.myapplication', ) android_prebuilt_aar( name = 'compat', aar = "libs/appcompat.aar", ) android_prebuilt_aar( name = 'compat_core', aar = "libs/core.aar", ) 


كل هذا يحدث بسرور شديد. يستغرق التجميع النظيف أكثر من 7 ثوان بقليل ، بينما التجميع الإضافي غير مرئي تمامًا 200 مللي ثانية. أعتقد أن هذه نتيجة جيدة للغاية.

هذا هو ما يفعله Facebook. بالإضافة إلى التطبيق الرئيسي الخاص بهم ، يقومون بتجميع Facebook Messenger لهم. وأوبر ، الذي جعل البرنامج المساعد لجرادل و Airbnb مع Lyft.

النتائج


الآن بعد أن تحدثنا عن كل نظام بناء ، يمكننا أن نقارنهم مع بعضهم البعض باستخدام مثال Hello ، world! مجموعة وحدة التحكم يحلو لها مع الاستقرار. يمكن اعتبار وقت تنفيذ البرنامج النصي من المحطة المرجعية مرجعًا للتجميعات النظيفة ، نظرًا لأن تكاليف الجهة الخارجية لتحليل النصوص البرمجية تكون ضئيلة هنا. في هذه الحالة ، أود أن أسمي مافن من الخارج الواضح لزيادة ضئيلة للغاية في التجمع التدريجي. يقوم Bazel بتوزيع التهيئة لفترة طويلة جدًا وتهيئة: هناك فكرة أنه يخبئ نتائج التهيئة بطريقة أو بأخرى ، لأن بنائه التزايدي أسرع بكثير من النظيفة. باك هو الزعيم بلا منازع لهذه المجموعة. سريع جدا على حد سواء التجمع نظيفة وتزايدي.



الآن قارن بين إيجابيات وسلبيات. لن أدرج Maven في المقارنة ، لأنه يخسر بوضوح إلى Gradle ولا يستخدم أبدًا في السوق. أنا توحد باك و Bazel ، لأن لديهم تقريبا نفس المزايا والعيوب.

لذلك ، حول Gradle:

  • الأول ، وفي رأيي ، أهم شيء هو أنه بسيط. بسيط جدا
  • خارج الصندوق ، تفريغ وتفريغ التبعيات ؛
  • بالنسبة له هناك الكثير من التدريبات والوثائق المختلفة.
  • مدعومة بنشاط من قبل كل من جوجل والمجتمع. تكامل رائع مع Android Studio ، أداة التطوير الرئيسية الحالية. وستظهر جميع الميزات الجديدة لإنشاء تطبيق Android أولاً في Gradle.

حول باك / بازيل:

  • يمكن أن يكون بالتأكيد سريعًا جدًا مقارنة بـ Gradle. أعتقد أن هذا ملحوظ بشكل خاص في المشاريع الكبيرة جدًا
  • يمكنك الاحتفاظ بمشروع واحد سيكون فيه رموز مصدر لكل من iOS و Android ، وتجميعها بنظام بناء واحد. هذا يسمح لبعض أجزاء التطبيق بالتعثر بين الأنظمة الأساسية. على سبيل المثال ، هكذا يجري Chromium ؛
  • اضطر لوصف التبعيات بالتفصيل ، وبالتالي إجبار المطور على أن يكون متعدد الوحدات.

لا تنسى سلبيات.

يدفع Gradle لبساطته من خلال كونه بطيئًا وغير فعال.
Buck / Bazel ، على العكس من ذلك ، بسبب سرعته ، يعاني من الحاجة لوصف عملية الإنشاء في التكوينات بمزيد من التفاصيل. حسنًا ، نظرًا لأنها ظهرت في السوق مؤخرًا نسبيًا ، فليس هناك الكثير من الوثائق وأوراق الغش المختلفة.

iFUNNY


ربما لديك سؤال كيف نجمع iFunny. تماما مثل الكثيرين - باستخدام Gradle. وهناك أسباب لهذا:

  1. لم يتضح بعد أي نوع من المكاسب في سرعة التجميع التي سيمنحنا هذا. يستغرق البناء النظيف لـ iFunny حوالي 3 دقائق ، وتدريجيًا - حوالي دقيقة واحدة ، وهي في الواقع ليست طويلة جدًا.
  2. تعد إعدادات التكوينات Buck أو Bazel أكثر صعوبة في الصيانة. في حالة Buck ، تحتاج أيضًا إلى مراقبة أهمية المكتبات المتصلة والمكتبات التي تعتمد عليها.
  3. من المألوف نقل مشروع قائم من Gradle إلى Buck / Bazel ، خاصةً في ظروف الربح غير المفهوم.

إذا كان مشروعك سيستغرق أكثر من 45 دقيقة وكان هناك حوالي 20 شخصًا في فريق تطوير Android ، فمن المنطقي التفكير في تغيير نظام الإنشاء. إذا كنت أنت وصديقك يشاهدان بدء تشغيل ، فاستخدم Gradle واسقط هذه الأفكار.



سأكون سعيدًا لمناقشة احتمالات بدائل Gradle في التعليقات!
رابط للمشروع

Source: https://habr.com/ru/post/ar469771/


All Articles