فشل بناء Flutter بسبب Gradle: الأسباب الشائعة والحلول

عند بناء تطبيق Flutter لنظام Android، تعمل عدة تقنيات معًا، من بينها Flutter وDart وGradle وAndroid Gradle Plugin وJava وKotlin وAndroid SDK. وأي مشكلة في التوافق بين هذه المكونات يمكن أن تؤدي إلى فشل عملية بناء التطبيق.

قد يظهر خطأ شائع بهذا الشكل:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileDebugKotlin'.

> Compilation error. See log for more details.

وقد تظهر رسالة أخرى مثل:

Gradle build failed to produce an .apk file.

المهم أن تفهم أن رسالة Gradle build failed ليست غالبًا السبب الحقيقي للمشكلة، وإنما هي النتيجة النهائية لخطأ آخر ظهر في وقت سابق داخل سجل البناء.

1. ابحث عن الخطأ الحقيقي أولًا

قبل تعديل إعدادات Gradle بشكل عشوائي، ابدأ بفحص بيئة Flutter:

flutter doctor -v

بعد ذلك قم بتنظيف المشروع واستعادة الحزم:

flutter clean
flutter pub get

للحصول على سجل تفصيلي لعملية البناء استخدم:

flutter run -v

أو عند إنشاء APK:

flutter build apk --debug -v

يمكن تلخيص طريقة التشخيص الاحترافية كالتالي:

Build failed
    ↓
قراءة أول خطأ حقيقي
    ↓
تحديد المكون المسؤول
    ↓
فحص الإصدارات
    ↓
إصلاح الإعدادات
    ↓
تنظيف المشروع
    ↓
إعادة البناء

لا تركز فقط على BUILD FAILED، لأن السبب الحقيقي يكون عادةً قبل هذه الرسالة بعدة أسطر.

2. عدم توافق إصدار Gradle

يُعد عدم توافق إصدار Gradle من أكثر أسباب فشل بناء تطبيقات Flutter على Android.

عادةً يوجد إعداد Gradle Wrapper في:

android/gradle/wrapper/gradle-wrapper.properties

وقد تجد إعدادًا مشابهًا:

distributionUrl=https\://services.gradle.org/distributions/gradle-8.x-bin.zip

يعتمد إصدار Gradle المناسب على إصدار Android Gradle Plugin وإصدار Java وإعدادات المشروع.

يمكنك معرفة إصدار Gradle باستخدام:

cd android
gradlew --version

وفي macOS أو Linux:

cd android
./gradlew --version

تحقق من إصدار Gradle وإصدار JVM قبل تعديل أي إعدادات.

3. عدم توافق Android Gradle Plugin

يعمل Gradle بالتعاون مع Android Gradle Plugin، والذي يُعرف اختصارًا باسم AGP. ويجب أن يكون الإصداران متوافقين مع بعضهما.

بحسب بنية المشروع، يمكن العثور على إصدار AGP في:

android/settings.gradle

أو في المشاريع القديمة:

android/build.gradle

قد يحتوي المشروع على إعداد مشابه:

plugins {
    id "com.android.application" version "8.x.x" apply false
}

إذا كان إصدار Gradle غير متوافق مع AGP، فقد تظهر أخطاء مثل:

Minimum supported Gradle version is ...

أو:

The Android Gradle plugin supports only ...

لا تقم برفع إصدار Gradle عشوائيًا. تحقق أولًا من توافق AGP وGradle وJava.

4. مشاكل إصدار Java

يُعتبر توافق Java من أهم العوامل التي تؤثر على عملية بناء Android.

تحقق من إصدار Java المثبت:

java -version

ويمكنك أيضًا معرفة إصدار Java الذي يستخدمه Gradle:

cd android
gradlew --version

قد يظهر في النتيجة شيء مشابه:

JVM: 17.x.x

تحدث المشكلة غالبًا عندما يكون إصدار Java المستخدم غير متوافق مع إصدارات Gradle وAndroid Gradle Plugin الموجودة في المشروع.

يمكن تصور العلاقة كالتالي:

Java
  ↓
Gradle
  ↓
Android Gradle Plugin

استخدم flutter doctor -v لمعرفة إعداد Java الذي يستخدمه Flutter.

5. مشاكل Android SDK

يعتمد Flutter أيضًا على إعداد صحيح لـ Android SDK.

نفذ:

flutter doctor -v

قد تواجه أخطاء مثل:

Android SDK not found

أو:

cmdline-tools component is missing

كما قد تكون هناك مشكلة في تراخيص Android.

flutter doctor --android-licenses

