سؤال

قرأت في وثائق Android التي من خلال تعيين خاصية Launchmode الخاصة بنشاط النشاط إلى SingleTOP أو عن طريق إضافة FLAG_ACTIVITY_SINGLE_TOP علم إلى نية بلدي، أن الاتصال startActivity(intent) سوف إعادة استخدام مثيل نشاط واحد وتعطيني النية في onNewIntent أتصل مرة أخرى. فعلت كل من هذه الأشياء، و onNewIntent لا تطلق أبدا و onCreate حرائق في كل مرة. الدقة يقول أيضا ذلك this.getIntent() إرجاع النية التي تم تمريرها لأول مرة إلى النشاط عند إنشاءها لأول مرة. في onCreate انا اتصل getIntent وأنا أحصل على واحدة جديدة في كل مرة (أقوم بإنشاء كائن نية في نشاط آخر وإضافة إضافي إليها ... يجب أن يكون هذا الإضافي هو نفسه في كل مرة إذا كان قد أعيد لي نفس كائن النية). كل هذا يقودني للاعتقاد بأن نشاطي لا يتصرف مثل "أعلى واحد"، وأنا لا أفهم لماذا.

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

في Androidmanifest.xml:

    <activity
        android:name=".ArtistActivity"
        android:label="Artist"
        android:launchMode="singleTop">
    </activity>     

في نشاط الاتصال الخاص بي:

        Intent i = new Intent();
        i.putExtra(EXTRA_KEY_ARTIST, id);
        i.setClass(this, ArtistActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(i);
هل كانت مفيدة؟

المحلول

هل تحقق ما إذا كان onDestroy() كان يسمى كذلك؟ ربما هذا هو السبب onCreate() يتم الاحتجاج في كل مرة بدلا من onNewIntent(), ، والتي لن يتم استدعاؤها إلا إذا كان النشاط موجودا بالفعل.

على سبيل المثال، إذا تركت نشاطك عبر الزر الخلفي، فسيتم تدميره افتراضيا. ولكن إذا ارتفعت أعلى على مكدس النشاط إلى أنشطة أخرى ومن تتصل بك ArtistActivity.class مرة أخرى سوف تخطي onCreate() وتذهب مباشرة إلى onNewIntent(), ، نظرا لأن النشاط قد تم إنشاؤه بالفعل وبذلك حددته singleTop لن يقوم Android بإنشاء مثيل جديد منه، ولكن خذ الشخص الذي يكذب بالفعل.

ما الذي أفعله لرؤية ما يحدث في تطبيق وظائف وهمية لجميع الحالات المختلفة لكل نشاط لذلك أنا دائما ما يحدث الآن:

@Override
public void onDestroy() {
    Log.i(TAG, "onDestroy()");
    super.onDestroy();
}

الشيء نفسه بالنسبة ل onRestart(), onStart(), onResume(), onPause(), onDestroy()

إذا لم يكن ما سبق (زر الخلفي) مشكلتك، فهل تنفذ هذه الدمز سيساعدك على الأقل في تصحيح الأخطاء قليلا.

نصائح أخرى

الجواب المقبول ليس صحيحا تماما. إذا تم استدعاء OnDestroy () سابقا، فسيتم دائما استدعاء OnCreate () دائما. ومع ذلك، هذا البيان خطأ.

قسم "singletop" http://developer.android.com/guide/components/tasks-and-back-stack.html. يوضح بوضوح كيف يعمل (الانتباه إلى النص الغامق أدناه؛ لقد أثبتت ذلك أيضا من خلال تصحيح الأخشاب الخاصة بي):

"على سبيل المثال، افترض أن كومة الخلفية للمهمة تتكون من نشاط الجذر أ مع الأنشطة B و C و D في الأعلى (المكدس abcd؛ د في الأعلى). نية تصل إلى نشاط النوع D. إذا كان D لديه وضع التشغيل "Standard" الافتراضي، فسيتم تشغيل مثيل جديد للفئة وتصبح المكدس ABCDD. ومع ذلك، إذا كان وضع إطلاق D'S "SingletOp"، فإن مثيل D الحالي يتلقى النية من خلال OnNewintent ()، لأنه في الجزء العلوي من المكدس - لا يزال المكدس ABCD. ومع ذلك، إذا وصلت النية لنشاط من النوع B، فسيتم إضافة مثيل جديد من B إلى المكدس، حتى إذا كان وضع الإطلاق "SingletOp". "

بمعنى آخر، فإن بدء نشاط من خلال Single_top سيؤدي إلا إلى إعادة استخدام النشاط الحالي إذا كان كذلك بالفعل في الجزء العلوي من المكدس. وبعد لن يعمل إذا كان نشاطا آخر في هذه المهمة نفسها موجودة في الأعلى (على سبيل المثال، النشاط الذي يتم تنفيذه (Single_top))؛ سيتم إنشاء مثيل جديد بدلا من ذلك.

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

الطريق الأول (كما هو موضح في قسم التعليق من الإجابة المقبولة): يمكنك إضافة مطلق "singletask" إلى نشاطك. هذا من شأنه أن يجبر Onewintent () لأن Singletask يعني أنه لا يمكن أن يكون هناك مثيل واحد فقط من نشاط معين في مهمة معينة. هذا هو محلول اختراق إلى حد ما لأنه إذا كان تطبيقك يحتاج إلى مثيلات متعددة من هذا النشاط في وضع معين (كما أفعل في مشروعي)، فأنت مشدود.

الطريقة الثانية (أفضل):بدلا من flag_activity_single_top، استخدم Flag_Activity_Reorder_to_Front. سيؤدي ذلك إلى إعادة استخدام مثيل النشاط الحالي من خلال نقله إلى أعلى المكدس (سيتم استدعاء المكدس (OnNewintent () كما هو متوقع).

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

اضبط هذا العلم على نيتك:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top