मैं मूल गतिविधि में सही तरीके से कैसे लौट सकता हूं?


179

मेरे एंड्रॉइड एप्लिकेशन में 2 गतिविधियां (ए और बी) हैं और मैं गतिविधि ए से गतिविधि बी तक पहुंचने के इरादे का उपयोग करता हूं। पेरेंट_एक्टिविटी का उपयोग सक्षम है:

 <activity
        android:name=".B"
        android:label="B" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.app_name.A" />
  </activity>

मैं एक थीम का भी उपयोग करता हूं जो एक यूपी-बटन प्रदान करता है।

इसलिए जब मैंने गतिविधि को कॉल किया तो बीआई गतिविधि ए पर वापस जाने के लिए यूपी-बटन का उपयोग कर सकता है। समस्या यह है कि एप्लिकेशन ऑन-क्रिएट () गतिविधि के-ए को फिर से कॉल करने लगता है और यह वह व्यवहार नहीं है जिसकी मुझे आवश्यकता है। मुझे गतिविधि ए की उसी तरह देखने की ज़रूरत है जैसे गतिविधि बी को कहने से पहले इसे देखा था।

क्या इसको हासिल करने के लिए कोई रास्ता है?

अग्रिम में धन्यवाद

संपादित करें:

मैंने गतिविधि ए से गतिविधि बी शुरू करने के लिए कोई कोड नहीं लिखा था। मुझे लगता है कि यह ग्रहण द्वारा स्वतःपूर्ण है।

क्लास बी लगता है:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_b, menu);
    return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
    }
    return super.onOptionsItemSelected(item);
}

गतिविधि A को B से शुरू करने के लिए, आपको पोस्ट करें ..
user370305

अगर मैं आपको सही समझता हूं, तो आप startActivityForResult () का उपयोग कर सकते हैं और एक परिणाम या कुछ वापस कर सकते हैं।
कानून Gimenez

कृपया अपने टैग किए गए सही उत्तर को अपडेट करें! सही जवाब लोरेंजेक से आ रहा है - उपयोगकर्ता से नहीं ......! इसे सही के रूप में टैग करना भ्रामक है और इससे भी अधिक प्रोग्रामर नेविगेशन को गलत समझते हैं क्योंकि बैक नेविगेशन के विपरीत है!
जोर्डिड

जी, यहाँ इतने सारे गलत जवाब, क्या आप कृपया इसे साफ करने में मदद कर सकते हैं ...?
जोर्डिड

@ शशि - आपके कोड डिज़ाइन के अनुसार सही उत्तर अपडेट किया गया है।
user370305

जवाबों:


334

आपने launchModeएंड्रॉइड मेनिफेस्ट में मानक ए के साथ गतिविधि ए की घोषणा की। प्रलेखन के अनुसार , इसका मतलब है कि निम्नलिखित:

सिस्टम हमेशा लक्ष्य कार्य में गतिविधि का एक नया उदाहरण बनाता है और इसके इरादे को मार्ग देता है।

इसलिए, onCreateकार्य स्टैक को सही तरीके से हैंडल करने पर भी सिस्टम ए (यानी कॉलिंग ) को दोबारा बनाने के लिए मजबूर होता है।

इस समस्या को ठीक करने के लिए, आपको एक्टिविटी घोषणा में निम्नलिखित विशेषता को जोड़ते हुए, मेनिफ़ेस्ट को बदलना होगा:

android:launchMode="singleTop"

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


11
यहाँ एंड्रॉइड डॉक्स से स्पष्टीकरण दिया गया है, "मानक" और "सिंगलटॉप" मोड एक-दूसरे से केवल एक सम्मान में भिन्न होते हैं: हर बार "मानक" गतिविधि के लिए एक नया इरादा होता है, जवाब देने के लिए कक्षा का एक नया उदाहरण बनाया जाता है वह इरादा। प्रत्येक उदाहरण एक एकल इरादे को संभालता है। इसी तरह, एक नए इरादे को संभालने के लिए "सिंगलटॉप" गतिविधि का एक नया उदाहरण भी बनाया जा सकता है। हालाँकि, यदि टारगेट टास्क में पहले से ही अपने स्टैक के शीर्ष पर गतिविधि का एक मौजूदा उदाहरण है, तो वह उदाहरण नया आशय प्राप्त करेगा (onNewIntent () कॉल); एक नया उदाहरण नहीं बनाया गया है।
kpsfoo

