الفرق بين المراجعتين لصفحة: «Cordova/platforms android»

من موسوعة حسوب
إنشاء الصفحة. هذه الصفحة من مساهمات "رياض خليفة".
 
ط خطأ إملائي
 
(4 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة)
سطر 5: سطر 5:


== المتطلبات والدعم ==
== المتطلبات والدعم ==
استعمال كوردوفا من أجل أندرويد يتطلب Android SDK الذي يمكن تثبيته على OS X أو لينكس أو ويندوز. راجع [http://developer.android.com/sdk/index.html#Requirements متطلبات النظام] لديك من أجل تثبيت Android SDK. تدعم أحدث حزمة من أندرويد في كوردوفا [http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels المستوى 25] للواجهة البرمجية (Android API-Level). يمكن العثور على مستويات Android API المعتمدة وإصدارات Android لإصدارات كوردوفا-أندرويد الماضية في الجدول التالي:
استعمال كوردوفا من أجل أندرويد يتطلب Android SDK الذي يمكن تثبيته على OS X أو لينكس أو ويندوز. راجع [http://developer.android.com/sdk/index.html#Requirements متطلبات النظام] من أجل تثبيت Android SDK. تدعم أحدث حزمة من أندرويد في كوردوفا [http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels المستوى 28] للواجهة البرمجية (Android API-Level). يمكن العثور على مستويات Android API المعتمدة وإصدارات Android لإصدارات كوردوفا-أندرويد الماضية في الجدول التالي:
{| class="wikitable"
{| class="wikitable"
!إصدار كوردوفا-أندرويد
!إصدار كوردوفا-أندرويد
!مستويات واجهة أندرويد البرمجية المدعومة
!مستويات واجهة أندرويد البرمجية المدعومة
!إصدار أندرويد المقابل
!إصدار أندرويد المقابل
|-
|‎8.X.X
|1‎9 - 28
|‎4.4 - 9.0.0
|-
|-
|‎7.X.X
|‎7.X.X
سطر 50: سطر 54:


=== أندرويد SDK ===
=== أندرويد SDK ===
ثبت [https://developer.android.com/studio/index.html Android Studio]. توجد إرشادات التثبيت التفصيلية على الموقع بشكل واضح.
ثبت [https://developer.android.com/studio/index.html Android Studio]. توجد إرشادات التثبيت التفصيلية على الموقع بشكل واضح. عندما تفتح Android Studio للمرة الأولى سيتم إرشادك إلى كيفية تثبيت Android SDK.


=== إضافة حزم SDK ===
=== إضافة حزم SDK ===
بعد تثبيت Android SDK، يجب أيضًا تثبيت الحزم لأي مستوى من [http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels مستويات واجهة برمجة التطبيقات] التي ترغب في استهدافها. يوصى بتثبيت أعلى إصدارمن SDK  يدعمه إصدار كوردوفا-أردوينو الخاص بك (راجع قسم المتطلبات والدعم في الأعلى).
بعد تثبيت Android SDK، يجب أيضًا تثبيت الحزم لأي مستوى من [http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels مستويات واجهة برمجة التطبيقات] التي ترغب في استهدافها. يوصى بتثبيت أعلى إصدارمن SDK  يدعمه إصدار كوردوفا-أندرويد الخاص بك (راجع قسم المتطلبات والدعم في الأعلى).


افتح Android SDK Manager (عبر تنفيذ الأمر <code>sdkmanager</code> من الطرفية) وتأكد من تثبيت ما يلي:
افتح Android SDK Manager (عبر الذهاب إلى <code>Tools > SDK Manager</code> في Android Studio أو عبر تنفيذ الأمر <code>sdkmanager</code> من الطرفية) وتأكد من تثبيت ما يلي:
# حزم SDK لمنصة أندرويد للنسخة المستهدفة من نظام أندرويد
# حزم SDK لمنصة أندرويد للنسخة المستهدفة من نظام أندرويد
# أدوات بناء حزم SDK لأندرويد الإصدار 19.1.0 أو أحدث
# أدوات بناء حزم SDK لأندرويد الإصدار 19.1.0 أو أحدث
# مستودع دعم أندرويد (موجود أسفل "الإضافات" [Extra])
# مستودع دعم أندرويد (ستعثر عليه في أسفل التبويب "SDK Tools")
راجع توثيق أردوينو حول [https://developer.android.com/studio/intro/update.html تثبيت حزم SDK] لمزيد من التفاصيل.
راجع توثيق أندرويد حول [https://developer.android.com/studio/intro/update.html تثبيت حزم SDK] لمزيد من التفاصيل.


=== ضبط متغيرات البيئة ===
=== ضبط متغيرات البيئة ===
سطر 65: سطر 69:
# اضبط متغير البيئة <code>JAVA_HOME</code> على مكان تثبيت JDK الخاص بك.
# اضبط متغير البيئة <code>JAVA_HOME</code> على مكان تثبيت JDK الخاص بك.
# اضبط متغير البيئة <code>ANDROID_HOME</code> على موقع تثبيت Android SDK.
# اضبط متغير البيئة <code>ANDROID_HOME</code> على موقع تثبيت Android SDK.
# يوصى أيضًا بإضافة المجلدات tools، و tools/bin، و platform-tools الخاصة بحزم Android SDK إلى <code>PATH</code>.
# يوصى أيضًا بإضافة المجلدات <code>tools</code>، و <code>tools/bin</code>، و <code>platform-tools</code> الخاصة بحزم Android SDK إلى <code>PATH</code>.


=== النظام OS X ولينكس ===
=== النظام OS X ولينكس ===
في النظام ماك أو لينكس، يمكنك استخدام محرر نصي لإنشاء أو تعديل الملف ‎~/.bash_profile. ولتعيين متغير بيئة، أضف خطًا يستخدم <code>export</code> مثل ذلك (استبدل المسار بالتثبيت المحلي):<syntaxhighlight lang="shell">
في النظام ماك أو لينكس، يمكنك استخدام محرر نصي لإنشاء أو تعديل الملف <code>‎~/.bash_profile</code>. ولتعيين متغير بيئة، أضف خطًا يستخدم <code>export</code> مثل ذلك (استبدل المسار بالتثبيت المحلي):<syntaxhighlight lang="shell">
export ANDROID_HOME=/Development/android-sdk/
export ANDROID_HOME=/Development/android-sdk/
</syntaxhighlight>لتحديث <code>PATH</code>، أضف خطًا يشبه ما يلي (استبدال المسارات بمواقع تثبيت Android SDK المحلي):<syntaxhighlight lang="shell">
</syntaxhighlight>لتحديث <code>PATH</code>، أضف خطًا يشبه ما يلي (استبدال المسارات بمواقع تثبيت Android SDK المحلي):<syntaxhighlight lang="shell">
export PATH=${PATH}:/Development/android-sdk/platform-tools:/Development/android-sdk/tools
export PATH=${PATH}:/Development/android-sdk/platform-tools:/Development/android-sdk/tools
</syntaxhighlight>أعد تشغيل الطرفية لمعرفة سيريان مفعول هذا التغيير أو نفذ الأمر التالي عوضًا عن ذلك:<syntaxhighlight lang="shell">
</syntaxhighlight>أعد تشغيل الطرفية لمعرفة سيريان مفعول هذا التغيير أو نفذ الأمر التالي عوضًا عن ذلك:<syntaxhighlight lang="shell">
$ source ~/.bash_profile
$ source ~/.bash_profile
سطر 86: سطر 91:
C:\Users\[your user]\AppData\Local\Android\Sdk\platform-tools
C:\Users\[your user]\AppData\Local\Android\Sdk\platform-tools
C:\Users\[your user]\AppData\Local\Android\Sdk\tools
C:\Users\[your user]\AppData\Local\Android\Sdk\tools


</syntaxhighlight>
</syntaxhighlight>
سطر 105: سطر 109:
من الممكن تكوين Gradle عن طريق تحديد قيم بعض [https://docs.gradle.org/current/userguide/build_environment.html خاصيات Gradle] التي تعرضها كوردوفا. الخصائص التالية متاحة لتعيين:
من الممكن تكوين Gradle عن طريق تحديد قيم بعض [https://docs.gradle.org/current/userguide/build_environment.html خاصيات Gradle] التي تعرضها كوردوفا. الخصائص التالية متاحة لتعيين:
{| class="wikitable"
{| class="wikitable"
|الخاصية
!الخاصية
|الوصف
!الوصف
|-
|-
|<code>cdvBuildMultipleApks</code>
|<code>cdvBuildMultipleApks</code>
سطر 112: سطر 116:
|-
|-
|<code>cdvVersionCode</code>
|<code>cdvVersionCode</code>
|تستبدل مجموعة كود الإصدار في AndroidManifest.xml.
|تستبدل مجموعة كود الإصدار في A<code>ndroidManifest.xml</code>.
|-
|-
|<code>cdvReleaseSigningPropertiesFile</code>
|<code>cdvReleaseSigningPropertiesFile</code>
|القيمة الافتراضية: release-signing.properties
|القيمة الافتراضية: <code>release-signing.properties</code>


تحدد هذه الخاصية مسار الملف ‎.properties الذي يحتوي على معلومات التوقيع لبنيات الإصدار (انظر قسم توقيع التطبيق).
تحدد هذه الخاصية مسار الملف ‎.properties الذي يحتوي على معلومات التوقيع لبنيات الإصدار (انظر قسم توقيع التطبيق).
|-
|-
|<code>cdvDebugSigningPropertiesFile</code>
|<code>cdvDebugSigningPropertiesFile</code>
|القيمة الافتراضية: debug-signing.properties
|القيمة الافتراضية: <code>debug-signing.properties</code>


تحدد مسار الملف ‎.properties الذي يحتوي على معلومات تسجيل لبنيات التنقيح (انظر قسم توقيع التطبيق). هذه الخاصية مفيدة عندما تحتاج إلى مشاركة مفتاح توقيع مع مطورين آخرين.
تحدد مسار الملف ‎.properties الذي يحتوي على معلومات تسجيل لبنيات التنقيح (انظر قسم توقيع التطبيق). هذه الخاصية مفيدة عندما تحتاج إلى مشاركة مفتاح توقيع مع مطورين آخرين.
|-
|-
|<code>cdvMinSdkVersion</code>
|<code>cdvMinSdkVersion</code>
|تستبدل قيمة المجموعة <code>minSdkVersion</code> في الملف AndroidManifest.xml. هذه الخاصية مفيدة عند إنشاء ملفات APK متعددة استنادًا إلى إصدار SDK.
|تستبدل قيمة المجموعة <code>minSdkVersion</code> في الملف <code>AndroidManifest.xml</code>. هذه الخاصية مفيدة عند إنشاء ملفات APK متعددة استنادًا إلى إصدار SDK.
|-
|-
|<code>cdvBuildToolsVersion</code>
|<code>cdvBuildToolsVersion</code>
|تستبدل القيمة android.buildToolsVersion التي يتم اكتشافها تلقائيًا.
|تستبدل القيمة <code>android.buildToolsVersion</code> التي يتم اكتشافها تلقائيًا.
|-
|-
|<code>cdvCompileSdkVersion</code>
|<code>cdvCompileSdkVersion</code>
|تستبدل القيمة android.compileSdkVersion التي يتم اكتشافها تلقائيًا.
|تستبدل القيمة <code>android.compileSdkVersion</code> التي يتم اكتشافها تلقائيًا.
|}
|}
تستطيع أن تضبط هذه الخصائص بواسطة واحدة من هذه الطرق الأربعة:
تستطيع أن تضبط هذه الخصائص بواسطة واحدة من هذه الطرق الأربعة:
سطر 145: سطر 149:
 $ cordova run android -- --gradleArg=-PcdvMinSdkVersion=20
 $ cordova run android -- --gradleArg=-PcdvMinSdkVersion=20
</syntaxhighlight>
</syntaxhighlight>
* بواسطة وضع ملف اسمه gradle.properties  في مجلد منصة أندرويد (<code><your-project>/platforms/android</code>)  وادخال الخصائص فيه بالشكل التالي:
* بواسطة وضع ملف اسمه <code>gradle.properties</code>  في مجلد منصة أندرويد (<code><your-project>/platforms/android</code>)  وادخال الخصائص فيه بالشكل التالي:
<syntaxhighlight lang="shell">
<syntaxhighlight lang="shell">
# In <your-project>/platforms/android/gradle.properties
# In <your-project>/platforms/android/gradle.properties
cdvMinSdkVersion=20
cdvMinSdkVersion=20
</syntaxhighlight>
</syntaxhighlight>
* بواسطة توسيع  build.gradle عن طريق الملف build-extras.gradle وضبط الخاصية بالشكل التالي:
* بواسطة توسيع  <code>build.gradle</code> عن طريق الملف <code>build-extras.gradle</code> وضبط الخاصية بالشكل التالي:
<syntaxhighlight lang="shell">
<syntaxhighlight lang="shell">
// In <your-project>/platforms/android/build-extras.gradle
// In <your-project>/platforms/android/build-extras.gradle
سطر 159: سطر 163:


=== توسيع build.gradle ===
=== توسيع build.gradle ===
إذا كنت بحاجة إلى تخصيص build.gradle، بدلًا من تحريره مباشرةً، فيجب إنشاء ملف شقيق باسم build-extras.gradle. سيتم تضمين هذا الملف بواسطة build.gradle الرئيسي عند وجوده. يجب وضع هذا الملف في مجلد منصة أندرويد (‎(<code><your-project>/platform/android</code>، لذا يُنصح بنسخه عبر برنامج نصي مرفق بالخطاف <code>before_build</code>. إليك هذا المثال:<syntaxhighlight lang="shell">
إذا كنت بحاجة إلى تخصيص <code>build.gradle</code>، بدلًا من تحريره مباشرةً، فيجب إنشاء ملف شقيق باسم <code>build-extras.gradle</code>. سيتم تضمين هذا الملف بواسطة <code>build.gradle</code> الرئيسي عند وجوده. يجب وضع هذا الملف في مجلد منصة أندرويد (‎(<code><your-project>/platform/android</code>، لذا يُنصح بنسخه عبر برنامج نصي مرفق بالخطاف <code>before_build</code>. إليك هذا المثال:<syntaxhighlight lang="shell">
// Example build-extras.gradle
// build-extras.gradle مثال عن
// This file is included at the beginning of `build.gradle`
// `build.gradle` يُضمّن هذا الملف في بداية
ext.cdvDebugSigningPropertiesFile = '../../android-debug-keys.properties'


// When set, this function allows code to run at the end of `build.gradle`
// وإعادة تعيين القيم الافتراضية - build.gradle يمكن إعداد بعض الخاصيات - انظر
// ext.cdvDebugSigningPropertiesFile = '../../android-debug-keys.properties'
 
// `build.gradle` إعداد عادي لـ
android {
  defaultConfig {
    testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
  }
}
dependencies {
  androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
  }
}
 
// `build.gradle` تنفيذ الشيفرة في نهاية  `ext.postBuildExtras` عند تعيينها، تتيح الدالة
ext.postBuildExtras = {
ext.postBuildExtras = {
     android.buildTypes.debug.applicationIdSuffix = '.debug'
     android.buildTypes.debug.applicationIdSuffix = '.debug'
}
}
</syntaxhighlight>لاحظ أن الإضافات ممكن أن تتضمن ملفات build-extras.gradle  عن طريق:<syntaxhighlight lang="xml">
</syntaxhighlight>لاحظ أن الإضافات ممكن أن تتضمن ملفات <code>build-extras.gradle</code>  عن طريق:<syntaxhighlight lang="xml">
<framework src="some.gradle" custom="true" type="gradleReference" />
<framework src="some.gradle" custom="true" type="gradleReference" />
</syntaxhighlight>
</syntaxhighlight>


=== ضبط إصدار الشيفرة ===
=== ضبط إصدار الشيفرة ===
إن أردت تغيير [https://developer.android.com/studio/publish/versioning.html إصدار الشيفرة] للتطبيق apk المولد، فاضبط الخاصية <code>android-versionCode</code> في العنصر widget في الملف [[Cordova/config ref|config.xml]] الخاص بالتطبيق. إذا لم يتم تعيين الخاصية <code>android-versionCode</code>، فسيتم تحديد رمز الإصدار باستخدام الخاصية version. على سبيل المثال، إذا كان الإصدار هو MAJOR.MINOR.PATCH:<syntaxhighlight lang="shell">
إن أردت تغيير [https://developer.android.com/studio/publish/versioning.html إصدار الشيفرة] للتطبيق apk المولد، فاضبط الخاصية <code>android-versionCode</code> في العنصر widget في الملف [[Cordova/config ref|config.xml]] الخاص بالتطبيق. إذا لم يتم تعيين الخاصية <code>android-versionCode</code>، فسيتم تحديد رمز الإصدار باستخدام الخاصية <code>version</code>. على سبيل المثال، إذا كان الإصدار هو <code>MAJOR.MINOR.PATCH</code>:<syntaxhighlight lang="shell">
versionCode = MAJOR * 10000 + MINOR * 100 + PATCH
versionCode = MAJOR * 10000 + MINOR * 100 + PATCH
</syntaxhighlight>إذا كان التطبيق الخاص بك قد فعَّل خاصية Gradle التي هي <code>CdvBuildMultipleApks</code> (راجع قسم ضبط خاصيات Gradle في الأعلى)، فسيتم ضرب إصدار الشيفرة الخاص بتطبيقك أيضًا بالقيمة 10 بحيث يمكن استخدام آخر رقم من الشيفرة للإشارة إلى البنية التي تم إنشاء apk لها. ستجرى عملية الضرب هذه بغض النظر عما إذا كان رمز الإصدار مأخوذًا من الخاصية <code>android-versionCode</code> أو تم إنشاؤه باستخدام الإصدار. كن على علم بأن بعض الإضافات المضافة إلى مشروعك (بما في ذلك Cordova-plugin-crosswalk-webview) قد تقوم بتعيين خاصية Gradle هذه تلقائيًا.
</syntaxhighlight>إذا كان التطبيق الخاص بك قد فعَّل خاصية Gradle التي هي <code>CdvBuildMultipleApks</code> (راجع قسم ضبط خاصيات Gradle في الأعلى)، فسيتم ضرب إصدار الشيفرة الخاص بتطبيقك أيضًا بالقيمة 10 بحيث يمكن استخدام آخر رقم من الشيفرة للإشارة إلى البنية التي تم إنشاء apk لها. ستجرى عملية الضرب هذه بغض النظر عما إذا كان رمز الإصدار مأخوذًا من الخاصية <code>android-versionCode</code> أو تم إنشاؤه باستخدام الإصدار. كن على علم بأن بعض الإضافات المضافة إلى مشروعك (بما في ذلك <code>Cordova-plugin-crosswalk-webview</code>) قد تقوم بتعيين خاصية Gradle هذه تلقائيًا.


'''ملاحظة مهمة''': عند تحديث الخاصية <code>android-versionCode</code>، فإنه ليس من الحكمة زيادة إصدار الشيفرة المأخوذ من التطبيقات apk المبنية. فبدلًا من ذلك، يجب زيادة الشيفرة استنادًا إلى القيمة الموجودة في الخاصية <code>android-versionCode</code> في الملف [[Cordova/config ref|config.xml]]. ويرجع ذلك إلى أنَّ الخاصية <code>cdvBuildMultipleApks</code> تتسبب في ضرب إصدار الشيفرة المراد ضربه بالقيمة 10 في التطبيقات apk المبنية، وبالتالي فإن استخدام هذه القيمة سيؤدي إلى أن يكون إصدار الشيفرة التالي لديك 100 مرة قدر الأصلي وهكذا دواليك.
'''ملاحظة مهمة''': عند تحديث الخاصية <code>android-versionCode</code>، فإنه ليس من الحكمة زيادة إصدار الشيفرة المأخوذ من التطبيقات apk المبنية. فبدلًا من ذلك، يجب زيادة الشيفرة استنادًا إلى القيمة الموجودة في الخاصية <code>android-versionCode</code> في الملف [[Cordova/config ref|config.xml]]. ويرجع ذلك إلى أنَّ الخاصية <code>cdvBuildMultipleApks</code> تتسبب في ضرب إصدار الشيفرة المراد ضربه بالقيمة 10 في التطبيقات apk المبنية، وبالتالي فإن استخدام هذه القيمة سيؤدي إلى أن يكون إصدار الشيفرة التالي لديك 100 مرة قدر الأصلي وهكذا دواليك.
سطر 207: سطر 225:
|انواع المخزن الرئيسي (المخزن المفتاحي)
|انواع المخزن الرئيسي (المخزن المفتاحي)
|<code>‎--keystoreType</code>
|<code>‎--keystoreType</code>
|القيمة الافتراضية هي: auto-detect أي الاكتشاف التلقائي الذي يستند على لاحقة الملف والتي إما أن تكون pkcs12 أو jks.
|القيمة الافتراضية هي: <code>auto-detect</code> أي الاكتشاف التلقائي الذي يستند على لاحقة الملف والتي إما أن تكون pkcs12 أو jks.
|}
|}
يمكن تحديد هذه المعاملات باستخدام وسائط سطر الأوامر أعلاه مع الأمر <code>[[Cordova/cli#.D8.A7.D9.84.D8.A3.D9.85.D8.B1 cordova build|build]]</code> والأمر <code>[[Cordova/cli#.D8.A7.D9.84.D8.A3.D9.85.D8.B1 cordova run|run]]</code> في سطر أوامر كوردوفا.
يمكن تحديد هذه المعاملات باستخدام وسائط سطر الأوامر أعلاه مع الأمر <code>[[Cordova/cli#.D8.A7.D9.84.D8.A3.D9.85.D8.B1 cordova build|build]]</code> والأمر <code>[[Cordova/cli#.D8.A7.D9.84.D8.A3.D9.85.D8.B1 cordova run|run]]</code> في سطر أوامر كوردوفا.
سطر 216: سطر 234:


=== استخدام build.json ===
=== استخدام build.json ===
بدلاً من ذلك، يمكنك تحديدها في ملف ضبط البناء (الذي هو build.json) باستخدام الوسيط <code>‎--buildConfig</code> مع نفس الأوامر. إليك نموذجًا من ملف ضبط البناء:<syntaxhighlight lang="text">
بدلاً من ذلك، يمكنك تحديدها في ملف ضبط البناء (الذي هو <code>build.json</code>) باستخدام الوسيط <code>‎--buildConfig</code> مع نفس الأوامر. إليك نموذجًا من ملف ضبط البناء:<syntaxhighlight lang="text">
{
{
     "android": {
     "android": {
سطر 237: سطر 255:
</syntaxhighlight>بالنسبة إلى توقيع الإصدار، يمكن استبعاد كلمات المرور وسيصدر نظام الإنشاء نافذة منبثقة تطلب كلمة المرور.
</syntaxhighlight>بالنسبة إلى توقيع الإصدار، يمكن استبعاد كلمات المرور وسيصدر نظام الإنشاء نافذة منبثقة تطلب كلمة المرور.


هناك أيضا دعم لدمج ومطابقة وسائط ومعاملات سطر الأوامر في build.json. ستحصل القيم من وسائط سطر الأوامر على الأسبقية. هذا يمكن أن يكون مفيدًا لتحديد كلمات المرور على سطر الأوامر.
هناك أيضا دعم لدمج ومطابقة وسائط ومعاملات سطر الأوامر في <code>build.json</code>. ستحصل القيم من وسائط سطر الأوامر على الأسبقية. هذا يمكن أن يكون مفيدًا لتحديد كلمات المرور على سطر الأوامر.


=== استخدام Gradle ===
=== استخدام Gradle ===
يمكنك أيضًا تحديد خصائص التوقيع من خلال تضمين الملف ‎.properties والإشارة إليه باستخدام خاصيات Gravers التي هي <code>cdvReleaseSigningPropertiesFile</code> و <code>cdvDebugSigningPropertiesFile</code> (راجع قسم ضبط خاصيات Gradle في الأعلى). يجب أن يبدو الملف كما يلي:<syntaxhighlight lang="text">
يمكنك أيضًا تحديد خصائص التوقيع من خلال تضمين الملف <code>‎.properties</code> والإشارة إليه باستخدام خاصيات Gradle التي هي <code>cdvReleaseSigningPropertiesFile</code> و <code>cdvDebugSigningPropertiesFile</code> (راجع قسم ضبط خاصيات Gradle في الأعلى). يجب أن يبدو الملف كما يلي:<syntaxhighlight lang="text">
storeFile=relative/path/to/keystore.p12
storeFile=relative/path/to/keystore.p12
storePassword=SECRET1
storePassword=SECRET1
سطر 246: سطر 264:
keyAlias=DebugSigningKey
keyAlias=DebugSigningKey
keyPassword=SECRET2
keyPassword=SECRET2
</syntaxhighlight>الخاصية <code>storePassword</code> و <code>keyPassword</code> اختيارية، وستتم مطالبتك بها إذا تم حذفها.
</syntaxhighlight>الخاصية <code>storePassword</code> و <code>keyPassword</code> اختيارية، وستتم مطالبتك بها إذا تم حذفها.


سطر 252: سطر 271:


=== فتح مشروع في Android Studio ===
=== فتح مشروع في Android Studio ===
يمكن فتح مشاريع كوردوفا للأندرويد في [https://developer.android.com/studio/index.html Android Studio]. قد يكون ذلك مفيدًا إذا كنت ترغب في استخدام أدوات التنقيح المدمجة في Android Studio أو إذا كنت تعمل على تطوير إضافات أندرويد. يرجى ملاحظة أنه عند فتح مشروعك في Android Studio، يوصى بعدم تعديل شيفرتك في البيئة التطويرية هنالك (IDE) لأن ذلك سيؤدي إلى تعديل الشيفرة في المجلد platforms في مشروعك (وليس المجلد www) وستكون التغييرات عرضةً للاستبدال. بدلًا من ذلك، قم بتحرير المجلد www ونسخ التغييرات التي أجريتها عن طريق تنفيذ الأمر <code>[[Cordova/cli#.D8.A7.D9.84.D8.A3.D9.85.D8.B1 cordova build|cordova build]]</code>.
يمكن فتح مشاريع كوردوفا للأندرويد في [https://developer.android.com/studio/index.html Android Studio]. قد يكون ذلك مفيدًا إذا كنت ترغب في استخدام أدوات التنقيح المدمجة في Android Studio أو إذا كنت تعمل على تطوير إضافات أندرويد. يرجى ملاحظة أنه عند فتح مشروعك في Android Studio، يوصى بعدم تعديل شيفرتك في البيئة التطويرية هنالك (IDE) لأن ذلك سيؤدي إلى تعديل الشيفرة في المجلد <code>platforms</code> في مشروعك (وليس المجلد <code>www</code>) وستكون التغييرات عرضةً للاستبدال. بدلًا من ذلك، قم بتحرير المجلد <code>www</code> ونسخ التغييرات التي أجريتها عن طريق تنفيذ الأمر <code>[[Cordova/cli#.D8.A7.D9.84.D8.A3.D9.85.D8.B1 cordova build|cordova build]]</code>.


يجب على مطوري الإضافات الراغبين في تحرير الشيفرة الأصلية في بيئة تطوير Android Studio استخدام الراية ‎<code>--link</code> عند إضافة الإضافة للمشروع عن طريق الأمر  <code>cordova plugin add</code>. سيؤدي هذا إلى ربط الملفات بحيث تلك التغييرات التي تطرأ على ملفات الإضافة في المجلد platforms تنعكس في المجلد المصدري للإضافة (والعكس صحيح).
يجب على مطوري الإضافات الراغبين في تحرير الشيفرة الأصلية في بيئة تطوير Android Studio استخدام الراية ‎<code>--link</code> عند إضافة الإضافة للمشروع عن طريق الأمر  <code>cordova plugin add</code>. سيؤدي هذا إلى ربط الملفات بحيث تلك التغييرات التي تطرأ على ملفات الإضافة في المجلد <code>platforms</code> تنعكس في المجلد المصدري للإضافة (والعكس صحيح).


لفتح مشروع كوردوفا لتطبيق أندرويد في Android Studio، اتبع الخطوات التالية:
لفتح مشروع كوردوفا لتطبيق أندرويد في Android Studio، اتبع الخطوات التالية:
# شغل Android Studio.
# شغل '''Android Studio'''.
# حدد Import Project ‏(Eclipse ADT, Gradle, etc).  [[ملف:asdk_import_project.png|بديل=فتح Android Studio ثم تحديد الخيار Import Project من الخيارات الظاهرة لفتح مشروع كوردوفا لتطبيق أندرويد.|بدون|فتح Android Studio ثم تحديد الخيار Import Project من الخيارات الظاهرة لفتح مشروع كوردوفا لتطبيق أندرويد فيه.|تصغير|600بك]]
# حدد '''Import Project''' ‏(Eclipse ADT, Gradle, etc).  [[ملف:asdk_import_project.png|بديل=فتح Android Studio ثم تحديد الخيار Import Project من الخيارات الظاهرة لفتح مشروع كوردوفا لتطبيق أندرويد.|بدون|فتح Android Studio ثم تحديد الخيار Import Project من الخيارات الظاهرة لفتح مشروع كوردوفا لتطبيق أندرويد فيه.|تصغير|600بك]]
# حدد مجلد منصة أندرويد في مشروعك (‎<your-project>/platforms/android).  [[ملف:asdk_import_select_location.png|بديل=تحديد مجلد منصة أندرويد في مشروعك الذي أنشئ باستعمال كوردوفا وذلك لفتحه في Android Studio.|بدون|تحديد مجلد منصة أندرويد في مشروعك الذي أنشئ باستعمال كوردوفا وذلك لفتحه في Android Studio.|تصغير|400بك]]
# حدد مجلد منصة أندرويد في مشروعك (‎<code><your-project>/platforms/android</code>).  [[ملف:asdk_import_select_location.png|بديل=تحديد مجلد منصة أندرويد في مشروعك الذي أنشئ باستعمال كوردوفا وذلك لفتحه في Android Studio.|بدون|تحديد مجلد منصة أندرويد في مشروعك الذي أنشئ باستعمال كوردوفا وذلك لفتحه في Android Studio.|تصغير|400بك]]
# بالنسبة إلى سؤال <code>Gradle Sync</code>، يمكنك ببساطة الإجابة بنعم.
# بالنسبة إلى سؤال <code>Gradle Sync</code>، يمكنك ببساطة الإجابة بنعم.
بمجرد الانتهاء من الاستيراد، يجب أن تكون قادرًا على إنشاء التطبيق وتشغيله مباشرة من Android Studio. راجع صفحة [https://developer.android.com/studio/intro/index.html4 نظرة عامة على Android Studio] وصفحة [https://developer.android.com/studio/run/index.html البناء والتشغيل من Android Studio] لمزيد من التفاصيل.
بمجرد الانتهاء من الاستيراد، يجب أن تكون قادرًا على إنشاء التطبيق وتشغيله مباشرة من Android Studio. راجع صفحة [https://developer.android.com/studio/intro/index.html4 نظرة عامة على Android Studio] وصفحة [https://developer.android.com/studio/run/index.html البناء والتشغيل من Android Studio] لمزيد من التفاصيل.
سطر 270: سطر 289:
لكل من النصوص الموضحة أدناه، ارجع إلى [[Cordova/cli|واجهة سطر أوامر كوردوفا]] للحصول على مزيد من المعلومات حول الوسائط والاستعمالات. يملك كل برنامج نصي اسمًا يطابق أمرًا مقابلًا له في سطر الأوامر. على سبيل المثال،إنَّ <code>Cordova-android/bin/create</code> يعادل الأمر <code>cordova create</code>.
لكل من النصوص الموضحة أدناه، ارجع إلى [[Cordova/cli|واجهة سطر أوامر كوردوفا]] للحصول على مزيد من المعلومات حول الوسائط والاستعمالات. يملك كل برنامج نصي اسمًا يطابق أمرًا مقابلًا له في سطر الأوامر. على سبيل المثال،إنَّ <code>Cordova-android/bin/create</code> يعادل الأمر <code>cordova create</code>.


للبدء، قم بتنزيل حزمة أندرويد-كوردوفا من [https://www.npmjs.com/package/cordova-android npm] أو [https://github.com/apache/cordova-android Github]. لإنشاء مشروع باستخدام هذه الحزمة، قم بتشغيل البرنامج النصي <code>create</code> في المجلد bin:<syntaxhighlight lang="shell">
للبدء، قم بتنزيل حزمة أندرويد-كوردوفا من [https://www.npmjs.com/package/cordova-android npm] أو [https://github.com/apache/cordova-android Github]. لإنشاء مشروع باستخدام هذه الحزمة، قم بتشغيل البرنامج النصي <code>create</code> في المجلد <code>bin</code>:<syntaxhighlight lang="shell">
$ cordova-android/bin/create
$ cordova-android/bin/create
</syntaxhighlight>سيكون للمشروع الذي تم إنشاؤه مجلدًا باسم cordova بداخله يحتوي على برامج نصية لأوامر كوردوفا الخاصة بالمشروع (مثل الأمر <code>run</code>، و <code>build</code>، ...إلخ). بالإضافة إلى ذلك، سيحتوي المشروع على هيكل مختلف عن مشروع كوردوفا العادي. ومن الجدير بالذكر أن المجلد ‎/www نقل إلى ‎/assets/www.
</syntaxhighlight>سيكون للمشروع الذي تم إنشاؤه مجلدًا باسم <code>cordova</code> بداخله يحتوي على برامج نصية لأوامر كوردوفا الخاصة بالمشروع (مثل الأمر <code>run</code>، و <code>build</code>، ...إلخ). بالإضافة إلى ذلك، سيحتوي المشروع على هيكل مختلف عن مشروع كوردوفا العادي. ومن الجدير بالذكر أن المجلد <code>‎/www</code> نقل إلى ‎<code>/assets/www</code>.


لتثبيت إضافات في هذا المشروع، استخدم الأداة [[Cordova/plugman|Plugman]] المساعدة.
لتثبيت إضافات في هذا المشروع، استخدم الأداة [[Cordova/plugman|Plugman]] المساعدة.
سطر 310: سطر 329:
التطبيق الخاص بك هو عرضة للتدمير من قبل نظام التشغيل كلما تركته جانبًا. فهناك موقفان رئيسيان يمكن أن يحدث فيهما هذا؛ الحالة الأولى والأكثر وضوحًا هي عندما يضغط المستخدم على زر الصفحة الرئيسية أو يتحول إلى تطبيق آخر.
التطبيق الخاص بك هو عرضة للتدمير من قبل نظام التشغيل كلما تركته جانبًا. فهناك موقفان رئيسيان يمكن أن يحدث فيهما هذا؛ الحالة الأولى والأكثر وضوحًا هي عندما يضغط المستخدم على زر الصفحة الرئيسية أو يتحول إلى تطبيق آخر.


ومع ذلك، هناك حالة ثانية (وأكثر دهاء) يمكن لبعض الإضافات إدخالها. كما ذكر أعلاه، تقتصر تطبيقات كوردوفا عادة على النشاط الفردي الذي يحتوي على العارض [[Cordova/webviews|WebView]]. ومع ذلك، هناك حالات قد يتم فيها تشغيل أنشطة أخرى بواسطة المكونات الإضافية وتدفع نشاط كوردوفا مؤقتًا إلى الخلفية. يتم عادةً تشغيل هذه الأنشطة الأخرى لتنفيذ مهمة محددة باستخدام تطبيق أصلي مثبت على الجهاز. على سبيل المثال، تطلق [[Cordova/cordova plugin camera|إضافة الكاميرا]] في كوردوفا أي واجهة كاميرا مثبتة أصلًا على الجهاز لالتقاط صورة. إن إعادة استخدام تطبيق الكاميرا المثبت بهذه الطريقة يجعل تطبيقك يشبه إلى حد كبير التطبيق الأصلي كلما يحاول المستخدم التقاط صورة. وللأسف أيضًا، عندما تدفع الواجهة المحلية تطبيقك إلى الخلفية، هناك احتمال أن ينهيه نظام التشغيل.
ومع ذلك، هناك حالة ثانية (وأكثر خفاء) يمكن لبعض الإضافات إدخالها. كما ذكر أعلاه، تقتصر تطبيقات كوردوفا عادة على النشاط الفردي الذي يحتوي على العارض [[Cordova/webviews|WebView]]. ومع ذلك، هناك حالات قد يتم فيها تشغيل أنشطة أخرى بواسطة المكونات الإضافية وتدفع نشاط كوردوفا مؤقتًا إلى الخلفية. يتم عادةً تشغيل هذه الأنشطة الأخرى لتنفيذ مهمة محددة باستخدام تطبيق أصلي مثبت على الجهاز. على سبيل المثال، تطلق [[Cordova/cordova plugin camera|إضافة الكاميرا]] في كوردوفا أي واجهة كاميرا مثبتة أصلًا على الجهاز لالتقاط صورة. إن إعادة استخدام تطبيق الكاميرا المثبت بهذه الطريقة يجعل تطبيقك يشبه إلى حد كبير التطبيق الأصلي كلما يحاول المستخدم التقاط صورة. وللأسف أيضًا، عندما تدفع الواجهة المحلية تطبيقك إلى الخلفية، هناك احتمال أن ينهيه نظام التشغيل.


للحصول على فهم أوضح لهذه الحالة الثانية، دعنا نجرب عبر مثال باستخدام [[Cordova/cordova plugin camera|إضافة الكاميرا]]. تخيل أنَّ لديك تطبيقًا يتطلب من المستخدم التقاط صورة للملف الشخصي. سيظهر تدفق الأحداث في التطبيق عندما يسير كل شيء كما هو مخطط له على النحو التالي:
لتحسين فهمنا للحالة الثانية، دعنا نجرب عبر مثال باستخدام [[Cordova/cordova plugin camera|إضافة الكاميرا]]. تخيل أنَّ لديك تطبيقًا يتطلب من المستخدم التقاط صورة للملف الشخصي. سيظهر تدفق الأحداث في التطبيق عندما يسير كل شيء كما هو مخطط له على النحو التالي:
# يتفاعل المستخدم مع تطبيقك ويحتاج إلى التقاط صورة.
# يتفاعل المستخدم مع تطبيقك ويحتاج إلى التقاط صورة.
# يُطلَق المكون الإضافي للكاميرا واجهة الكاميرا الأصلية.
# يُطلَق المكون الإضافي للكاميرا واجهة الكاميرا الأصلية.
سطر 357: سطر 376:


* أخطاء متنوعة أخرى:
* أخطاء متنوعة أخرى:
 
**<code>"Class not found"</code>
* <code>"Class not found"</code>
**<code>"Illegal access"</code>
* <code>"Illegal access"</code>
**<code>"Instantiation error"</code>
* <code>"Instantiation error"</code>
**<code>"Malformed url"</code>
* <code>"Malformed url"</code>
**<code>"IO error"</code>
* <code>"IO error"</code>
**<code>"Invalid action"</code>
* <code>"Invalid action"</code>
**<code>"JSON error"</code>
* <code>"JSON error"</code>
يرجى ملاحظة أن الأمر متروك للإضافة لتقرر ما هو موجود في الحقل <code>result</code> ومعنى الحقل <code>pluginStatus</code> الذي تم إعادته. ويمكنك الرجوع إلى واجهة برمجة التطبيقات للإضافة التي تستخدمها للاطلاع على ما يجب أن تتوقعه من هذه الحقول وكيفية احتوائها على قيمها.
يرجى ملاحظة أن الأمر متروك للإضافة لتقرر ما هو موجود في الحقل <code>result</code> ومعنى الحقل <code>pluginStatus</code> الذي تم إعادته. ويمكنك الرجوع إلى واجهة برمجة التطبيقات للإضافة التي تستخدمها للاطلاع على ما يجب أن تتوقعه من هذه الحقول وكيفية احتوائها على قيمها.


=== مثال ===
=== مثال ===
فيما يلي مثالًا موجزًا لتطبيق يستخدم الحدث <code>[[Cordova/events#resume|resume]]</code> والحدث <code>[[Cordova/events#pause|pause]]</code> لإدارة الحالة. ويستخدم البرنامج [[Cordova/cordova plugin camera|إضافة الكاميرا]] كمثال على كيفية استرداد نتائج استدعاء الإضافة من حمولة الحدث <code>[[Cordova/events#resume|resume]]</code>. ويتطلب الجزء من الشيفرة الذي يتعامل مع الكائن <code>event.pendingResult</code> للحدث <code>[[Cordova/events#resume|resume]]</code> الذي يتطلب الإصدار 5.1.0 وما بعده من كوردوفا-أندرويد:<syntaxhighlight lang="javascript">
فيما يلي مثالًا موجزًا لتطبيق يستخدم الحدث <code>[[Cordova/events#resume|resume]]</code> والحدث <code>[[Cordova/events#pause|pause]]</code> لإدارة الحالة. ويستخدم البرنامج [[Cordova/cordova plugin camera|إضافة الكاميرا]] كمثال على كيفية استرداد نتائج استدعاء الإضافة من حمولة الحدث <code>[[Cordova/events#resume|resume]]</code>. ويتطلب الجزء من الشيفرة الذي يتعامل مع الكائن <code>event.pendingResult</code> للحدث <code>[[Cordova/events#resume|resume]]</code> الذي يتطلب الإصدار 5.1.0 وما بعده من كوردوفا-أندرويد:<syntaxhighlight lang="javascript">
// This state represents the state of our application and will be saved and
// onPause() و  onResume() تمثل هذه الحالة حالة التطبيق وستُخزن وتُسترجع عبر
// restored by onResume() and onPause()
var appState = {
var appState = {
     takingPicture: true,
     takingPicture: true,
سطر 383: سطر 400:
     },
     },
     bindEvents: function() {
     bindEvents: function() {
         // Here we register our callbacks for the lifecycle events we care about
         // سنسجل رد النداء لأحداث دورة الحياة التي تهمنا
         document.addEventListener('deviceready', this.onDeviceReady, false);
         document.addEventListener('deviceready', this.onDeviceReady, false);
         document.addEventListener('pause', this.onPause, false);
         document.addEventListener('pause', this.onPause, false);
سطر 390: سطر 407:
     onDeviceReady: function() {
     onDeviceReady: function() {
         document.getElementById("take-picture-button").addEventListener("click", function() {
         document.getElementById("take-picture-button").addEventListener("click", function() {
             // Because the camera plugin method launches an external Activity,
             // لما أطلقت إضافة الكامير نشاطا خارجيا، فهناك احتمال أن يُنهى تطبيقنا قبل أن تُستدعى دوال رد النداء الخاصة
             // there is a chance that our application will be killed before the
             // بالفشل أو النجاح
             // success or failure callbacks are called. See onPause() and
             // حيث نخزن ونسترجع الحالة لمعالجة هذه الحالة onResume() و  onPause() انظر
            // onResume() where we save and restore our state to handle this case
             appState.takingPicture = true;
             appState.takingPicture = true;


سطر 407: سطر 423:
     },
     },
     onPause: function() {
     onPause: function() {
         // Here, we check to see if we are in the middle of taking a picture. If
         // نتحقق هنا إن كنا في طور التقاط صورة. إن كان الأمر كذلك، نرغب في حفظ حالتنا لكي 
         // so, we want to save our state so that we can properly retrieve the
         // onResume() نسترجع نتيجة الإضافة في
        // plugin result in onResume(). We also save if we have already fetched
         // نرغب كذلك في الحفظ إن كنا قد استرجعنا عنوان الصورة سلفا.
         // an image URI
         if(appState.takingPicture || appState.imageUri) {
         if(appState.takingPicture || appState.imageUri) {
             window.localStorage.setItem(APP_STORAGE_KEY, JSON.stringify(appState));
             window.localStorage.setItem(APP_STORAGE_KEY, JSON.stringify(appState));
سطر 416: سطر 431:
     },
     },
     onResume: function(event) {
     onResume: function(event) {
         // Here we check for stored state and restore it if necessary. In your
         // نتحقق هنا من الحلة المحفوظة ونسترجعها إن لزم الأمر.الخيار يعود لك، يمكنك الاستمرار بتعقب المواضع
         // application, it's up to you to keep track of where any pending plugin
         // التي تأتي منها نتائج الإضافة المعلقة، أي مواضع الشيفرة البرمجية التي أتي منها الاستدعاء
         // results are coming from (i.e. what part of your code made the call)
         // وكذلك الوسائط التي مررتها للإضافة إن لزم الأمر
        // and what arguments you provided to the plugin if relevant
         var storedState = window.localStorage.getItem(APP_STORAGE_KEY);
         var storedState = window.localStorage.getItem(APP_STORAGE_KEY);


سطر 426: سطر 440:
         }
         }


         // Check to see if we need to restore an image we took
         // التحقق من أننا نحتاج إلى حفظ الصورة التي أخذناها
         if(!appState.takingPicture && appState.imageUri) {
         if(!appState.takingPicture && appState.imageUri) {
             document.getElementById("get-picture-result").src = appState.imageUri;
             document.getElementById("get-picture-result").src = appState.imageUri;
         }
         }
         // Now we can check if there is a plugin result in the event object.
         // cordova-android 5.1.0+ يمكننا الآن التحقق إن كانت هناك نتيجة في كائن الحدث، وهذا يتطلب الإصدار
        // This requires cordova-android 5.1.0+
         else if(appState.takingPicture && event.pendingResult) {
         else if(appState.takingPicture && event.pendingResult) {
             // Figure out whether or not the plugin call was successful and call
             // تعني "OK" التحقق من فشل أو نجاح استدعاء الإضافة، ثم استدعاء رد النداء المناسب. في حالة إضافة الكاميرا،
            // the relevant callback. For the camera plugin, "OK" means a
             // أن النتيجة ناجحة، وأي نتيجة أخرى ستُؤول كفشل
             // successful result and all other statuses mean error
             if(event.pendingResult.pluginStatus === "OK") {
             if(event.pendingResult.pluginStatus === "OK") {
                 // The camera plugin places the same result in the resume object
                 // تضع إضافة الكاميرا النتيجة نفسها في كائن الاستئناف، حيث يُمرر إلى 
                 // as it passes to the success callback passed to getPicture(),
                 // getPictre() رد النداء الخاص بالنجاح والممرر إلى
                 // thus we can pass it to the same callback. Other plugins may
                 // وهكذا يمكننا تمريره إلى رد النداء نفسه. قد تعيد الإَضافات الأخرى نتائج أخرى.  
                // return something else. Consult the documentation for
                 // ارجع إلى توثيق الإضافة التي تستعمل لتتعلم كيف تؤول النتائج
                // whatever plugin you are using to learn how to interpret the
                 // result field
                 cameraSuccessCallback(event.pendingResult.result);
                 cameraSuccessCallback(event.pendingResult.result);
             } else {
             } else {
سطر 451: سطر 461:
}
}


// Here are the callbacks we pass to getPicture()
// getPicture() هاذان هما ردا النداء المُمرران إلى
function cameraSuccessCallback(imageUri) {
function cameraSuccessCallback(imageUri) {
     appState.takingPicture = false;
     appState.takingPicture = false;
سطر 491: سطر 501:
=== اختبار دورة حياة الواجهة ===
=== اختبار دورة حياة الواجهة ===
يوفر أندرويد إعداد مطور البرامج لاختبار تدمير النشاط على ذاكرة منخفضة. قم بتمكين الضبط "عدم الاحتفاظ بالنشاطات" (Don't keep activities) في قائمة خيارات المطور (Developer Options) على جهازك أو على المحاكي لمحاكاة سيناريوهات الذاكرة المنخفضة. يجب عليك دائمًا إجراء بعض الاختبارات باستخدام هذا الإعداد وذلك للتأكد من أن التطبيق الخاص بك يحتفظ بحالته بشكل صحيح.
يوفر أندرويد إعداد مطور البرامج لاختبار تدمير النشاط على ذاكرة منخفضة. قم بتمكين الضبط "عدم الاحتفاظ بالنشاطات" (Don't keep activities) في قائمة خيارات المطور (Developer Options) على جهازك أو على المحاكي لمحاكاة سيناريوهات الذاكرة المنخفضة. يجب عليك دائمًا إجراء بعض الاختبارات باستخدام هذا الإعداد وذلك للتأكد من أن التطبيق الخاص بك يحتفظ بحالته بشكل صحيح.
== انظر أيضًا ==
* [[Cordova/android upgrade|ترقية أندرويد]]
* [[Cordova/plugins android|تطوير الإضافات على منصة أندرويد]]
* [[Cordova/platform plugin versioning ref|إدارة إصدارات المنصات والإضافات]]
* [[Cordova/platforms ios|دليل التطوير على منصة iOS]]


== مصادر ==
== مصادر ==
* [https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html صفحة Android Platform Guide في توثيق كوردوفا الرسمي.]
* [https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html صفحة Android Platform Guide في توثيق كوردوفا الرسمي.]

المراجعة الحالية بتاريخ 14:49، 27 أغسطس 2021

يوضح هذا الدليل كيفية إعداد بيئة SDK لنشر تطبيقات كوردوفا لأجهزة أندرويد، وكيفية استخدام أدوات سطر الأوامر المتمحورة حول أندرويد اختياريًا في سير عمل التطوير الخاص بك. تحتاج إلى تثبيت Android SDK بغض النظر عما إذا كنت تريد استخدام أدوات الصدفة (shell) المتمحورة حول المنصة أو سطر الأوامر العابر للمنصات لأغراض التطوير. للمقارنة بين مساري التطوير، راجع صفحة نظرة عامة التي شُرح فيها كل مسار عمل على حدة. وللحصول على تفاصيل حول سطر الأوامر، انتقل إلى صفحة واجهة سطر الأوامر في كوردوفا.

المتطلبات والدعم

استعمال كوردوفا من أجل أندرويد يتطلب Android SDK الذي يمكن تثبيته على OS X أو لينكس أو ويندوز. راجع متطلبات النظام من أجل تثبيت Android SDK. تدعم أحدث حزمة من أندرويد في كوردوفا المستوى 28 للواجهة البرمجية (Android API-Level). يمكن العثور على مستويات Android API المعتمدة وإصدارات Android لإصدارات كوردوفا-أندرويد الماضية في الجدول التالي:

إصدار كوردوفا-أندرويد مستويات واجهة أندرويد البرمجية المدعومة إصدار أندرويد المقابل
‎8.X.X 1‎9 - 28 ‎4.4 - 9.0.0
‎7.X.X 1‎9 - 27 ‎4.4 - 8.1
6‎.X.X ‎16 - 26 4.1‎ - 8.0.0
5‎.X.X ‎14 - 23 ‎4.0 - 6.0.1
4.1‎.X ‎14 - 22 4.0‎ - 5.1
‎4.0.X ‎10 - 22 2.3.‎3 - 5.1
‎3.7.X ‎10 - 21 ‎2.3.3 - 5.0.2

يرجى ملاحظة أن الإصدارات المذكورة هنا لأجل حزمة كوردوفا-أندرويد (cordova-android) وليس من أجل سطر أوامر كوردوفا. ولأجل تحديد إصدار حزمة أندرويد من كوردوفا المثبت في مشروعك الخاص، قم بتنفيذ الأمر cordova platform ls في المجلد الذي يحتوي على المشروع الخاص بك.

كقاعدة عامة، تصبح إصدارات أندرويد غير مدعومة من قِبل كوردوفا إذا انخفضت إلى أقل من 5٪ على لوحة بيانات التوزيع من Google.

تثبيت المتطلبات

مجموعة تطوير جافا (JDK)

قم بتثبيت مجموعة تطوير جافا الإصدار JDK) 8). عند التثبيت على ويندوز، يجب أيضًا تعيين متغير البيئة JAVA_HOME وفقًا لمسار تثبيت JDK الخاص بك (اطلع على القسم إعداد متغيرات البيئة في الأسفل).

Gradle

بالنسبة لكوردوفا-أندرويد 6.4.0، أصبح Gradle مطلوبًا الآن تثبيته لبناء أندرويد.

عند التثبيت على ويندوز، يجب إضافة Gradle إلى المسار الخاص بك (راجع قسم إعداد متغيرات البيئة في الأسفل).

أندرويد SDK

ثبت Android Studio. توجد إرشادات التثبيت التفصيلية على الموقع بشكل واضح. عندما تفتح Android Studio للمرة الأولى سيتم إرشادك إلى كيفية تثبيت Android SDK.

إضافة حزم SDK

بعد تثبيت Android SDK، يجب أيضًا تثبيت الحزم لأي مستوى من مستويات واجهة برمجة التطبيقات التي ترغب في استهدافها. يوصى بتثبيت أعلى إصدارمن SDK  يدعمه إصدار كوردوفا-أندرويد الخاص بك (راجع قسم المتطلبات والدعم في الأعلى).

افتح Android SDK Manager (عبر الذهاب إلى Tools > SDK Manager في Android Studio أو عبر تنفيذ الأمر sdkmanager من الطرفية) وتأكد من تثبيت ما يلي:

  1. حزم SDK لمنصة أندرويد للنسخة المستهدفة من نظام أندرويد
  2. أدوات بناء حزم SDK لأندرويد الإصدار 19.1.0 أو أحدث
  3. مستودع دعم أندرويد (ستعثر عليه في أسفل التبويب "SDK Tools")

راجع توثيق أندرويد حول تثبيت حزم SDK لمزيد من التفاصيل.

ضبط متغيرات البيئة

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

  1. اضبط متغير البيئة JAVA_HOME على مكان تثبيت JDK الخاص بك.
  2. اضبط متغير البيئة ANDROID_HOME على موقع تثبيت Android SDK.
  3. يوصى أيضًا بإضافة المجلدات tools، و tools/bin، و platform-tools الخاصة بحزم Android SDK إلى PATH.

النظام OS X ولينكس

في النظام ماك أو لينكس، يمكنك استخدام محرر نصي لإنشاء أو تعديل الملف ‎~/.bash_profile. ولتعيين متغير بيئة، أضف خطًا يستخدم export مثل ذلك (استبدل المسار بالتثبيت المحلي):

export ANDROID_HOME=/Development/android-sdk/

لتحديث PATH، أضف خطًا يشبه ما يلي (استبدال المسارات بمواقع تثبيت Android SDK المحلي):

export PATH=${PATH}:/Development/android-sdk/platform-tools:/Development/android-sdk/tools

أعد تشغيل الطرفية لمعرفة سيريان مفعول هذا التغيير أو نفذ الأمر التالي عوضًا عن ذلك:

$ source ~/.bash_profile

نظام ويندوز

قد تختلف هذه الخطوات وفقًا لإصدار ويندوز المثبت. أغلق وأعد تشغيل أية نوافذ مفتوحة لموجه الأوامر (command prompt) بعد إجراء أية تغييرات للتحقق من تطبيقها.

  1. انقر فوق قائمة ابدأ (Start) في الزاوية السفلية اليسرى من سطح المكتب
  2. في شريط البحث، ابحث عن "متغيرات البيئة" (Environment Variables) واختر "تعديل متغيرات بيئة النظام" (Edit the system Environment Variables) من الخيارات التي تظهر لك
  3. في النافذة التي تظهر، انقر فوق زر "متغيرات البيئة" (Environment Variables)

لإنشاء متغيرات بيئة جديدة، انقر فوق "جديد" (New...‎) وأدخل اسم المتغير وقيمته.

لتعيين المتغير PATH، حدده ثم اضغط على "تعديل" (Edit). أضف بعد ذلك المدخلات في المواقع التابع للمتغير PATH. اطلع على المثال التالي (استبدل المسارات بمواقع تثبيت Android SDK المحلي:

C:\Users\[your user]\AppData\Local\Android\Sdk\platform-tools
C:\Users\[your user]\AppData\Local\Android\Sdk\tools

ضبط المشروع

إعداد محاكي

إذا كنت ترغب في تشغيل تطبيق كوردوفا الخاص بك على محاكي أندرويد، فستحتاج أولًا إلى إنشاء جهاز أندرويد افتراضي (AVD، اختصار للعبارة Android Virtual Device). راجع توثيق أندرويد لإدارة الأجهزة الافتراضية وضبط المحاكي وإعداد حساس التسارع.

بمجرد تكوين الجهاز الافتراضي الخاص بك بشكل صحيح، يجب أن تكون قادرًا على نشر تطبيق كوردوفا الخاص بك على المحاكي عن طريق تنفيذ الأمر التالي:

$ cordova run --emulator

ضبط Gradle

اعتبارًا من cordova-android@4.0.0، تم تصميم كوردوفا لمشاريع أندرويد باستخدام Gradle. للحصول على إرشادات حول البناء باستخدام Ant، راجع الإصدارات القديمة من التوثيق. يرجى ملاحظة أن البناء باستعمال Ant أصبح مهملًا بدءًا من الإصدار 25.3.0 لأدوات SDK للأندرويد.

ضبط خاصيات Gradle

من الممكن تكوين Gradle عن طريق تحديد قيم بعض خاصيات Gradle التي تعرضها كوردوفا. الخصائص التالية متاحة لتعيين:

الخاصية الوصف
cdvBuildMultipleApks إذا تم تعيين هذه الخاصية، فسيتم إنشاء ملفات APK متعددة: واحد لكل نظام أساسي مدمج مدعوم بمشاريع المكتبة (x86، ARM، ...إلخ). قد يكون هذا مهمًا إذا كان مشروعك يستخدم مكتبات أصلية كبيرة، مما قد يزيد بشكل كبير من حجم ملف APK الذي تم إنشاؤه. إذا لم يتم تعيينها، فسيتم إنشاء ملف APK واحد يمكن استخدامه على جميع الأجهزة.
cdvVersionCode تستبدل مجموعة كود الإصدار في AndroidManifest.xml.
cdvReleaseSigningPropertiesFile القيمة الافتراضية: release-signing.properties

تحدد هذه الخاصية مسار الملف ‎.properties الذي يحتوي على معلومات التوقيع لبنيات الإصدار (انظر قسم توقيع التطبيق).

cdvDebugSigningPropertiesFile القيمة الافتراضية: debug-signing.properties

تحدد مسار الملف ‎.properties الذي يحتوي على معلومات تسجيل لبنيات التنقيح (انظر قسم توقيع التطبيق). هذه الخاصية مفيدة عندما تحتاج إلى مشاركة مفتاح توقيع مع مطورين آخرين.

cdvMinSdkVersion تستبدل قيمة المجموعة minSdkVersion في الملف AndroidManifest.xml. هذه الخاصية مفيدة عند إنشاء ملفات APK متعددة استنادًا إلى إصدار SDK.
cdvBuildToolsVersion تستبدل القيمة android.buildToolsVersion التي يتم اكتشافها تلقائيًا.
cdvCompileSdkVersion تستبدل القيمة android.compileSdkVersion التي يتم اكتشافها تلقائيًا.

تستطيع أن تضبط هذه الخصائص بواسطة واحدة من هذه الطرق الأربعة:

  • عن طريق ضبط متغيرات البيئة مثل:
$ export ORG_GRADLE_PROJECT_cdvMinSdkVersion=20
$ cordova build android
  • بواسطة استخدام الراية ‎--gradleArg أثناء استعمال الأمر build أو run في سطر أوامر كوردوفا مثل:
 $ cordova run android -- --gradleArg=-PcdvMinSdkVersion=20
  • بواسطة وضع ملف اسمه gradle.properties  في مجلد منصة أندرويد (<your-project>/platforms/android)  وادخال الخصائص فيه بالشكل التالي:
# In <your-project>/platforms/android/gradle.properties
cdvMinSdkVersion=20
  • بواسطة توسيع  build.gradle عن طريق الملف build-extras.gradle وضبط الخاصية بالشكل التالي:
// In <your-project>/platforms/android/build-extras.gradle
ext.cdvMinSdkVersion = 20

يتضمن الخياران الأخيران تضمين ملف إضافي في مجلد منصة أندرويد الخاص بك. وبصفة عامة، لا يمكن تحرير محتويات هذا المجلد لأنه من السهل أن فقدان أو استبدال هذه التغييرات. بدلًا من ذلك، يجب نسخ هذين الملفين من موقع آخر إلى هذا المجلد كجزء من أمر البناء باستخدام الخطاف before_build.

توسيع build.gradle

إذا كنت بحاجة إلى تخصيص build.gradle، بدلًا من تحريره مباشرةً، فيجب إنشاء ملف شقيق باسم build-extras.gradle. سيتم تضمين هذا الملف بواسطة build.gradle الرئيسي عند وجوده. يجب وضع هذا الملف في مجلد منصة أندرويد (‎(<your-project>/platform/android، لذا يُنصح بنسخه عبر برنامج نصي مرفق بالخطاف before_build. إليك هذا المثال:

// build-extras.gradle مثال عن
// `build.gradle` يُضمّن هذا الملف في بداية

// وإعادة تعيين القيم الافتراضية - build.gradle يمكن إعداد بعض الخاصيات - انظر 
// ext.cdvDebugSigningPropertiesFile = '../../android-debug-keys.properties'

// `build.gradle` إعداد عادي لـ
android {
  defaultConfig {
    testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
  }
}
dependencies {
  androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
  }
}

// `build.gradle` تنفيذ الشيفرة في نهاية  `ext.postBuildExtras` عند تعيينها، تتيح الدالة 
ext.postBuildExtras = {
    android.buildTypes.debug.applicationIdSuffix = '.debug'
}

لاحظ أن الإضافات ممكن أن تتضمن ملفات build-extras.gradle  عن طريق:

<framework src="some.gradle" custom="true" type="gradleReference" />

ضبط إصدار الشيفرة

إن أردت تغيير إصدار الشيفرة للتطبيق apk المولد، فاضبط الخاصية android-versionCode في العنصر widget في الملف config.xml الخاص بالتطبيق. إذا لم يتم تعيين الخاصية android-versionCode، فسيتم تحديد رمز الإصدار باستخدام الخاصية version. على سبيل المثال، إذا كان الإصدار هو MAJOR.MINOR.PATCH:

versionCode = MAJOR * 10000 + MINOR * 100 + PATCH

إذا كان التطبيق الخاص بك قد فعَّل خاصية Gradle التي هي CdvBuildMultipleApks (راجع قسم ضبط خاصيات Gradle في الأعلى)، فسيتم ضرب إصدار الشيفرة الخاص بتطبيقك أيضًا بالقيمة 10 بحيث يمكن استخدام آخر رقم من الشيفرة للإشارة إلى البنية التي تم إنشاء apk لها. ستجرى عملية الضرب هذه بغض النظر عما إذا كان رمز الإصدار مأخوذًا من الخاصية android-versionCode أو تم إنشاؤه باستخدام الإصدار. كن على علم بأن بعض الإضافات المضافة إلى مشروعك (بما في ذلك Cordova-plugin-crosswalk-webview) قد تقوم بتعيين خاصية Gradle هذه تلقائيًا.

ملاحظة مهمة: عند تحديث الخاصية android-versionCode، فإنه ليس من الحكمة زيادة إصدار الشيفرة المأخوذ من التطبيقات apk المبنية. فبدلًا من ذلك، يجب زيادة الشيفرة استنادًا إلى القيمة الموجودة في الخاصية android-versionCode في الملف config.xml. ويرجع ذلك إلى أنَّ الخاصية cdvBuildMultipleApks تتسبب في ضرب إصدار الشيفرة المراد ضربه بالقيمة 10 في التطبيقات apk المبنية، وبالتالي فإن استخدام هذه القيمة سيؤدي إلى أن يكون إصدار الشيفرة التالي لديك 100 مرة قدر الأصلي وهكذا دواليك.

توقيع التطبيق

أولاً، يجب قراءة متطلبات توقيع تطبيق أندرويد.

استخدام الرايات

لتوقيع تطبيق، تحتاج إلى المعاملات التالية:

المعامل الراية الوصف
المخزن الرئيسي (المفتاحي) ‎--keystore المسار إلى ملف التنفيذ (binary file) الذي يمكنه الاحتفاظ بمجموعة من المفاتيح.
كلمة المرور للمخزن الرئيسي ‎--storePassword إنشاء كلمة مرور للدخول إلى المخزن الرئيسي (المفتاحي).
الاسم البديل ‎--alias الاسم البديل المعرف الذي يحدد المفتاح الخاص المستخدم الدخول.
كلمة المرور ‎--password كلمة المرور المخصصة لمفتاح خاص.
انواع المخزن الرئيسي (المخزن المفتاحي) ‎--keystoreType القيمة الافتراضية هي: auto-detect أي الاكتشاف التلقائي الذي يستند على لاحقة الملف والتي إما أن تكون pkcs12 أو jks.

يمكن تحديد هذه المعاملات باستخدام وسائط سطر الأوامر أعلاه مع الأمر build والأمر run في سطر أوامر كوردوفا.

ملاحظة: يجب أن تستخدم الرمز -- بشكل مزدوج للإشارة إلى أنها وسائط خاصة بالمنصة. اطلع على المثال التالي:

cordova run android --release -- --keystore=../my-release-key.keystore --storePassword=password --alias=alias_name --password=password

استخدام build.json

بدلاً من ذلك، يمكنك تحديدها في ملف ضبط البناء (الذي هو build.json) باستخدام الوسيط ‎--buildConfig مع نفس الأوامر. إليك نموذجًا من ملف ضبط البناء:

{
    "android": {
        "debug": {
            "keystore": "../android.keystore",
            "storePassword": "android",
            "alias": "mykey1",
            "password" : "password",
            "keystoreType": ""
        },
        "release": {
            "keystore": "../android.keystore",
            "storePassword": "",
            "alias": "mykey2",
            "password" : "password",
            "keystoreType": ""
        }
    }
}

بالنسبة إلى توقيع الإصدار، يمكن استبعاد كلمات المرور وسيصدر نظام الإنشاء نافذة منبثقة تطلب كلمة المرور.

هناك أيضا دعم لدمج ومطابقة وسائط ومعاملات سطر الأوامر في build.json. ستحصل القيم من وسائط سطر الأوامر على الأسبقية. هذا يمكن أن يكون مفيدًا لتحديد كلمات المرور على سطر الأوامر.

استخدام Gradle

يمكنك أيضًا تحديد خصائص التوقيع من خلال تضمين الملف ‎.properties والإشارة إليه باستخدام خاصيات Gradle التي هي cdvReleaseSigningPropertiesFile و cdvDebugSigningPropertiesFile (راجع قسم ضبط خاصيات Gradle في الأعلى). يجب أن يبدو الملف كما يلي:

storeFile=relative/path/to/keystore.p12
storePassword=SECRET1
storeType=pkcs12
keyAlias=DebugSigningKey
keyPassword=SECRET2

الخاصية storePassword و keyPassword اختيارية، وستتم مطالبتك بها إذا تم حذفها.

التنقيح

للحصول على تفاصيل حول أدوات تصحيح الأخطاء (debugging) التي تأتي مجمعة مع Android SDK، راجع توثيق مطوري برامج أندرويد لتصحيح الأخطاء. بالإضافة إلى ذلك، يوفر توثيق مطوري برامج أندرويد لتصحيح الأخطاء لتطبيقات الويب مقدمة لتصحيح أخطاء جزء التطبيق الذي يعمل في عرض الويب.

فتح مشروع في Android Studio

يمكن فتح مشاريع كوردوفا للأندرويد في Android Studio. قد يكون ذلك مفيدًا إذا كنت ترغب في استخدام أدوات التنقيح المدمجة في Android Studio أو إذا كنت تعمل على تطوير إضافات أندرويد. يرجى ملاحظة أنه عند فتح مشروعك في Android Studio، يوصى بعدم تعديل شيفرتك في البيئة التطويرية هنالك (IDE) لأن ذلك سيؤدي إلى تعديل الشيفرة في المجلد platforms في مشروعك (وليس المجلد www) وستكون التغييرات عرضةً للاستبدال. بدلًا من ذلك، قم بتحرير المجلد www ونسخ التغييرات التي أجريتها عن طريق تنفيذ الأمر cordova build.

يجب على مطوري الإضافات الراغبين في تحرير الشيفرة الأصلية في بيئة تطوير Android Studio استخدام الراية ‎--link عند إضافة الإضافة للمشروع عن طريق الأمر  cordova plugin add. سيؤدي هذا إلى ربط الملفات بحيث تلك التغييرات التي تطرأ على ملفات الإضافة في المجلد platforms تنعكس في المجلد المصدري للإضافة (والعكس صحيح).

لفتح مشروع كوردوفا لتطبيق أندرويد في Android Studio، اتبع الخطوات التالية:

  1. شغل Android Studio.
  2. حدد Import Project ‏(Eclipse ADT, Gradle, etc).
    فتح Android Studio ثم تحديد الخيار Import Project من الخيارات الظاهرة لفتح مشروع كوردوفا لتطبيق أندرويد.
    فتح Android Studio ثم تحديد الخيار Import Project من الخيارات الظاهرة لفتح مشروع كوردوفا لتطبيق أندرويد فيه.
  3. حدد مجلد منصة أندرويد في مشروعك (‎<your-project>/platforms/android).
    تحديد مجلد منصة أندرويد في مشروعك الذي أنشئ باستعمال كوردوفا وذلك لفتحه في Android Studio.
    تحديد مجلد منصة أندرويد في مشروعك الذي أنشئ باستعمال كوردوفا وذلك لفتحه في Android Studio.
  4. بالنسبة إلى سؤال Gradle Sync، يمكنك ببساطة الإجابة بنعم.

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

اكتمال استيراد تطبيق أندرويد أنشئ باستعمال كوردوفا في Android Studio.
اكتمال استيراد تطبيق أندرويد أنشئ باستعمال كوردوفا في Android Studio.

سير العمل المرتكز على منصة واحدة

يتضمن كوردوفا-أندرويد عددًا من النصوص البرمجية (scripts) التي تسمح باستخدام المنصة بدون سطر أوامر كوردوفا الكامل. قد يوفر لك مسار التطوير هذا مجموعة أكبر من خيارات التطوير في مواقف معينة لا تجدها في سير العمل العابر للمنصات عبر سطر الأوامر. على سبيل المثال، تحتاج إلى استخدام أدوات الصدفة (shell) عند نشر عارض WebView مخصص إلى جانب المكونات الأصلية. قبل استخدام مسار التطوير هذا، يجب عليك تهيئة بيئة Android SDK كما هو موضح في قسم المتطلبات والدعم أعلاه.

لكل من النصوص الموضحة أدناه، ارجع إلى واجهة سطر أوامر كوردوفا للحصول على مزيد من المعلومات حول الوسائط والاستعمالات. يملك كل برنامج نصي اسمًا يطابق أمرًا مقابلًا له في سطر الأوامر. على سبيل المثال،إنَّ Cordova-android/bin/create يعادل الأمر cordova create.

للبدء، قم بتنزيل حزمة أندرويد-كوردوفا من npm أو Github. لإنشاء مشروع باستخدام هذه الحزمة، قم بتشغيل البرنامج النصي create في المجلد bin:

$ cordova-android/bin/create

سيكون للمشروع الذي تم إنشاؤه مجلدًا باسم cordova بداخله يحتوي على برامج نصية لأوامر كوردوفا الخاصة بالمشروع (مثل الأمر run، و build، ...إلخ). بالإضافة إلى ذلك، سيحتوي المشروع على هيكل مختلف عن مشروع كوردوفا العادي. ومن الجدير بالذكر أن المجلد ‎/www نقل إلى ‎/assets/www.

لتثبيت إضافات في هذا المشروع، استخدم الأداة Plugman المساعدة.

الترقية

انتقل إلى هذه الصفحة للحصول على إرشادات لترقية إصدار كوردوفا-أندرويد.

دليل دورة الحياة

كوردوفا وأندرويد

تتكون تطبيقات أندرويد الأصيلة عادةً من سلسلة من النشاطات (Activities) التي يتفاعل معها المستخدم. يمكن اعتبار هذه النشاطات كشاشات فردية تشكل تطبيقًا، إذ إن مهام مختلفة في التطبيق سيكون لها في الغالب نشاطها الخاص حيث تحتوي كل واجهة على دورة حياتها الخاصة التي يتم الحفاظ عليها أثناء دخول الواجهة من واجهة جهاز المستخدم وتركها.

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

حدث كوردوفا المكافيء العام لأندرويد المعنى
deviceready onCreate()‎ التطبيق قيد البدء (ليس من جهة الخلفية).
pause onPause()‎ التطبيق قيد الانتقال إلى الخلفية.
resume ‎onResume()‎ التطبيق يعود إلى المقدمة.

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

ما الذي يجعل أندرويد مختلفًا؟

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

متى يمكن أن يحدث هذا؟

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

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

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

  1. يتفاعل المستخدم مع تطبيقك ويحتاج إلى التقاط صورة.
  2. يُطلَق المكون الإضافي للكاميرا واجهة الكاميرا الأصلية.
    1. يتم دفع واجهة كوردوفا إلى الخلفية (يتم تشغيل الحدث pause).
  3. يأخذ المستخدم صورة.
  4. ينتهي نشاط الكاميرا.
    1. يتم نقل واجهة كوردوفا إلى المقدمة (يتم إطلاق الحدث resume).
  5. يتم إرجاع المستخدم إلى التطبيق الخاص بك حيث توقف.

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

  1. يتفاعل المستخدم مع تطبيقك ويلزم التقاط صورة.
  2. يُطلق المكون الإضافي للكاميرا واجهة الكاميرا الأصلية.
    1. نظام التشغيل يدمر واجهة كوردوفا (يتم إطلاق الحدث pause).
  3. يأخذ المستخدم صورة.
  4. تنتهي واجهة الكاميرا.
    1. يقوم نظام التشغيل بإعادة إنشاء نشاط كوردوفا (يتم إطلاق الحدث deviceready والحدث resume)
  5. يشعر المستخدم بالارتباك حول سبب عودته فجأة إلى شاشة تسجيل الدخول إلى تطبيقك.

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

احترام دورة الحياة

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

هناك عامل إضافي واحد في المثال أعلاه لا ينطبق إلا في الحالة التي تمت مناقشتها ثانيًا (أي عندما تبدأ إضافة ما نشاطًا خارجيًا). حيث لم تكن حالة التطبيق مفقودة فقط عندما انتهى المستخدم من التقاط صورة، ولكن كانت أيضًا خلال التقاطها. عادةً، سيتم تسليم هذه الصورة إلى التطبيق الخاص بك من خلال رد نداء مسجل من قبل في إضافة الكاميرا. ومع ذلك، عندما تم تدمير العارض WebView، فإنَّ رد النداء هذا - ولحسن الحظ - قد فقد إلى الأبد. يوفر الإصدار 5.1.0 وما بعده من كوردوفا-أندرويد وسيلة لجلب النتيجة لاستدعاء تلك الإضافة عند استئناف عمل تطبيقك.

استرداد نتائج رد نداء إضافة (الإصدار 5.1.0 وما بعده من كوردوفا-أندرويد)

عندما يدمر نظام التشغيل نشاط كوردوفا الذي تم دفعه إلى الخلفية عن طريق إضافة، يتم فقدان أي عمليات استرجاع معلقة أيضًا. هذا يعني أنه إذا قمت بتمرير رد نداء إلى الإضافة التي بدأت نشاطًا جديدًا (مثل إضافة الكاميرا)، فلن يتم إطلاق رد النداء هذا عند إعادة إنشاء التطبيق. ومع ذلك، بدءًا من الإصدار 5.1.0 وما بعده من كوردوفا-أندرويد، ستتضمن حمولة الحدث resume أية نتائج معلقة للإضافة من طلب الإضافة الذي بدأ النشاط الخارجي الذي تم إجراؤه قبل تدمير النشاط.

تلتزم حمولة الحدث resume بالتنسيق التالي:

{
    action: "resume",
    pendingResult: {
        pluginServiceName: string,
        pluginStatus: string,
        result: any
    }
}

يتم تعريف حقول هذه الحمولة على النحو التالي:

  • pluginServiceName: اسم الإضافة التي تعيد النتيجة (مثل "Camera" عند استعمال إضافة الكاميرا). يمكن العثور على هذا في الوسم <name> للملف plugin.xml للإضافة.
  • pluginStatus: حالة استدعاء الإضافة (انظر أدناه).
  • result: أيًا كانت نتيجة استدعاء الإضافة.

تتضمن القيم المحتملة للحقل pluginStatus في الحقل pendingResult ما يلي:

  • "OK": ثم استدعاء الإضافة بنجاح.
  • "No Result": انتهى استدعاء الإضافة دون نتيجة.
  • "Error": أدى استدعاء الإضافة إلى حدوث بعض الأخطاء العامة.
  • أخطاء متنوعة أخرى:
    • "Class not found"
    • "Illegal access"
    • "Instantiation error"
    • "Malformed url"
    • "IO error"
    • "Invalid action"
    • "JSON error"

يرجى ملاحظة أن الأمر متروك للإضافة لتقرر ما هو موجود في الحقل result ومعنى الحقل pluginStatus الذي تم إعادته. ويمكنك الرجوع إلى واجهة برمجة التطبيقات للإضافة التي تستخدمها للاطلاع على ما يجب أن تتوقعه من هذه الحقول وكيفية احتوائها على قيمها.

مثال

فيما يلي مثالًا موجزًا لتطبيق يستخدم الحدث resume والحدث pause لإدارة الحالة. ويستخدم البرنامج إضافة الكاميرا كمثال على كيفية استرداد نتائج استدعاء الإضافة من حمولة الحدث resume. ويتطلب الجزء من الشيفرة الذي يتعامل مع الكائن event.pendingResult للحدث resume الذي يتطلب الإصدار 5.1.0 وما بعده من كوردوفا-أندرويد:

// onPause() و  onResume() تمثل هذه الحالة حالة التطبيق وستُخزن وتُسترجع عبر 
var appState = {
    takingPicture: true,
    imageUri: ""
};

var APP_STORAGE_KEY = "exampleAppState";

var app = {
    initialize: function() {
        this.bindEvents();
    },
    bindEvents: function() {
        // سنسجل رد النداء لأحداث دورة الحياة التي تهمنا
        document.addEventListener('deviceready', this.onDeviceReady, false);
        document.addEventListener('pause', this.onPause, false);
        document.addEventListener('resume', this.onResume, false);
    },
    onDeviceReady: function() {
        document.getElementById("take-picture-button").addEventListener("click", function() {
            // لما أطلقت إضافة الكامير نشاطا خارجيا، فهناك احتمال أن يُنهى تطبيقنا قبل أن تُستدعى دوال رد النداء الخاصة
            //  بالفشل أو النجاح
            //  حيث نخزن ونسترجع الحالة لمعالجة هذه الحالة onResume() و  onPause() انظر
            appState.takingPicture = true;

            navigator.camera.getPicture(cameraSuccessCallback, cameraFailureCallback,
                {
                    sourceType: Camera.PictureSourceType.CAMERA,
                    destinationType: Camera.DestinationType.FILE_URI,
                    targetWidth: 250,
                    targetHeight: 250
                }
            );
        });
    },
    onPause: function() {
        // نتحقق هنا إن كنا في طور التقاط صورة. إن كان الأمر كذلك، نرغب في حفظ حالتنا لكي  
        // onResume()  نسترجع نتيجة الإضافة في
        // نرغب كذلك في الحفظ إن كنا قد استرجعنا عنوان الصورة سلفا.
        if(appState.takingPicture || appState.imageUri) {
            window.localStorage.setItem(APP_STORAGE_KEY, JSON.stringify(appState));
        }
    },
    onResume: function(event) {
        // نتحقق هنا من الحلة المحفوظة ونسترجعها إن لزم الأمر.الخيار يعود لك، يمكنك الاستمرار بتعقب المواضع
        // التي تأتي منها نتائج الإضافة المعلقة، أي مواضع الشيفرة البرمجية التي أتي منها الاستدعاء
        // وكذلك الوسائط التي مررتها للإضافة إن لزم الأمر
        var storedState = window.localStorage.getItem(APP_STORAGE_KEY);

        if(storedState) {
            appState = JSON.parse(storedState);
        }

        // التحقق من أننا نحتاج إلى حفظ الصورة التي أخذناها
        if(!appState.takingPicture && appState.imageUri) {
            document.getElementById("get-picture-result").src = appState.imageUri;
        }
        // cordova-android 5.1.0+ يمكننا الآن التحقق إن كانت هناك نتيجة في كائن الحدث، وهذا يتطلب الإصدار
        else if(appState.takingPicture && event.pendingResult) {
            // تعني "OK" التحقق من فشل أو نجاح استدعاء الإضافة، ثم استدعاء رد النداء المناسب. في حالة إضافة الكاميرا،
            // أن النتيجة ناجحة، وأي نتيجة أخرى ستُؤول كفشل
            if(event.pendingResult.pluginStatus === "OK") {
                //  تضع إضافة الكاميرا النتيجة نفسها في كائن الاستئناف، حيث يُمرر إلى   
                // getPictre() رد النداء الخاص بالنجاح والممرر إلى
                // وهكذا يمكننا تمريره إلى رد النداء نفسه. قد تعيد الإَضافات الأخرى نتائج أخرى. 
                // ارجع إلى توثيق الإضافة التي تستعمل لتتعلم كيف تؤول النتائج
                cameraSuccessCallback(event.pendingResult.result);
            } else {
                cameraFailureCallback(event.pendingResult.result);
            }
        }
    }
}

// getPicture() هاذان هما ردا النداء المُمرران إلى 
function cameraSuccessCallback(imageUri) {
    appState.takingPicture = false;
    appState.imageUri = imageUri;
    document.getElementById("get-picture-result").src = imageUri;
}

function cameraFailureCallback(error) {
    appState.takingPicture = false;
    console.log(error);
}

app.initialize();

ملف HTML المقابل:

<!DOCTYPE html>

<html>
    <head>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <title>Cordova Android Lifecycle Example</title>
    </head>
    <body>
        <div class="app">
            <div>
                <img id="get-picture-result" />
            </div>
            <Button id="take-picture-button">Take Picture</button>
        </div>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
    </body>
</html>

اختبار دورة حياة الواجهة

يوفر أندرويد إعداد مطور البرامج لاختبار تدمير النشاط على ذاكرة منخفضة. قم بتمكين الضبط "عدم الاحتفاظ بالنشاطات" (Don't keep activities) في قائمة خيارات المطور (Developer Options) على جهازك أو على المحاكي لمحاكاة سيناريوهات الذاكرة المنخفضة. يجب عليك دائمًا إجراء بعض الاختبارات باستخدام هذا الإعداد وذلك للتأكد من أن التطبيق الخاص بك يحتفظ بحالته بشكل صحيح.

انظر أيضًا

مصادر