इतिहास स्टैक से किसी गतिविधि को निकालना


382

मेरा ऐप पहली बार उपयोगकर्ता द्वारा ऐप चलाने पर साइनअप गतिविधि दिखाता है, जैसे दिखता है:

  1. एक्टिविटीएसप्लाशस्क्रीन (गेम में आपका स्वागत है, एक खाते के लिए साइन अप करें?)
  2. ActivitySplashScreenSignUp (महान, इस जानकारी को भरें)
  3. एक्टिविटीगैमेन (मुख्य खेल स्क्रीन)

इसलिए गतिविधियाँ एक दूसरे को ठीक उसी क्रम में लॉन्च करती हैं, जब उपयोगकर्ता प्रत्येक स्क्रीन पर एक बटन के माध्यम से क्लिक करता है।

जब उपयोगकर्ता गतिविधि # 2 से # 3 पर जाता है, तो क्या इतिहास के ढेर से # 1 और # 2 को मिटा देना संभव है? मुझे यह पसंद है कि यदि उपयोगकर्ता # 3 पर है, और बैक बटन को हिट करता है, तो वे केवल होमस्क्रीन पर जाते हैं, वापस स्प्लैश स्क्रीन पर।

मुझे लगता है कि मैं इसे कार्यों के साथ पूरा कर सकता हूं (यानी # 3 पर एक नया कार्य शुरू करना), लेकिन यह देखना चाहता था कि क्या सरल विधि है,

धन्यवाद


होम स्क्रीन में होने के बाद, जब उपयोगकर्ता आपके ऐप को फिर से शुरू करता है तो क्या यह उसे एक्टिविटीप्लास्क्रीन या एक्टिविटीगैमेन में ले जाता है?
तमिल

जवाबों:


632

आप सेट करके ऐसा हासिल कर सकते हैं android:noHistory विशेषता के लिए "true"प्रासंगिक में <activity>अपने में प्रविष्टियों AndroidManifest.xmlफ़ाइल। उदाहरण के लिए:

<activity
    android:name=".AnyActivity"
    android:noHistory="true" />

12
यह इसे करने का सबसे अच्छा तरीका है।
श्क्नाइडर

22
समान रूप से आप उपयोग कर सकते हैं FLAG_ACTIVITY_NO_HISTORY
टिम्मम

34
मैं इसे कोड से कैसे प्राप्त कर सकता हूं? क्योंकि मैं हर समय ऐसा नहीं करना चाहता। मैं केवल कुछ शर्तों के तहत इतिहास से दी गई गतिविधि को निकालना चाहूंगा।
नम्रता

8
बस ध्यान रखें कि noHistory विशेषता का उपयोग करने से वह गतिविधि समाप्त हो जाएगी, जिससे उदाहरण के लिए G + लॉगिन के साथ अप्रत्याशित व्यवहार हो सकता है। देखें: stackoverflow.com/questions/20383878/… इस बग को खोजने के लिए मुझे कुछ समय लगा क्योंकि मेरा ऐप बिना किसी निशान के दुर्घटनाग्रस्त हो गया।
अकापुल्को

13
लिंक के रूप में आवश्यक ध्वज को कॉपी करना मुश्किल है, इसलिए यहां एक है जिसे आसानी से कॉपी किया जा सकता है। android:noHistory="true"
दर्पण

137

आप अगले एक को लॉन्च करते समय गतिविधि स्टैक से पिछली गतिविधि को हटाने के लिए अग्रेषण का उपयोग कर सकते हैं। APIDemos में इसका एक उदाहरण है , लेकिन मूल रूप से आप जो भी कर रहे हैं वह कॉल करने के finish()तुरंत बाद कॉल कर रहा है startActivity()


1
हाय डैनियल, मैं उदाहरण के माध्यम से पढ़ता हूं, लेकिन यह केवल 1 गतिविधि द्वारा इतिहास के ढेर को साफ करेगा, है ना? अगर मेरा स्टैक ए, बी, और सी की तरह लग रहा है, तो मैं चाहता हूं कि सी नई जड़ हो और पूरी तरह से स्पष्ट ए और बी। एसडी उदाहरण में, बी से कॉलिंग फिनिश () मुझे ए के ढेर के साथ छोड़ देगा। , सी, यह नहीं होगा? धन्यवाद।
मार्क

1
जैसे ही आप B लॉन्च करते हैं आप A को साफ़ कर सकते हैं और C को लॉन्च करते समय B को साफ़ कर सकते हैं; हालाँकि, मुझे लगता है कि तब आप B से A तक वापस नहीं जा पाएंगे यदि आपकी इच्छा है। मुझे इस पर अधिक सोचना होगा यदि यह समस्या है।
डैन लुई

3
मार्क, आप जो चाहते हैं उसे प्राप्त करने के लिए, आपको ध्वज का उपयोग करना होगा: FLAG_ACTIVITY_CLEAR_TOP। मुझे उम्मीद है यह मदद करेगा।
फ्रांसिस्को जूनियर

3
FLAG_ACTIVITY_CLEAR_TOPकाम नहीं करेगा क्योंकि C पहले से ही बैक स्टैक में नहीं है।
टिम्मम

1
@DanielLew APIDemos में बहुत सारे उदाहरण हैं। आपके पास सुझाए गए उदाहरण का नाम होगा?
स्टीफन

52

हां, Intent.FLAG_ACTIVITY_NO_HISTORY पर एक नज़र डालें


46
ध्यान दें कि यह आपके द्वारा लॉन्च की जाने वाली गतिविधि के लिए कोई इतिहास नहीं सेट करता है। आपके द्वारा शुरू की जा रही गतिविधि के लिए कोई इतिहास नहीं है, मैंने इसे केवल android:noHistory="true"प्रकट में निर्धारित किया है।
georgiecasey

1
यह अच्छा काम करता है। intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)इस ध्वज को सेट करने के लिए उपयोग करें ।
वोवहॉस्ट १३'१६ को