ध्यान दें कि के अनुसार प्रलेखन navigateUpFromSameTask(...) जोड़ने होना चाहिए FLAG_ACTIVITY_CLEAR_TOPकरने के लिए upIntent(के माध्यम से navigateUpTo(...)जो एक ही व्यवहार में परिणाम चाहिए (के अनुसार इस गाइड ), लेकिन ध्वज सेट कभी नहीं रहा है - और इसलिए इस सवाल का जवाब समझ में आता है
Anigif

82

अपडेट किया गया उत्तर: नेविगेशन डिजाइन

आपको यह घोषित करना होगा कि कौन सी गतिविधि प्रत्येक गतिविधि के लिए उपयुक्त जनक है। ऐसा करने से सिस्टम को नेविगेशन पैटर्न जैसे अप को सुविधाजनक बनाने की अनुमति मिलती है क्योंकि सिस्टम प्रकट फ़ाइल से तार्किक मूल गतिविधि को निर्धारित कर सकता है।

तो इसके लिए आपको अपने पैरेंट एक्टिविटी को विशेषता के साथ टैग एक्टिविटी में घोषित करना होगा

android:parentActivityName

पसंद,

<!-- The main/home activity (it has no parent activity) -->
    <activity
        android:name="com.example.app_name.A" ...>
        ...
    </activity>
    <!-- A child of the main activity -->
    <activity
        android:name=".B"
        android:label="B"
        android:parentActivityName="com.example.app_name.A" >
        <!-- Parent activity meta-data to support 4.0 and lower -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.app_name.A" />
    </activity>

इस तरह घोषित अभिभावक गतिविधि के साथ, आप नीचे दिए गए उपयुक्त माता-पिता तक नेविगेट कर सकते हैं,

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // Respond to the action bar's Up/Home button
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

इसलिए जब आप NavUtils.navigateUpFromSameTask(this);इस विधि को कहते हैं , तो यह वर्तमान गतिविधि को पूरा करता है और उपयुक्त मूल गतिविधि को शुरू (या फिर से शुरू) करता है। यदि लक्ष्य माता-पिता की गतिविधि कार्य के बैक स्टैक में है, तो इसे परिभाषित किया गया है FLAG_ACTIVITY_CLEAR_TOP

और अप बटन प्रदर्शित करने के लिए आपको घोषणा करनी होगी setDisplayHomeAsUpEnabled():

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

पुराना उत्तर: (बिना नेविगेशन के, डिफ़ॉल्ट बैक नेविगेशन)

यह तभी होता है जब आप गतिविधि ए को फिर से गतिविधि बी से शुरू कर रहे हैं।

का उपयोग कर startActivity()

इसके बजाय गतिविधि ए से गतिविधि बी का उपयोग शुरू करें startActivityForResult()और onActivtyResult()गतिविधि ए में ओवरराइड करें ।

अब गतिविधि बी में केवल finish()बटन अप पर कॉल करें। तो अब आपने onActivityResult()गतिविधि ए को फिर से गतिविधि ए के निर्माण के बिना निर्देशित किया ।


मुझे पता नहीं है कि गतिविधि B में StartActivity () कहां कहा जाता है। मैंने गतिविधि B का स्रोत कोड पोस्ट किया है ...
ashiaka

18
कोड लाइन NavUtils.navigateUpFromSameTask(this); लिखने के बजाय finish()
user370305

4
यह सवाल है, कैसे आता है कि Google ने नेविगेशन ( developer.android.com/design/patterns/navigation.html ) पर अपने दस्तावेज़ में finish()या startActivityForResult()उसके बारे में कुछ भी उल्लेख नहीं किया है ?
वायर्ड00

यह एक श्रमसाध्य लगता है। @LorenzCK का जवाब ज्यादा बेहतर लगता है।
carmen_munich

NavUtils.navigateUpFromSameTask (यह) का उपयोग करने के लिए बहुत बहुत धन्यवाद। बड़ा प्लस! मैं फिनिश () को बदलने के लिए इस तरह की एक विधि की तलाश कर रहा हूं जो कुछ परिस्थितियों में मूल गतिविधि में वापस नहीं आती है। खत्म () अनिवार्य रूप से पिछली गतिविधि पर वापस जा रहा है जो कि मूल गतिविधि नहीं है।
हांग

22

मेरे पास बहुत ही समान सेटअप था जो एक ही अवांछित व्यवहार के लिए अग्रणी था। मेरे लिए यह काम किया: Manifest.xmlमेरे ऐप के गतिविधि ए में निम्नलिखित विशेषता को जोड़ना :

android:launchMode="singleTask"

अधिक स्पष्टीकरण के लिए इस लेख को देखें ।


1
मेरे दृष्टिकोण से समस्या का सही समाधान है। यह ठीक उसी तरह का व्यवहार करेगा जैसे अगर आप फिनिश कहते हैं () यदि कार्य स्टैक में मौजूद है। अगर ऐसा नहीं है तो इसे बनाया और शुरू किया जाएगा।
जोहान

5
यह सही तरीका नहीं है क्योंकि यह हर बार अनावश्यक रूप से एक नया कार्य बनाएगा, आपको इसके बजाय लॉन्चर = "सिंगलटाउन" का उपयोग करना चाहिए।
kpsfoo

19

हालांकि एक पुराना सवाल, यहाँ एक और (सबसे साफ और सबसे अच्छा) समाधान है क्योंकि पिछले सभी जवाब मेरे लिए काम नहीं करते थे क्योंकि मैंने एक विजेट से गतिविधि बी को हटा दिया था ।

public void navigateUp() {
final Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) {
    Log.v(logTag, "Recreate back stack");
        TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
  } else {
    NavUtils.navigateUpTo(this, upIntent);
  }
}