ويمكنك فحص مكونات SDK المتوفرة باستخدام:

sdkmanager --list

تأكد من تثبيت Android SDK Platforms وBuild Tools المطلوبة للمشروع.

6. إعدادات compileSdk وtargetSdk

يحتوي مشروع Flutter على إعدادات Android SDK. وقد يحتوي المشروع الحديث على إعداد مشابه:

android {
    compileSdk flutter.compileSdkVersion

    defaultConfig {
        applicationId "com.example.myapp"
        minSdk flutter.minSdkVersion
        targetSdk flutter.targetSdkVersion
    }
}

تختلف الإعدادات الدقيقة حسب إصدار Flutter وبنية المشروع.

قد تحتاج إحدى Flutter Plugins إلى إصدار Android SDK أحدث من الإصدار المستخدم في التطبيق.

Plugin
   ↓
Requires newer Android SDK
   ↓
Application uses older SDK
   ↓
Build failure

لذلك يجب دائمًا مراجعة متطلبات Android الخاصة بالحزمة قبل تغيير إعدادات SDK.

7. أخطاء minSdkVersion

قد تتطلب إحدى الحزم إصدار Android SDK أعلى من الحد الأدنى الذي يدعمه التطبيق.

مثلًا:

uses-sdk:minSdkVersion 21 cannot be smaller than version 23 declared in library

هذا يعني أن التطبيق يدعم API 21 بينما تحتاج إحدى الحزم إلى API 23.

يمكن أن يكون الحل هو رفع الحد الأدنى:

android {
    defaultConfig {
        minSdk 23
    }
}

لكن لا تقم برفع minSdk بشكل عشوائي. تأكد من أن الإصدار الجديد مناسب لإصدارات Android التي تريد أن يدعمها تطبيقك.

8. تعارض إصدارات Kotlin

قد تعتمد بعض Flutter Plugins على Kotlin، وقد يؤدي عدم توافق إصدار Kotlin إلى أخطاء مثل:

Kotlin compilation failed

أو:

Module was compiled with an incompatible version of Kotlin

في المشاريع الحديثة قد يتم تعريف Kotlin داخل plugins block:

plugins {
    id "org.jetbrains.kotlin.android" version "..."
}

بينما قد تستخدم المشاريع القديمة:

ext.kotlin_version = "..."

لا تقم بنسخ إصدار Kotlin عشوائيًا من مشروع آخر. يجب أن يكون إصدار Kotlin متوافقًا مع Android Gradle Plugin وباقي dependencies.

9. مشاكل توافق Flutter Plugins

في بعض الحالات لا يكون Gradle هو المشكلة الحقيقية. فقد تحتوي إحدى Flutter Packages على كود Android Native غير متوافق مع إعدادات المشروع الحالية.

مثلًا:

dependencies:
  some_package: ^1.0.0

بعد تنفيذ flutter pub get قد يفشل Gradle أثناء ترجمة الجزء الخاص بـ Android من هذه الحزمة.

افحص الحزم باستخدام:

flutter pub outdated

وتحقق أيضًا من ملف pubspec.yaml.

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

Project works
    ↓
Dependency upgraded
    ↓
Build fails
    ↓
Dependency becomes a suspect

راجع Documentation وChangelog الخاص بالحزمة لمعرفة متطلبات Android وGradle وKotlin وJava وSDK.

10. تنظيف مشروع Flutter

قد تحتوي ملفات Build المؤقتة على بيانات قديمة أو غير متوافقة.

ابدأ باستخدام:

flutter clean
flutter pub get

ثم جرّب:

flutter run

ولإنشاء APK بصيغة Release:

flutter build apk --release

يمكنك أيضًا تنظيف مشروع Android Gradle:

cd android
gradlew clean

وفي macOS وLinux:

cd android
./gradlew clean

11. حذف مجلدات Build التي يتم إنشاؤها تلقائيًا

إذا لم يحل التنظيف العادي المشكلة، يمكنك حذف بعض المجلدات التي يتم إنشاؤها تلقائيًا مثل:

build/
.dart_tool/
android/.gradle/

ثم استعادة الحزم:

flutter pub get
flutter build apk

احرص على عدم حذف كود المشروع أو ملفات الإعدادات المهمة.

12. أخطاء حل وتحميل Dependencies

قد يفشل Gradle أثناء تحميل أو حل dependencies.

مثلًا:

Could not resolve all files for configuration ':app:debugRuntimeClasspath'.

أو:

Could not resolve com.android.tools.build:gradle:...