1
@georgiecasey यह तब उपयोगी है जब कभी-कभी आप इसे इतिहास में रखना चाहते हैं और कई बार आप इसे इतिहास में नहीं चाहते हैं।
विहान वर्मा

24

यह संभवतः इसे करने का आदर्श तरीका नहीं है। अगर किसी के पास बेहतर तरीका है, तो मैं इसे लागू करने के लिए उत्सुक हूं। यहाँ मैं कैसे हूँ पूर्व-संस्करण -11 एसडीके के साथ इस विशिष्ट कार्य पूरा किया।

प्रत्येक कक्षा में जब आप स्पष्ट समय चाहते हैं तो चले जाना चाहते हैं, आपको ऐसा करने की आवश्यकता है:

    ... interesting code stuff ...
    Intent i = new Intent(MyActivityThatNeedsToGo.this, NextActivity.class);
    startActivityForResult(i, 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == R.string.unwind_stack_result_id) {
        this.setResult(R.string.unwind_stack_result_id);
        this.finish();
    }
}

तब स्टैक से चबूतरे की श्रृंखला को सेट करने की आवश्यकता होती है, जब आपको इसे आरंभ करने की आवश्यकता होती है, तो बस इसे कॉल करें:

NextActivity.this.setResult(R.string.unwind_stack_result_id);
NextActivity.this.finish();

तब गतिविधियाँ ढेर पर नहीं होती हैं!
लोगों को याद रखें, कि आप एक गतिविधि शुरू कर सकते हैं, और फिर उसके पीछे सफाई शुरू कर सकते हैं, निष्पादन एक (ui) धागे का पालन नहीं करता है।


यदि बाद में किसी को भी यह पता चलता है, तो मुझे लगा कि यह जानना महत्वपूर्ण हो सकता है, अगर आपने स्क्रीन को घुमाया है, तो जब आप स्टैक से अंतिम गतिविधि को हटाते हैं, तो एंड्रॉइड आपके लिए आपके आवेदन को फिर से शुरू करने में मदद करेगा। बस इस के बारे में पता होना चाहिए!
ट्रैविस

यह एक अच्छा जवाब है अगर आप केवल सशर्त पर निर्भर करता है कि क्या उपयोगकर्ता +1 गतिविधि में करता ढेर से एक गतिविधि निकालना चाहते हैं
theMothaShip

