امسح مكدس التاريخ بأكمله وابدأ نشاطًا جديدًا على Android

StackOverflow https://stackoverflow.com/questions/3473168

سؤال

هل من الممكن بدء نشاط على المكدس ، وقم بتطهير التاريخ بأكمله قبله؟

الوضع

لديّ مكدس نشاط إما يذهب A-> B-> C أو B-> C (SCRACK A يحدد رمز المستخدمين ، ولكن العديد من المستخدمين لديهم رمز واحد فقط).

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

ملحوظات

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

هل كانت مفيدة؟

المحلول

في API المستوى 11 ، تمت إضافة علامة نية جديدة فقط لهذا: intent.flag_activity_clear_task

فقط للتوضيح ، استخدم هذا:

جافا

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);


كوتلين

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK


لسوء الحظ بالنسبة لـ API LVL <= 10 ، لم أجد حلاً نظيفًا لهذا بعد. ال "Donthackandroidlikethis" حل هو في الواقع اختراق خالص. يجب أن لا تفعل ذلك. قون

يحرر:حسب @بن بيرسونتعليق ، لـ API <= 10 الآن يمكن للمرء استخدامه intentcompat فئة لنفسه. يمكن للمرء استخدام IntentCompat.FLAG_ACTIVITY_CLEAR_TASK العلم لمسح المهمة. حتى تتمكن من دعم مستوى API 11 أيضًا.

نصائح أخرى

الحالة 1: نشاطان فقط A و B:

هنا تدفق النشاط هو A-> b. على النقر فوق Backbutton من B ، نحتاج إلى إغلاق التطبيق ثم أثناء بدء النشاط B من A Just Call Finish () سيمنع هذا Android من تخزين النشاط A إلى Backstack.eg للنشاط A هو شاشة الإقامة/رش التطبيق.

Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();

الحالة 2: أكثر من اثنين من activitiy:

إذا كان هناك تدفق مثل a-> b-> c-> d-> b وعند النقر فوق الزر مرة أخرى في النشاط B أثناء قدومه من النشاط. في هذه الحالة ، يجب أن نستخدمها.

Intent newIntent = new Intent(D.this,B.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);

هنا سيتم تشغيل النشاط B من backstack بدلاً من مثيل جديد بسبب intent.flag_activity_clear_top و intent.flag_activity_new_task يمسح المكدس ويجعله أعلى.

مع إصدار Android الأحدث> = استخدام API 16 finishAffinity()

النهج مناسب لـ> = API 16.

Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
  • هو نفسه مثل بدء نشاط جديد ، ومسح كل المكدس.
  • أو إعادة التشغيل إلى النشاط الرئيسي/النشاط الأول.

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

ماذا أفعل؟ ضع النشاط الذي يتم إطلاقه في المكدس باستخدام flag_activity_new_task ، مما يجعل هذا النشاط بداية مهمة جديدة على كومة التاريخ. ثم أضف علامة flag_activity_clear_top.

الآن ، عندما يذهب flag_activity_clear_top للعثور على النشاط الجديد في المكدس ، سيكون هناك وسحبه قبل مسح كل شيء آخر.

ها هي وظيفة تسجيل الخروج الخاصة بي. معلمة العرض هي الزر الذي ترفق عليه الوظيفة.

public void onLogoutClick(final View view) {
    Intent i = new Intent(this, Splash.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(i);
    finish();
}

يجب ألا تغير المكدس. يجب أن يعمل زر Back Android كما هو الحال في متصفح الويب.

أستطيع أن أفكر في طريقة للقيام بذلك ، لكنها اختراق تمامًا.

  • اصنع أنشطتك singleTask عن طريق إضافته إلى AndroidManifestمثال:

    <activity android:name=".activities.A"
              android:label="@string/A_title"
              android:launchMode="singleTask"/>
    
    <activity android:name=".activities.B"
              android:label="@string/B_title"
              android:launchMode="singleTask"/>
    
  • تمديد Application والتي سوف تحمل منطق أين تذهب.

مثال:

public class DontHackAndroidLikeThis extends Application {

  private Stack<Activity> classes = new Stack<Activity>();

  public Activity getBackActivity() {
    return classes.pop();
  }

  public void addBackActivity(Activity activity) {
    classes.push(activity);
  }
}

من الالف الى الياء:

DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(A.class); 
startActivity(this, B.class);

من ب إلى ج:

DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(B.class); 
startActivity(this, C.class);

في ج:

If ( shouldNotGoBackToB() ) {
  DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
  app.pop();
}

والتعامل مع زر العودة إلى pop() من المكدس.

مرة أخرى ، يجب ألا تفعل هذا :)

مباشرة بعد بدء نشاط جديد ، باستخدام startActivity, ، تأكد من الاتصال finish() بحيث لا يتم تكديس النشاط الحالي وراء النشاط الجديد.

جرب هذا:

Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();
Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

حاول أدناه الكود ،

Intent intent = new Intent(ManageProfileActivity.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK| 
                Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

لي لا أحد من الطرق المذكورة أعلاه لا يعمل.

فقط افعل هذا ل مسح كل النشاط السابق:

finishAffinity() // if you are in fragment use activity.finishAffinity()
Intent intent = new Intent(this, DestActivity.class); // with all flags you want
startActivity(intent)

لقد وجدت اختراقًا بسيطًا جدًا ، فقط قم بذلك إضافة عنصر جديد في AndroidManifest كما:-

<activity android:name=".activityName"
          android:label="@string/app_name"
          android:noHistory="true"/>

ال android:noHistory سوف مسح نشاطك غير المرغوب فيه من Stack.

في بعض الأحيان ، قد يفشل محاكي Android الخاص بك في توصيل أداة Eclipse DDMS واطلب أن تبدأ ADB يدويًا. في هذه الحالة ، يمكنك بدء أو إيقاف ADB باستخدام موجه الأوامر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top