[ https://stackoverflow.com/a/31350642/570168 ]

लेकिन यह भी देखें: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android


7

इसे प्राप्त करने का एक बेहतर तरीका दो चीजों का उपयोग करना है: कॉल:

NavUtils.navigateUpFromSameTask(this);

अब, इसे काम करने के लिए, आपको अपनी प्रकट फ़ाइल स्थिति की आवश्यकता है कि गतिविधि A के पास एक पैरेंट गतिविधि है B. मूल गतिविधि को किसी भी चीज़ की आवश्यकता नहीं है। संस्करण 4 और इसके बाद के संस्करण में आपको बिना किसी अतिरिक्त प्रयास के एक अच्छा बैक एरो मिलेगा (यह निचले संस्करणों पर और साथ ही थोड़े कोड के साथ किया जा सकता है, मैं इसे नीचे रखूंगा) आप इस डेटा को मैनिफ़ेस्ट में सेट कर सकते हैं-> एप्लिकेशन टैब GUI में (मूल गतिविधि नाम तक स्क्रॉल करें, और इसे हाथ से डालें)

समर्थन नोड:

यदि आप संस्करण 4 से नीचे के संस्करण का समर्थन करना चाहते हैं, तो आपको मेटाडेटा को भी शामिल करना होगा। गतिविधि पर राइट क्लिक करें, जोड़ें-> मेटा डेटा, नाम = android.support.PARENT_ACTIVITY और मूल्य = your.full.activity.name

निम्न संस्करणों में अच्छा तीर पाने के लिए:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

कृपया ध्यान दें कि आपको यह सब काम करने के लिए लाइब्रेरी संस्करण 7 का समर्थन चाहिए होगा, लेकिन यह इसके लायक है!


5

मेरे लिए क्या काम कर रहा था:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onBackPressed() {
        finish();
    }

, TheRelevantActivity.javaऔर अब यह उम्मीद के मुताबिक काम कर रहा है

और हाँ जोड़ना मत भूलना:

getSupportActionbar.setDisplayHomeAsUpEnabled(true);में onCreate()विधि


4

मैंने कोशिश की android:launchMode="singleTask", लेकिन यह मदद नहीं की। का उपयोग कर मेरे लिए काम कियाandroid:launchMode="singleInstance"


Android जोड़ना: launchMode = "singleInstance" पेरेंट एक्टिविटी के लिए मेरे लिए समस्या हल की
emir

4

@ LorenCK के उत्तर में परिवर्तन करना

NavUtils.navigateUpFromSameTask(this);

नीचे दिए गए कोड से अगर आपकी गतिविधि किसी अन्य गतिविधि से शुरू की जा सकती है और यह किसी अन्य ऐप द्वारा शुरू किए गए कार्य का हिस्सा बन सकता है

Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    TaskStackBuilder.create(this)
            .addNextIntentWithParentStack(upIntent)
            .startActivities();
} else {
    NavUtils.navigateUpTo(this, upIntent);
}