23

एक तरीका जो पहले एपीआई 11 काम करता है ActivityGameMain, उसे पहले शुरू करना है , फिर onCreateउस गतिविधि में अपनी ActivitySplashScreenगतिविधि शुरू करें । ActivityGameMainके रूप में आप startActivity छप के लिए भी जल्द ही फोन दिखाई नहीं देगा।

तब आशय पर इन झंडों को सेट करके शुरू करने पर आप स्टैक साफ़ कर सकते हैंActivityGameMain :

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

आपको इसे भी ActivSplashScreen में जोड़ना होगा:

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

ताकि उस गतिविधि पर वापस दबाव डालने से आप वापस न जाएं ActivityGameMain

मुझे लगता है कि आप नहीं चाहते कि स्प्लैश स्क्रीन या तो वापस चली जाए, इसे प्राप्त करने के लिए मैं इसे noHistoryआपके में सेट करने का सुझाव देता हूं AndroidManifest.xml। फिर अपने में goBackPressedकोड डालेंActivitySplashScreenSignUp बजाय कक्षा ।

हालाँकि मुझे इसे तोड़ने के कुछ तरीके मिले हैं। एक अधिसूचना से दूसरे ऐप को शुरू करेंActivitySplashScreenSignUpदिखाया गया है, वापस इतिहास रीसेट नहीं है।

इसके चारों ओर एकमात्र वास्तविक तरीका API 11 में है:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

20

मैं इस तरह का उपयोग करता हूं।

Intent i = new Intent(MyOldActivity.this, MyNewActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);

धन्यवाद। मुझे इस मामले में यह मददगार लगा कि मेरे मेनू में एक होम बटन था, और मैं यह नहीं चाहता था कि स्टैक्ड गतिविधियाँ दिखाई दें जब उपयोगकर्ता वहाँ से घर पर क्लिक करता है।
गितेश

8

मुझे पता है कि मुझे इस पर देर है (यह सवाल पूछे जाने के बाद से दो साल हो गए हैं), लेकिन मैंने बैक बटन प्रेस को इंटरसेप्ट करके इसे पूरा किया। विशिष्ट गतिविधियों की जाँच करने के बजाय, मैं सिर्फ गिनती देखता हूँ और यदि यह 3 से कम है तो यह बस ऐप को बैक में भेजता है (ऐप को रोक देता है और लॉन्च से पहले जो कुछ भी चल रहा था उसे उपयोगकर्ता को वापस लौटा देता है)। मैं तीन से कम की जांच करता हूं क्योंकि मेरे पास केवल एक इंट्रो स्क्रीन है। इसके अलावा, मैं गिनती की जांच करता हूं क्योंकि मेरा ऐप उपयोगकर्ता को मेनू के माध्यम से होम स्क्रीन पर वापस नेविगेट करने की अनुमति देता है, इसलिए यह उन्हें सामान्य स्क्रीन की तरह अन्य स्क्रीन के माध्यम से बैकअप लेने की अनुमति देता है अगर स्टैक पर इंट्रो स्क्रीन के अलावा अन्य गतिविधियां हैं।