الأسباب المحتملة تشمل:

  • مشاكل الاتصال بالإنترنت
  • مشاكل إعداد repositories
  • إعدادات Proxy
  • تلف Gradle Cache
  • مشاكل مؤقتة في Repository
  • إصدارات Dependencies غير صحيحة

قد يحتوي إعداد repositories على:

repositories {
    google()
    mavenCentral()
}

تجنب إضافة repositories عشوائية من الإنترنت إلا إذا كنت تثق بالمصدر وتحتاج إليه فعليًا.

13. مشاكل Gradle Cache

في بعض الحالات يمكن أن يصبح Gradle Cache المحلي تالفًا.

في Windows يوجد مجلد Gradle عادةً في:

C:\Users\<USERNAME>\.gradle\

وفي macOS وLinux:

~/.gradle/

لا تبدأ بحذف Cache بالكامل كأول حل. ابدأ بـ:

flutter clean
flutter pub get

إذا استمرت أخطاء Dependencies، عندها يمكنك فحص Gradle Cache.

14. إعدادات Android Studio وJDK

قد يستخدم Android Studio إعداد JDK أو SDK مختلفًا عن Terminal.

وهذا قد يؤدي إلى حالة مثل:

Android Studio build → works

Terminal build → fails

أو العكس.

تحقق من:

  • موقع Android SDK
  • Gradle JDK
  • SDK Platforms
  • SDK Tools
  • Command-line Tools

ثم نفذ:

flutter doctor -v

الهدف هو التأكد من أن Flutter وAndroid Studio وJava وGradle وAndroid SDK تعمل بإعدادات متوافقة.

15. مشاكل خاصة بـ Windows

قد يواجه المطورون على Windows أخطاء مثل:

Access is denied

أو:

Filename too long

أو:

Could not delete directory

ومن الأسباب المحتملة:

  • برنامج Antivirus يقوم بقفل الملفات
  • وجود Gradle Process آخر يستخدم المجلد
  • طول مسارات الملفات في Windows
  • عدم وجود الصلاحيات الكافية
  • تشغيل أكثر من عملية Build في نفس الوقت

أغلق Android Studio وVS Code وTerminals الخاصة بـ Flutter وعمليات Gradle الأخرى، ثم نفذ:

flutter clean
flutter pub get
flutter run

16. الفرق بين gradlew وgradle

تستخدم مشاريع Flutter Android عادةً Gradle Wrapper.

لذلك من الأفضل استخدام:

gradlew build

في Windows:

cd android
gradlew build

وفي macOS وLinux:

cd android
./gradlew build

يستخدم Gradle Wrapper إصدار Gradle المحدد للمشروع، وهذا مهم لأن المشاريع المختلفة قد تحتاج إلى إصدارات مختلفة من Gradle.

17. فحص مجلد Android بعد تحديث Flutter

قد تحتوي مشاريع Flutter القديمة على إعدادات Android قديمة.

تحقق من إصدار Flutter:

flutter --version

ويمكن تحديث Flutter باستخدام:

flutter upgrade

إذا كان المشروع قديمًا، يمكنك إنشاء مشروع مؤقت:

flutter create test_project

ثم قارن إعدادات Android بين المشروع القديم والمشروع الجديد.

لا تستبدل مجلد android بالكامل بشكل عشوائي. قارن ملفات الإعدادات المهمة وانقل التغييرات المطلوبة بعناية.

18. الأخطاء الشائعة والأسباب المحتملة

الخطأ السبب المحتمل
Minimum supported Gradle version is... عدم توافق Gradle مع AGP
Android Gradle plugin requires Java... عدم توافق إصدار Java
Kotlin compilation failed مشكلة توافق Kotlin أو Plugin
minSdkVersion cannot be smaller... Dependency تحتاج minSdk أعلى
Could not resolve... مشكلة Dependency أو Repository أو Network
SDK location not found مشكلة في إعداد Android SDK
cmdline-tools component is missing أدوات Android SDK ناقصة
Manifest merger failed تعارض في إعدادات Android
Gradle build failed to produce an .apk غالبًا بسبب خطأ سابق في سجل البناء

19. التسلسل الموصى به لتشخيص المشكلة

اتبع عملية منظمة بدل تغيير عدة ملفات في نفس الوقت.

الخطوة 1: فحص Flutter

flutter --version

الخطوة 2: فحص البيئة

flutter doctor -v

الخطوة 3: تنظيف المشروع

flutter clean

الخطوة 4: استعادة Dependencies

flutter pub get

الخطوة 5: فحص الحزم القديمة

flutter pub outdated

الخطوة 6: اختبار Android Build

flutter build apk --debug

الخطوة 7: الحصول على سجل تفصيلي