यह एक नया कार्य शुरू करेगा और आपकी गतिविधि की मूल गतिविधि शुरू करेगा जिसे आप न्यूनतम एसडीके संस्करण के नीचे मैनिफेस्ट में परिभाषित कर सकते हैं <= 15

<meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.example.app_name.A" />

या parentActivityNameइसके> 15 का उपयोग करते हुए


नोट: parentActivityNameएसडीके के लिए घोषणा करें > 15 वरना यह आपको कुछ बेतरतीब क्रैश देगा
सौरभ

3

मुझे एक खराब पेरेंट एक्टिविटी नाम के साथ एंड्रॉइड 5.0 का उपयोग करने में एक समान समस्या थी

<activity
        android:name=".DisplayMessageActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName=".MainActivity" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />
    </activity>

मैंने पैरेंट एक्टिविटी नाम से com.example.myfirstapp हटा दिया और इसने ठीक से काम किया


2

विशेषता के साथ अपनी गतिविधि प्रकट जानकारी में जोड़ें

android:launchMode="singleTask"

मेरे लिए अच्छा काम कर रहा है


1
धूमकेतु प्रवाह ऐसा है कि @Override सार्वजनिक बूलियन onOptionsItemSelected (MenuItem आइटम) {स्विच (item.getItemId ()) {मामला android.R.id.home: NavUtils .navigateUpFromSameTask (यह); सच लौटना; } वापसी super.onOptionsItemSelected (आइटम); }
प्रवेश कुमार

अपने मैनिफ़ेस्ट में जोड़ें <activity android: name = "। MainActivity" android: label = "@ string / title_activity_main"> </ activity> <activity android: name = "। CreateEventActivity" android: label = = @ string / title_activity_create_event "android" : launchMode = "singleTask" android: parentActivityName = "। MainActivity"> <meta-data android: name = "android.support.PARENT_ACTIVITY" Android: value = "। MainActivity" /> </ activity>
Pravesh Kumar

2

जावा वर्ग में: -

    toolbar = (Toolbar) findViewById(R.id.apptool_bar);
    setSupportActionBar(toolbar);

    getSupportActionBar().setTitle("Snapdeal");

    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

मेनिफेस्ट में: -

<activity
            android:name=".SubActivity"
            android:label="@string/title_activity_sub"
            android:theme="@style/AppTheme" >
            <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity"></meta-data>
    </activity>

यह तुम्हे मदद करेगा


1
    @Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
    case android.R.id.home:
        finish();
        return true;
}
return super.onOptionsItemSelected(item);

बैक प्रेस की तरह


1

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

Intent intent;
@Override
public void onCreate(Bundle savedInstanceState) {
    intent = getIntent();   
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_b, menu);
    return true;
}  

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpTo(this,intent);
            return true;
    }
    return super.onOptionsItemSelected(item);
}

0

मेरे प्रकट होने और जोड़ने में android:launchMode="singleTop" गतिविधि में शामिल होने से मेरे लिए चाल चली गई।

इसने विशेष रूप से मेरी समस्या को हल कर दिया क्योंकि मैं नहीं चाहता था कि एंड्रॉइड को हिट करने के बाद पिछली गतिविधि का एक नया उदाहरण बनाएं Up कि टूलबार में बटन दबाए जाने के - जब मैं नेविगेशन पदानुक्रम के ऊपर गया तो मैं पहले की गतिविधि के मौजूदा उदाहरण का उपयोग करना चाहता था।

संदर्भ: एंड्रॉयड: लॉन्च


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