//We want the home screen to behave like the bottom of the activity stack so we do not return to the initial screen
//unless the application has been killed. Users can toggle the session mode with a menu item at all other times.
@Override
public void onBackPressed() {
    //Check the activity stack and see if it's more than two deep (initial screen and home screen)
    //If it's more than two deep, then let the app proccess the press
    ActivityManager am = (ActivityManager)this.getSystemService(Activity.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = am.getRunningTasks(3); //3 because we have to give it something. This is an arbitrary number
    int activityCount = tasks.get(0).numActivities;

    if (activityCount < 3)
    {
        moveTaskToBack(true);
    }
    else
    {
        super.onBackPressed();
    }
}

7

प्रकट में आप जोड़ सकते हैं:

android:noHistory="true"

<activity
android:name=".ActivityName"
android:noHistory="true" />

आप भी कॉल कर सकते हैं

finish()

कॉल करने के तुरंत बाद प्रारंभ (..)


2
गतिविधि झंडे का उपयोग करने से बेहतर है कि चीजों को प्रकट में रखा जाए।
ट्रेवर हार्ट


4

यह पागल है कि किसी ने भी इस सुरुचिपूर्ण समाधान का उल्लेख नहीं किया है। यह स्वीकृत उत्तर होना चाहिए।

SplashActivity -> AuthActivity -> DashActivity

if (!sessionManager.isLoggedIn()) {
    Intent intent = new Intent(context, AuthActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    context.startActivity(intent);
    finish();
} else {
   Intent intent = new Intent(context, DashActivity.class);
   context.startActivity(intent);
    finish();
}

यहां कुंजी का उपयोग intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); मध्यस्थ के लिए करना है Activity। एक बार जब वह मध्य लिंक टूट जाता है, DashActivityतो स्टैक में पहली और आखिरी इच्छा होगी।

android:noHistory="true"एक बुरा समाधान है, क्योंकि यह Activityकॉलबैक जैसे उदाहरण पर निर्भर होने पर समस्याओं का कारण बनता है onActivityResult। यह अनुशंसित समाधान है और इसे स्वीकार किया जाना चाहिए।


1
यह झंडा सच होने के लिए बहुत अच्छा लग रहा था। FLAG_ACTIVITY_NO_HISTORY अच्छी तरह से काम करता है और जब तक कोई ऐप को बैकग्राउंड में नहीं रखता है और तब तक फिर से ग्राउंडग्राउंड होता है, जबकि स्टैक के शीर्ष पर ध्वज के साथ गतिविधि होती है। पृष्ठभूमि में जाने पर, गतिविधि नष्ट हो जाती है। ऐप पर लौटते समय, कोई स्टैक से पिछली गतिविधि को देखेगा। मैं निश्चित रूप से ऐसा व्यवहार नहीं चाहता था।
नेवरटेन्टरमून

4

बहुत देर हो चुकी है लेकिन आशा है कि यह मदद करेगा। अधिकांश उत्तर सही दिशा में इशारा नहीं कर रहे हैं। ऐसी बात के लिए दो सरल झंडे हैं।

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

Android डॉक्स से:

सार्वजनिक स्थैतिक अंतिम int FLAG_ACTIVITY_CLEAR_TASK एपीआई स्तर 11 में जोड़ा गया

If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the

गतिविधि शुरू होने से पहले साफ किया जाना चाहिए। यही है, गतिविधि एक अन्यथा खाली कार्य की नई जड़ बन जाती है, और कोई भी पुरानी गतिविधियां समाप्त हो जाती हैं। इसका उपयोग केवल FLAG_ACTIVITY_NEW_TASK के संयोजन में किया जा सकता है।


1

बस इस तरह से फोन करें।

       Intent intent = new Intent(ActivityOne.this, ActivityTwo.class);
        this.finish();
        startActivity(intent);

जिन उपयोगकर्ताओं को "यह" पर त्रुटि है, उन्हें इसे "
ActivOne.this

1

एक इतिहास से किसी गतिविधि को हटाना उस गतिविधि से पहले ध्वज को सेट करके किया जाता है जिसे आप नहीं चाहते हैं

A-> बी> सी> डी

मान लीजिए कि A, B, C और D 4 गतिविधियाँ हैं, यदि आप B और C को साफ़ करना चाहते हैं, तो ध्वज को सेट करें

intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

गतिविधि में ए और बी

यहाँ कोड बिट है

Intent intent = new Intent(this,Activity_B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);

0
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            super.finishAndRemoveTask();
        }
        else {
            super.finish();
        }

-7

इसे इस्तेमाल करे:

intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)

यह एपीआई स्तर 1 है, लिंक की जांच करें


2
यह क्या करना चाहिए है? निश्चित रूप से प्रश्न में समस्या का समाधान नहीं है।
रॉडरिगो-सिल्वेरा

क्या आप सुनिश्चित हैं कि आपका मतलब नहीं था Intent.FLAG_ACTIVITY_NO_HISTORY?
दंगा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.