flutter build apk --debug -v

الخطوة 8: البحث عن أول خطأ حقيقي

لا تركز على BUILD FAILED. ابحث قبلها عن:

What went wrong:

ثم حدد أول Exception واضح.

20. قائمة فحص لتشخيص Gradle

قبل تعديل ملفات Gradle، تحقق من:

  • إصدار Flutter
  • flutter doctor -v
  • إصدار Java
  • إصدار Gradle
  • إصدار Android Gradle Plugin
  • إصدار Kotlin
  • Android SDK
  • compileSdk
  • minSdk
  • Flutter Dependencies
  • flutter clean
  • flutter pub get
  • Build Log التفصيلي

هذه الطريقة أكثر أمانًا من تغيير الإصدارات بشكل عشوائي حتى يعمل المشروع.

21. فهم بيئة بناء Flutter

يمكن تصور بيئة Flutter Android السليمة بهذا الشكل:

Flutter SDK
     │
     ├── Dart SDK
     │
     └── Android Toolchain
             │
             ├── Java
             │
             ├── Android SDK
             │
             ├── Android Gradle Plugin
             │
             └── Gradle
                    │
                    └── Flutter Plugins

إذا كان أحد هذه المكونات غير متوافق، فقد يفشل Build.

مثلًا:

New AGP
   +
Old Gradle
   =
Build Failure

أو:

New Kotlin
   +
Old Android Plugin
   =
Build Failure

أو:

Plugin requiring SDK 24
   +
Application minSdk 21
   =
Build Failure

22. أشياء يجب ألا تفعلها

لا تقم بتحديث كل شيء عشوائيًا

تجنب تغيير Gradle وKotlin وAGP وJava وجميع Flutter Packages في الوقت نفسه.

إذا استمر الخطأ، فلن تعرف أي تغيير تسبب في المشكلة أو قام بإصلاحها.

لا تنسخ إعدادات من Tutorials عشوائية

تتغير أدوات Flutter وAndroid باستمرار، والإعداد الذي كان يعمل مع إصدار معين من Flutter قد لا يعمل مع إصدار آخر.

لا تتجاهل أول خطأ

السطر BUILD FAILED لا يشرح السبب الحقيقي. الخطأ المفيد يكون عادةً قبل هذا السطر في سجل البناء.

23. استراتيجية احترافية لتشخيص المشكلة

فكر في نظام البناء على أنه سلسلة من المكونات:

Flutter
   ↓
Android Project
   ↓
AGP
   ↓
Gradle
   ↓
Java
   ↓
Android SDK
   ↓
Flutter Plugins

عند فشل عملية البناء، حدد الطبقة التي أنتجت الخطأ.

  • Kotlin error: تحقق من توافق Kotlin وAGP والـ Plugin.
  • Java error: تحقق من توافق Java وGradle وAGP.
  • SDK error: تحقق من إعدادات Android SDK.
  • Dependency error: تحقق من Flutter Packages وMaven Dependencies.
  • Manifest error: تحقق من إعدادات Android والـ Plugins.

هذه الطريقة أسرع بكثير من تغيير ملفات الإعدادات بشكل عشوائي.

24. Workflow نهائي للحل

عند ظهور:

Flutter Gradle Build Failed

ابدأ باستخدام:

flutter doctor -v
flutter clean
flutter pub get
flutter build apk --debug

إذا فشل البناء، استخدم:

flutter build apk --debug -v

ثم صنّف أول خطأ حقيقي:

  • Gradle
  • AGP
  • Java
  • Kotlin
  • SDK
  • Dependency
  • Manifest
  • Cache
  • Environment

أصلح الطبقة المسؤولة عن المشكلة ثم أعد عملية البناء.

الخلاصة

أخطاء Flutter Gradle Build لا تكون غالبًا بسبب Flutter نفسه. ففي كثير من الحالات يكون السبب الحقيقي هو عدم توافق بين Gradle أو Android Gradle Plugin أو Java أو Kotlin أو Android SDK أو إحدى Flutter Plugins.

الطريقة الأكثر فعالية ليست تغيير ملفات الإعدادات بشكل عشوائي، وإنما:

  1. قراءة سجل البناء.
  2. تحديد أول خطأ حقيقي.
  3. تحديد المكون المسؤول عن المشكلة.
  4. التحقق من توافق الإصدارات.
  5. تنظيف المشروع.
  6. إعادة البناء.

عندما تفهم العلاقة بين Flutter وAndroid وAGP وGradle وJava وAndroid SDK، ستصبح أخطاء Gradle أسهل بكثير في التشخيص والإصلاح.