امسح مكدس التاريخ بأكمله وابدأ نشاطًا جديدًا على Android
-
28-09-2019 - |
سؤال
هل من الممكن بدء نشاط على المكدس ، وقم بتطهير التاريخ بأكمله قبله؟
الوضع
لديّ مكدس نشاط إما يذهب 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 باستخدام موجه الأوامر.