لا يتكون التطبيق دائمًا من شاشة واحدة. على سبيل المثال، أنشأنا جدا برنامج مفيدويريد المستخدم أن يعرف من هو مؤلفه. ينقر على زر "حول" ويتم نقله إلى شاشة جديدة، حيث توجد معلومات مفيدة حول إصدار البرنامج، والمؤلف، وعنوان موقع الويب، وعدد القطط التي يمتلكها المؤلف، وما إلى ذلك. فكر في شاشة النشاط كصفحة ويب بها رابط إلى صفحة أخرى. إذا نظرت إلى الكود الموجود في الملف MainActivity.javaمن الدروس السابقة، سترى أن صفنا النشاط الرئيسيينطبق أيضا على نشاط(أو ورثته) أو بتعبير أدق ورثت منه.
يقوم MainActivity من الفئة العامة بتوسيع AppCompatActivity
كما قد تتخيل، يجب علينا إنشاء فئة جديدة يمكن أن تكون مشابهة لـ النشاط الرئيسيثم قم بالتبديل إليه بطريقة أو بأخرى عند الضغط على الزر.
بالنسبة للتجربة، سنأخذ البرنامج من الدرس الأول ونستخدم زرًا للتجارب (أو ننشئ مشروعًا جديدًا بزر واحد على الشاشة). بعد ذلك، لنقم بإنشاء نموذج جديد لعرضه معلومات مفيدة. على سبيل المثال، دعونا نظهر للمستخدم ما تفعله القطة عندما تتحرك يمينًا ويسارًا. أوافق، هذا جدا معلومات مهمةالذي يوفر مفتاح الكون.
سنقوم بإنشاء نشاط جديد يدويًا، على الرغم من قيام الاستوديو بذلك قوالب جاهزة. ولكن لا يوجد شيء معقد، ومن أجل فهم أفضل، من المفيد القيام بكل شيء يدويًا.
لنقم بإنشاء ملف ترميز XML جديد Activity_about.xmlفي مجلد الدقة/التخطيط. انقر بزر الماوس الأيمن على المجلد تَخطِيطواختر من قائمة السياق جديد | ملف تخطيط الموارد. سيظهر مربع حوار. في الحقل الأول، أدخل اسم الملف Activity_about. في الثانية، تحتاج إلى إدخال العنصر الجذر. بشكل افتراضي هناك تخطيط القيد. امسح النص وأدخل عرض التمرير. إدخال بضعة أحرف يكفي للاستوديو لاقتراح خيارات جاهزة؛ يمكنك الضغط على Enter على الفور دون انتظار إدخال الكلمة كاملة:
سوف تحصل على الفراغ المقابل الذي سنقوم بإدراج العنصر فيه عرض النص.
سيتم استرداد المعلومات من الموارد، وهي مورد السلسلة about_text. الآن تم تمييزه باللون الأحمر، مما يشير إلى غياب المعلومات. كان من الممكن الضغط البديل + أدخلوأدخل النص في مربع الحوار. لكن بالنسبة لمثالنا، لن تعمل هذه الطريقة، نظرًا لأن النص سيكون متعدد الأسطر باستخدام أحرف التحكم. لذلك دعونا نفعل ذلك بشكل مختلف. دعونا نفتح الملف الدقة/القيم/strings.xmlوأدخل النص التالي يدويًا:
استخدمنا أبسط علامات تنسيق نص HTML مثل , , . على سبيل المثال، يكفي تسليط الضوء بالخط العريض على الكلمات التي تتعلق بالقطة واتجاه الحركة. لترجمة النص إلى خط جديداستخدام الرموز \n. دعونا نضيف مورد سلسلة آخر لعنوان الشاشة الجديدة:
لقد اكتشفنا العلامات. بعد ذلك تحتاج إلى إنشاء فئة للنافذة AboutActivity.java. اختر من القائمة ملف | جديد | فئة جافاواملأ الحقول المطلوبة. في البداية، يكفي الإشارة إلى الاسم فقط. ثم سوف تتعامل مع المجالات الأخرى.
دعونا نحصل على الفراغ.
الآن الفصل فارغ تقريبًا. دعونا نضيف الكود يدويا. يجب أن يرث الفصل من فئة مجردة نشاطأو أقاربه مثل نشاط التجزئة, AppCompatActivityإلخ. دعونا نضيف يمتد النشاط. يجب أن يكون لفئة النشاط طريقة عند الإنشاء (). ضع مؤشر الفأرة داخل الفصل واختر من القائمة الكود | طرق التجاوز(السيطرة+O). في مربع الحوار نبحث عن الفئة المطلوبة، يمكنك كتابة الأحرف الأولى على لوحة المفاتيح للبحث السريع. في الطريقة التي تم إنشاؤها تحتاج إلى استدعاء الطريقة setContentView()، والذي سيقوم بتحميل العلامة المعدة على الشاشة. سيكون لدينا هذا الخيار.
حزمة ru.alexanderklimov.helloworld; import android.app.Activity; استيراد android.os.Bundle؛ /** * أنشأه ألكسندر كليموف بتاريخ 2014/01/12.
*/ فئة عامة AboutActivity توسع النشاط ( @Override protected void onCreate(Bundle saveInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.activity_about); ) ) النشاط الرئيسيالآن يأتي الجزء الأكثر أهمية. مهمتنا هي الانتقال إلى شاشة جديدة عندما نضغط على الزر الموجود على الشاشة الأولى. دعونا نعود إلى الفصل
. لنكتب معالج النقر على الزر:
الفراغ العام عند النقر (عرض العرض) ( Intent Intent = new Intent(MainActivity.this, AboutActivity.class); startActivity(intent);)
لقد استخدمت هنا طريقة معالجة النقر على الزر الموضحة في الدرس. لبدء شاشة جديدة تحتاج إلى إنشاء مثيل للفئةنية وحدد الفصل الحالي في المعلمة الأولى، والفصل الذي تريد الانتقال إليه في المعلمة الثانية، لدينا هذاحول النشاط . بعد هذا يتم استدعاء الطريقةبداية النشاط ()
إذا حاولت الآن اختبار التطبيق في المحاكي، فسوف تتلقى رسالة خطأ. ماذا فعلنا الخطأ؟ لقد فاتنا خطوة واحدة مهمة. تحتاج إلى تسجيل واحدة جديدة نشاطفي البيان AndroidManifest.xml. ابحث عن هذا الملف في مشروعك وانقر عليه نقرًا مزدوجًا. سيتم فتح نافذة تحرير الملف. أضف علامة جديدة
هذا هو المكان الذي يكون فيه مورد السلسلة مفيدًا about_title. نقوم بتشغيل التطبيق، انقر فوق الزر والحصول على نافذة حول البرنامج. وهكذا تعلمنا كيفية إنشاء نافذة جديدة واستدعائها بالنقر فوق الزر. ولدينا الآن برنامج مريح للغاية تحت تصرفنا - الآن سيكون لدينا دائمًا في متناول اليد تلميح لما تفعله القطة عندما تتجه يسارًا.
مرة أخرى، يرجى ملاحظة أن فئة النشاط الثانية التي تم إنشاؤها يجب أن ترث من الفئة نشاطأو ما شابه ذلك ( نشاط القائمةوما إلى ذلك)، لديك ملف ترميز XML (إذا لزم الأمر) ويتم تحديده في البيان.
بعد استدعاء الطريقة . بعد هذا يتم استدعاء الطريقةسيتم إطلاق نشاط جديد (في هذه الحالة وحدد الفصل الحالي في المعلمة الأولى، والفصل الذي تريد الانتقال إليه في المعلمة الثانية، لدينا هذا)، سيصبح مرئيًا وينتقل إلى أعلى المكدس الذي يحتوي على المكونات قيد التشغيل. عند استدعاء الأسلوب ينهي()من نشاط جديد (أو عند الضغط على مفتاح إرجاع الأجهزة) سيتم إغلاقه وإزالته من المكدس. يمكن للمطور أيضًا الانتقال إلى النشاط السابق (أو أي نشاط آخر) باستخدام نفس الطريقة . بعد هذا يتم استدعاء الطريقة.
المبرمجون، مثل القطط، مخلوقات كسولة. تذكر دائمًا أنه بالنسبة للنشاط الذي تحتاج إلى إنشاء ترميز وفئة ترث منه نشاط، ثم لا تنس تسجيل الفصل في البيان - حسنًا.
في هذه الحالة، اختر من القائمة ملف | جديد | النشاط | النشاط الأساسي(أو قالب آخر). بعد ذلك، ستظهر النافذة المألوفة لإنشاء نشاط جديد. املأ الحقول المطلوبة.
انقر على الزر ينهيوسيكون النشاط جاهزا. للتحقق من ذلك، افتح ملف البيان وتحقق من وجود إدخال جديد. أنا لا أتحدث حتى عن ملفات الفصل والترميز، فسوف تظهر أمامك من تلقاء نفسها.
أضف زرًا جديدًا إلى شاشة النشاط الرئيسية بنفسك واكتب رمزًا للتبديل إلى النشاط الذي تم إنشاؤه.
في البداية، أنصحك بإنشاء جميع المكونات الضرورية للنشاط الجديد يدويًا حتى تتمكن من فهم العلاقة بين الفصل والترميز والبيان. وعندما تتقن الأمر، يمكنك استخدام معالج إنشاء النشاط لتسريع عملك.
استخدمنا مثالًا بسيطًا للاتصال بشاشة نشاط أخرى. في بعض الأحيان، لا تحتاج فقط إلى استدعاء شاشة جديدة، بل تحتاج أيضًا إلى نقل البيانات إليها. على سبيل المثال، اسم المستخدم. في هذه الحالة، تحتاج إلى استخدام منطقة خاصة extraData، التي يمتلكها الفصل لبدء شاشة جديدة تحتاج إلى إنشاء مثيل للفئة.
منطقة extraDataهي قائمة الأزواج المفتاح/القيمة، والذي ينتقل مع النية. تُستخدم السلاسل كمفاتيح، ويمكن استخدام أي أنواع بيانات أولية ومصفوفات من الأوليات وكائنات فئة للقيم باقةإلخ.
لنقل البيانات إلى نشاط آخر، استخدم الطريقة وضع اكسترا ():
Intent.putExtra("Key", "Value");
يجب أن يستدعي نشاط الاستلام بعض الطرق المناسبة: getIntExtra(), getStringExtra ()إلخ.:
Int count = getIntent().getIntExtra("name", 0);
دعونا نعيد المثال السابق. لدينا بالفعل ثلاثة أنشطة. سيحتوي النشاط الأول على حقلين نصيين وزر. قد يكون المظهر على النحو التالي:
في النشاط الثاني النشاط الثانيتعيين العنصر عرض النصحيث سنعرض النص الوارد من النشاط الأول. لنكتب الكود التالي للطريقة عند الإنشاء ()في النشاط الثاني
@Override protected void onCreate(Bundle saveInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.activity_ Second); String user = "Animal"; String gift = "Donut Hole"; TextView infoTextView = (TextView)findViewById( R .id.textViewInfo); infoTextView.setText(user + "، لقد تم إعطاؤك" + gift);
إذا قمنا الآن بتشغيل البرنامج وقمنا ببساطة باستدعاء النافذة الثانية، كما تم شرحه في الجزء الأول من المقالة، فسنرى النقش الافتراضي أيها الحيوان، لقد أعطوك ثقب الدونات. أوافق، إنه أمر مزعج للغاية لتلقي مثل هذه الرسائل.
دعونا نصحح الوضع. أضف الكود للنشاط الأول:
الفراغ العام onClick(عرض العرض) ( EditText userEditText = (EditText) findViewById(R.id.editTextUser); EditText giftEditText = (EditText) findViewById(R.id.editTextGift); Intentint = new Intent(MainActivity.this, SecondActivity. class)؛ // ادفع النص من حقل النص الأول إلى مفتاح اسم المستخدمint.putExtra("username"، userEditText.getText().toString()); // ادفع النص من حقل النص الثاني إلى مفتاح الهدية intent.putExtra("gift" ", giftEditText.getText().toString()); startActivity(intent); )
لقد وضعنا الكائن في حاوية خاصة لبدء شاشة جديدة تحتاج إلى إنشاء مثيل للفئةمفتاحين بقيم مأخوذة من الحقول النصية. عندما يقوم المستخدم بإدخال البيانات في الحقول النصية، سيتم نقلها إلى هذه الحاوية وتمريرها إلى النشاط الثاني.
يجب أن يكون النشاط الثاني جاهزًا لاستقبال الرسائل بحرارة على النحو التالي (بالخط العريض).
// القيم الافتراضية String user = "Animal"; هدية سلسلة = "ثقب الدونات"؛ user = getIntent().getExtras().getString("اسم المستخدم"); gift = getIntent().getExtras().getString("gift"); TextView infoTextView = (TextView)findViewById(R.id.textViewInfo); infoTextView.setText(user + "، لقد تم إعطاؤك" + gift);
الآن تبدو الرسالة أقل هجومًا، بل وممتعة بالنسبة للبعض. في الأمثلة المعقدة، يُنصح بإضافة علامة اختيار عند معالجة البيانات. قد تكون هناك مواقف حيث تقوم بتشغيل نشاط ثانٍ ببيانات فارغة من النوع باطل، مما قد يتسبب في تعطل التطبيق.
في حالتنا، نعلم أننا نتوقع قيمة سلسلة، لذلك يمكن إعادة كتابة الكود على النحو التالي:
نية النية = getIntent(); user =intent.getStringExtra("اسم المستخدم");
المستخدم = getIntent().getStringExtra("اسم المستخدم");
البرنامج له عيب - ليس من الواضح ممن نتلقى التحيات. لن يقبل أي قرد ذو تربية جيدة هدية من مصدر مجهول. لذلك، كواجب منزلي، قم بإضافة حقل نصي آخر لإدخال اسم المستخدم الذي يرسل الرسالة.
توصي Google باستخدام التنسيق التالي للمفاتيح: اسم الحزمة الخاصة بك كبادئة، متبوعًا بالمفتاح نفسه. في هذه الحالة، يمكنك التأكد من تفرد المفتاح عند التفاعل مع التطبيقات الأخرى. شيء من هذا القبيل:
السلسلة الثابتة النهائية العامة USER = "ru.alexanderklimov.myapp.USER"؛
لا يكفي دائمًا تمرير البيانات إلى نشاط آخر. في بعض الأحيان تحتاج إلى استعادة المعلومات من نشاط آخر عند إغلاقه. إذا استخدمنا الطريقة في وقت سابق startActivity (نية النية)، ثم هناك طريقة ذات صلة startActivityForResult (نية النية، رمز الطلب int). الفرق بين الطرق هو المعلمة الإضافية رمز الطلب. إنه في الأساس مجرد رقم صحيح يمكنك التوصل إليه بنفسك. إنه ضروري للتمييز ممن جاءت النتيجة. لنفترض أن لديك خمس شاشات إضافية وقمت بتعيين قيم من 1 إلى 5 لها، وباستخدام هذا الرمز يمكنك تحديد النتيجة التي تريد معالجتها. يمكنك استخدام القيمة -1، وستكون مماثلة لاستدعاء الطريقة . بعد هذا يتم استدعاء الطريقة، أي. لن نحصل على أي نتائج.
إذا كنت تستخدم الطريقة ستارتاكتيفيتيفورريسولت ()، فأنت بحاجة إلى تجاوز الطريقة الموجودة في التعليمات البرمجية الخاصة بك لتلقي النتيجة onActivityResult()ومعالجة النتيجة. مشوش؟ دعونا نلقي نظرة على مثال.
لنفترض أنك محقق. وردت معلومات عن سرقة قطعتين من النقانق ومنتجات أخرى من طاولة أحد الأشخاص ذوي النفوذ في أحد المطاعم. ووقعت الشكوك حول ثلاثة مشتبه بهم - غراب وكلب سخيف والقطة فاسكا.
قدم أحد الزوار سلسلة من الصور من جهاز iPhone الخاص به:
وهناك أيضاً شهادة من شاهد آخر: وفاسكا يستمع ويأكل.
إنشاء مشروع جديد شيرلوكمع نشاطين. على الشاشة الأولى سيكون هناك زر للتبديل إلى الشاشة الثانية وملصق نصي سيتم فيه عرض اسم اللص.
في الشاشة الثانية سيكون هناك مجموعة من المفاتيح:
وبما أننا نتوقع استجابة من الشاشة الثانية، فإننا بحاجة إلى استخدام هذه الطريقة ستارتاكتيفيتيفورريسولت ()في الشاشة الأولى التي سنمرر فيها المتغير CHOOSE_THIEFكمعلمة رمز الطلب.
ثابت نهائي خاص int CHOOSE_THIEF = 0; الفراغ العام onClick(View v) ( Intent questionIntent = new Intent(MainActivity.this, ChooseActivity.class); startActivityForResult(questionIntent, CHOOSE_THIEF); )
انظر إلى الكود. عندما نضغط على الزر سنعمل مع الشاشة الثانية اختر النشاطوتشغيل الشاشة الثانية في انتظار النتيجة.
دعنا نذهب إلى الشاشة الثانية ونكتب رمز النشاط الثاني.
السلسلة الثابتة العامة النهائية = "ru.alexanderklimov.sherlock.THIEF"؛ الفراغ العام onRadioClick(View v) ( Intent AnswerIntent = new Intent(); Switch (v.getId()) ( case R.id.radioDog:answerIntent.putExtra(THIEF, "Fucking doggie"); استراحة; case R.id .radioCrow: AnswerIntent.putExtra(THIEF, "Crow"); ;
كل شيء بسيط هنا، عندما يختار المحقق اسم المجرم، ثم من خلال الطريقة وضع اكسترا ()نمرر اسم المفتاح وقيمته.
للراحة، بعد التحديد، نغلق النافذة الثانية على الفور وقبل الإغلاق نمرر القيمة النتيجة_موافق، بحيث يكون من الواضح أن الاختيار قد تم. إذا قام المستخدم بإغلاق الشاشة عبر زر الرجوع، فسيتم تمرير القيمة تم إلغاء النتيجة.
طريقة نتيجة تعيين ()يأخذ معلمتين: الكود الناتج والنتيجة نفسها، ممثلة كهدف. يخبرك الكود الناتج بالنتيجة التي اكتمل بها النشاط، كقاعدة عامة، إما النشاط.RESULT_OK، أو النشاط.RESULT_CANCELED. في بعض الحالات، تحتاج إلى استخدام رمز الإرجاع الخاص بك للتعامل مع الاختلافات الخاصة بتطبيقك. طريقة نتيجة تعيين ()يدعم أي قيمة عددية.
إذا كنت ستقوم بتمرير البيانات بشكل صريح من خلال زر، فسيكون من الجيد إضافة طريقة ينهي()لإغلاق النشاط الثاني باعتباره غير ضروري. إذا حدث الانتقال من خلال زر "الخلف"، فهذا ليس ضروريًا.
إذا تم إغلاق النشاط من قبل المستخدم عن طريق الضغط على زر إرجاع الأجهزة أو إذا كانت الطريقة ينهي()تم استدعاؤه قبل الطريقة نتيجة تعيين ()، سيتم تعيين الكود الناتج على تم إلغاء النتيجة، وسيُظهر الهدف الذي تم إرجاعه القيمة باطل.
نعود إلى الشاشة الأولى. الشاشة الأولى تنتظر الرد من الشاشة الثانية، لذلك تحتاج إلى إضافة طريقة إلى الكود onActivityResult().
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) ( super.onActivityResult(requestCode, resultCode, data); TextView infoTextView = (TextView) findViewById(R.id.textViewInfo); if (requestCode == CHOOSE_THIEF) ( إذا (resultCode == RESULT_OK) ( String thiefname = data.getStringExtra(ChooseActivity.THIEF); infoTextView.setText(thiefname); )else ( infoTextView.setText(""); // مسح النص ) ) )
تتوقع الطريقة البيانات الواردة مع التعليمات البرمجية CHOOSE_THIEFوإذا وصلت هذه البيانات، فإنه يسترد القيمة من المفتاح اختر النشاط.اللصباستخدام الطريقة getStringExtra. نعرض القيمة الناتجة في عرض النص(عامل infoTextView). إذا عدنا إلى الشاشة من خلال زر العودة، فإننا ببساطة نمسح النص.
عندما يتم إغلاق نشاط فرعي داخل المكون الأصلي، يتم تشغيل المعالج onActivityResult(). معالج onActivityResult()يقبل العديد من المعلمات.
إذا تم إنهاء نشاط فرعي بشكل غير متوقع أو إذا لم يتم تحديد رمز النتيجة قبل إغلاقه، فسوف تصبح هذه المعلمة النشاط.RESULT_CANCELED.
نطلق المشروع ونضغط على الزر وننتقل إلى الشاشة الثانية. هناك نختار أحد الخيارات. إذا قمت بتحديد الغراب، فسيتم إغلاق الشاشة وسيظهر اسم المجرم على الشاشة الأولى. إذا قمت بتحديد كلب، سيتم عرض اسمه.
بالمناسبة، إذا قمت بتحديد قطة، فلن يتم عرض اسمها! التحقق من ذلك وانظر لنفسك. تسأل لماذا؟ الابتدائية، واتسون! لم يأخذ المجرم بعين الاعتبار تفاصيل مهمة واحدة. وكان المطعم تحت المراقبة بكاميرات الفيديو، وأظهر التسجيل من قام فعلا بسرقة النقانق وتلفيق التهمة للقطة. فاسكا، انتظر!
ملاحظة: إذا بدا شيء ما غير واضح في البداية، فسوف يصبح الكثير أكثر وضوحًا مع الممارسة. نقل البيانات بين الشاشات أمر شائع في التطبيقات، وسوف تدرس المثال أكثر من مرة.
P.S. أفضل الأسماك هي النقانق. مع العلم بهذا الضعف، لم يكن من الصعب تأطير القطة.
لقد عرضت في المقالة طريقة شائعة للتبديل إلى نشاط آخر عندما تكون في إحدى الطرق . بعد هذا يتم استدعاء الطريقةيتم الإشارة إلى الفصل الحالي والفصل المراد نقله. بالمناسبة، ليس من الضروري أن تكون فئة النشاط جزءًا من طلبك. إذا كنت تعرف اسم الفئة من تطبيق آخر، فيمكنك التبديل إليه. ولكن يمكنك الانتقال إلى نشاط آخر بطريقة أخرى.
ومن الناحية العملية، فهو أقل شيوعًا، ولكنه قد يكون مفيدًا. لنفترض أن لديك بالفعل نشاطًا ثانيًا. سنضيف في البيان مرشحًا خاصًا إليه:
ونطلق النشاط الثاني بالضغط على الزر بهذه الطريقة.
الفراغ العام عند النقر (عرض العرض) ( startActivity(new Intent("ru.alexanderklimov.testapplication.SecondActivity"));)
دعونا نستبدل السلسلة الطويلة بثابت.
السلسلة النهائية العامة الثابتة ACTION_SECOND_ACTIVITY = "ru.alexanderklimov.testapplication.SecondActivity"؛ الفراغ العام عند النقر (عرض العرض) ( startActivity(new Intent(ACTION_SECOND_ACTIVITY)); )
فماذا فعلنا. بالنسبة للنشاط الثاني، قمنا بتسجيل مرشح وحددنا اسمًا له فعلفي السمة الروبوت: الاسم. للراحة، قمت فقط بوضع الاسم الكامل للنشاط مع اسم الحزمة فيه. منشئ الطبقة لبدء شاشة جديدة تحتاج إلى إنشاء مثيل للفئةلديه العديد من الإصدارات المثقلة. في أحد الإصدارات، يمكنك تحديد سلسلة للإجراء. لقد أشرنا إلى الإجراء الذي تم إنشاؤه والذي تم تسجيله في النشاط الثاني. أثناء التشغيل، يقوم النظام بعرض بيانات كافة التطبيقات المثبتة. عند البحث عن تطابق، يعثر النظام على عامل التصفية الخاص بنا ويقوم بتشغيل النشاط المطلوب.
يمكنك إطلاق أنشطة أخرى باستخدام نفس المبدأ. انظر إلى المثال. إذا قمت بنسخ المثال لنفسك ونظرت إلى الوثائق الخاصة بـ android.provider.Settings.ACTION_AIRPLANE_MODE_SETTINGSسترى أن هذا الرمز يتوافق مع ثابت السلسلة النهائي العام الثابت java.lang.String ACTION_AIRPLANE_MODE_SETTINGS = "android.settings.AIRPLANE_MODE_SETTINGS". قارن مع الكود الخاص بنا. يمكنك أن تفترض أن نشاط الإعدادات لوضع عدم الاتصال يحتوي على هذا السطر في عامل التصفية الخاص به.
اسم فئة التصفية android.intent.category.DEFAULTيخبر النظام بتنفيذ الإجراء الافتراضي، وهو بدء النشاط. وهناك أسماء أخرى لا تهمنا بعد.
والآن سؤال أخير. ماذا يحدث إذا قمت بإنشاء نشاط آخر وقمت بتحديد نفس عامل التصفية للنشاط الثاني؟ دعونا التحقق من ذلك. أنشئ نشاطًا ثالثًا وانسخ الكتلة التي تحتوي على عامل التصفية من النشاط الثاني إليه.
انقر على الزر الموجود في النشاط الأول. سيطلب منك النظام تحديد الخيار المطلوب.
إذا قمت بتحديد دائماً، ففي المرة القادمة لن تضطر إلى الاختيار. لإعادة تعيين التحديد، انتقل إلى خصائص التطبيق في الإعدادات وابحث عن الزر مسح الإعدادات الافتراضية.
في المنشئ لبدء شاشة جديدة تحتاج إلى إنشاء مثيل للفئةالمعلمة الثانية هي الفئة. لكن لنفترض أن هناك نوعًا ما من قاعدة البيانات حيث تتم الإشارة إلى أسماء الأنشطة ونحتاج إلى تشغيل النشاط المطلوب باسمه. يمكننا الحصول على الفصل نفسه بناءً على متغير سلسلة وبدء النشاط.
حاول ( // الاسم الكامل لفئة النشاط String ActivityName = "ru.alexanderklimov.testapplication.SecondActivity"؛ // احصل على كائن الفئة>myClass = Class.forName(activityName);
Intent Intent = new Intent(this, myClass);
نحتاج إلى نقل البيانات من النشاط إلى الخدمة والعودة. كيف نفعل هذا؟ لدينا بالفعل كل ما نحتاجه لحل مشكلتنا. كل ما تحتاجه هو ربط الخدمة بالنشاط باستخدام bindService، وتمرير المعلمات الضرورية والقليل من السحر في شكل استخدام فئات الرسائل. والسحر هو استخدام متغيرات مثيل الرسالة، وعلى وجه الخصوص، الرد على. نحتاج إلى هذا المتغير حتى نتمكن من الوصول إلى مثيل خدمة Messanger من النشاط وفي الخدمة مثيل Messanger للنشاط. في الواقع، الأمر ليس بهذه البساطة. على الأقل بالنسبة لعقلي الأقل موهبة. جزئيًا، أقوم فقط بتحسين الوثائق الموجودة بالفعل - الخدمات. كما يوجد مثال جيد على StackOverflow. على أية حال، آمل أن يكون المقال مفيدًا لشخص ما على الأقل وأن عملي لم يذهب سدى.
على سبيل المثال، سنقوم بتنفيذ خدمة تعمل على زيادة وتقليل قيمة العداد وإرجاع النتيجة إلى النشاط في TextView. سأحذف رمز التخطيط، لأن هناك زرين وحقل نصي - كل شيء بسيط.
إليك رمز التفعيل الكامل:
يقوم MainActivity من الفئة العامة بتوسيع النشاط (السلسلة النهائية العامة الثابتة TAG = "TestService"؛ TestServiceConnection testServConn؛ TextView testTxt؛ Final رسول رسول= new Messenger(new IncomingHandler());
رسول إلىServiceMessenger؛
لتلقي رسالة من الخدمة، نستخدم معالجنا ونبحث ببساطة عن المتغيرات التي نحتاجها ونتخذ الإجراءات بشأنها. من خلال النقر على الأزرار (طرق countIncrClick، countDecrClick)، نرسل طلبات إلى الخدمة، مع الإشارة إلى الإجراء المطلوب في المتغير msg.what.
الحزمة com.example.servicetest; import android.app.Service; استيراد android.content.*; استيراد android.os.*; import android.os.Process; import android.util.Log; تعمل خدمة TestService على توسيع الخدمة (العدد النهائي الثابت العام COUNT_PLUS = 1؛ العدد النهائي الثابت العام COUNT_MINUS = 2؛ العدد النهائي الثابت العام SET_COUNT = 0؛ العدد النهائي الثابت العام GET_COUNT = 3؛ عدد int = 0؛ IncomingHandler inHandler؛ Messenger messenger؛ Messenger toActivityMessenger; @Override public void onCreate())( super.onCreate(); HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); inHandler = new IncomingHandler(thread.getLooper()); messanger = new Messenger(inHandler) @Override public IBinder onBind(Intent arg0) (returnmessanger.getBinder();) @Override public int onStartCommand(Intent Int, int flags, int startId) (return START_STICKY;) //message نشاط المعالج فئة خاصة IncomingHandler يمتد Handler ( public IncomingHandler(Looper Looper)( super(looper); ) @Override public void HandleMessage(Message msg)( //super.handleMessage(msg); toActivityMessenger = msg.replyTo;
التبديل (msg.what) (الحالة SET_COUNT: العد = msg.arg1؛ Log.d(MainActivity.TAG, "(الخدمة)...تعيين العد"); استراحة; الحالة COUNT_PLUS: count++; Log.d(MainActivity.TAG ، "(الخدمة)...عدد زائد"); );
outMsg.arg1 = count;
والتي بدونها سوف يسقط كل شيء. سيتم تمرير مثيل الواجهة هذا إلى ServiceConnection
الكل في الكل. هذا مثال بعيد الاحتمال للتفاعل بين النشاط والخدمة. يبدو لي أن هذا تفاعل غير تافه إلى حد ما، على الرغم من أن الآخرين قد يعتقدون خلاف ذلك.
الأسئلة والتوضيحات وغيرها في PM. قد تكون هناك أخطاء في بعض الجوانب، لذا لا تتردد في الكتابة والتصحيح.
أتمنى أن يكون التدوينة مفيدة للقراء.
آخر تحديث: 04/03/2018
يتم استخدام كائن Intent لنقل البيانات بين نشاطين. من خلال طريقة putExtra()، يمكنك إضافة مفتاح والقيمة المرتبطة به.
على سبيل المثال، تمرير السلسلة "Hello World" مع المفتاح "hello" من النشاط الحالي إلى SecondActivity:
// إنشاء كائن Intent لتشغيل SecondActivity Intent Intent = new Intent(this, SecondActivity.class); // تمرير كائن باستخدام المفتاح "hello" والقيمة "Hello World"int.putExtra("hello", "Hello World"); // ابدأ SecondActivity startActivity(intent);
لنقل البيانات، يتم استخدام طريقة putExtra()، والتي تسمح لك بنقل البيانات من أبسط الأنواع كقيمة - String، int، float، double، long، short، byte، char، صفائف من هذه الأنواع أو قابلة للتسلسل كائن الواجهة.
للحصول على البيانات المرسلة عند تحميل SecondActivity، يمكنك استخدام طريقة get()، والتي يتم تمرير مفتاح الكائن إليها:
وسيطات الحزمة = getIntent().getExtras(); اسم السلسلة = الوسيطات.get("hello").toString(); // مرحبا بالعالم
اعتمادًا على نوع البيانات التي نرسلها، يمكننا استخدام عدد من الطرق على كائن الحزمة عندما نستقبلها. كل منهم يأخذ مفتاح الكائن كمعلمة. أهمها:
get() : طريقة عامة تُرجع قيمة من النوع Object. وفقا لذلك، مجال الاستقبال قيمة معينةيجب تحويله إلى النوع المطلوب
getString() : تقوم بإرجاع كائن سلسلة
getInt() : تقوم بإرجاع قيمة int
getByte() : تقوم بإرجاع قيمة بايت
getChar() : تقوم بإرجاع قيمة char
getShort() : تُرجع قيمة من النوع القصير
getLong() : تقوم بإرجاع قيمة طويلة
getFloat() : تُرجع قيمة عائمة
getDouble() : تقوم بإرجاع قيمة مزدوجة
getBoolean() : تقوم بإرجاع قيمة منطقية
getCharArray() : يُرجع مصفوفة من كائنات char
getIntArray() : يُرجع مصفوفة من الكائنات int
getFloatArray() : يُرجع مصفوفة من الكائنات العائمة
getSerializable() : يقوم بإرجاع كائن واجهة قابل للتسلسل
دعونا نحدد نشاطين في مشروعنا: النشاط الرئيسي والنشاط الثاني.
في كود SecondActivity، سنحدد تلقي البيانات:
الحزمة com.example.eugene.serializeapp; import android.support.v7.app.AppCompatActivity; استيراد android.os.Bundle؛ import android.widget.TextView; تعمل الطبقة العامة SecondActivity على توسيع AppCompatActivity ( @Override protected void onCreate(Bundle saveInstanceState) ( super.onCreate(savedInstanceState); TextView textView = new TextView(this); textView.setTextSize(20); textView.setPadding(16, 16, 16, 16) ); السعر = الوسيطات.getInt("price"); textView.setText("الاسم: " + الاسم + "\nالشركة: " + الشركة + "\nالسعر: " + السعر ) setContentView(textView))
في في هذه الحالةفي SecondActivity نحصل على جميع البيانات من كائن Bundle ونعرضها في حقل النص TextView. من المفترض أنه سيتم تمرير ثلاثة عناصر إلى هذا النشاط - سلسلتين مع اسم المفاتيح والشركة ورقم مع سعر المفتاح.
الآن دعونا نحدد نقل البيانات إلى SecondActivity. على سبيل المثال، دعونا نحدد الواجهة التالية لـ MainActivity في ملفactiv_main.xml:
يتم هنا تعريف ثلاثة حقول نصية لإدخال البيانات وزر.
في فئة MainActivity سنحدد المحتوى التالي:
الحزمة com.example.eugene.serializeapp; import android.content.Intent; import android.support.v7.app.AppCompatActivity; استيراد android.os.Bundle؛ import android.view.View; import android.widget.EditText; تعمل الطبقة العامة MainActivity على توسيع AppCompatActivity ( @Override protected void onCreate(Bundle saveInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);) public void onClick(View v) ( Final EditText nameText = findViewById(R.id .name); السعر = Integer.parseInt(priceText.getText().toString()); Intentint = new Intent(this, SecondActivity.class);intent.putExtra("name", name); Intent.putExtra("price"، السعر startActivity(intent)) ؛
في معالج النقر على الزر، نتلقى البيانات المدخلة في حقول النص EditText ونمررها إلى كائن Intent باستخدام طريقة putExtra(). ثم نقوم بتشغيل SecondActivity.
نتيجة لذلك، عند النقر فوق الزر، سيتم تشغيل SecondActivity، والذي سيتلقى بعض البيانات المدخلة في حقول النص.
في المثال أعلاه، تم نقل بيانات بسيطة - أرقام، سلاسل. ولكن يمكننا أيضًا نقل بيانات أكثر تعقيدًا. في هذه الحالة، يتم استخدام آلية التسلسل.
على سبيل المثال، لنفترض أن لدينا فئة منتج محددة في مشروعنا:
الحزمة com.example.eugene.serializeapp; استيراد java.io.Serializable؛ يطبق المنتج من الفئة العامة إمكانية التسلسل (اسم سلسلة خاصة؛ شركة سلسلة خاصة؛ سعر int خاص؛ منتج عام (اسم سلسلة، شركة سلسلة، سعر int) (this.name = name؛ this.company = الشركة؛ this.price = السعر؛) سلسلة عامة getName () (اسم الإرجاع؛) مجموعة باطلة عامة (اسم سلسلة) (this.name = name؛) سلسلة عامة getCompany () (شركة إرجاع؛) مجموعة باطلة عامة (شركة سلسلة) (this.company = شركة؛) public int getPrice() (سعر الإرجاع;) public void setPrice(int Price) (this.price =price;))
تجدر الإشارة إلى أن هذه الفئة تطبق واجهة قابلة للتسلسل. الآن دعونا نغير رمز النشاط الرئيسي:
الحزمة com.example.eugene.serializeapp; import android.content.Intent; import android.support.v7.app.AppCompatActivity; استيراد android.os.Bundle؛ import android.view.View; import android.widget.EditText; تعمل الطبقة العامة MainActivity على توسيع AppCompatActivity ( @Override protected void onCreate(Bundle saveInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);) public void onClick(View v) ( Final EditText nameText = findViewById(R.id .name); السعر = Integer.parseInt(priceText.getText().toString()); منتج المنتج = منتج جديد (الاسم، الشركة، السعر)؛ .getSimpleName(), المنتج startActivity(intent)))
الآن، بدلاً من ثلاث بيانات منفصلة، يتم إرسال كائن منتج واحد. المفتاح هو نتيجة طريقة Product.class.getSimpleName()، والتي تُرجع بشكل أساسي اسم الفئة.
وقم بتغيير فئة SecondActivity:
الحزمة com.example.eugene.serializeapp; import android.support.v7.app.AppCompatActivity; استيراد android.os.Bundle؛ import android.widget.TextView; تعمل الطبقة العامة SecondActivity على توسيع AppCompatActivity ( @Override protected void onCreate(Bundle saveInstanceState) ( super.onCreate(savedInstanceState); TextView textView = new TextView(this); textView.setTextSize(20); textView.setPadding(16, 16, 16, 16) ); " + Product.getName() + "\nالشركة: " + Product.getCompany() + "\nالسعر: " + String.valueOf(product.getPrice())); ) setContentView(textView); ) )
يتم استخدام طريقة getSerializable() لاسترداد البيانات لأن فئة المنتج تنفذ الواجهة القابلة للتسلسل. بهذه الطريقة يمكننا تمرير كائن واحد بدلاً من مجموعة من البيانات المتباينة.