गतिविधि संदर्भ के बाहर से कॉलिंग प्रारंभ ()


367

मैंने ListViewअपने Android एप्लिकेशन में लागू किया है । मैं ListViewवर्ग के एक कस्टम उपवर्ग का उपयोग करके इसे बांधता हूं ArrayAdapter। ओवरराइड ArrayAdapter.getView(...)विधि के अंदर , मैं एक असाइन करता हूं OnClickListener। की onClickविधि में OnClickListener, मैं एक नई गतिविधि शुरू करना चाहता हूं। मुझे इसका अपवाद मिला:

Calling startActivity() from outside of an Activity  context requires the  
FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

मैं कैसे प्राप्त कर सकता हूं Contextकि ListView(वर्तमान Activity) के तहत काम कर रहा है?


1
मुझे लगता है कि एलेक्स का जवाब आपकी समस्या का 'स्वीकृत' समाधान होना चाहिए, क्योंकि यह आपके द्वारा अधिक सामान्य तरीके से बताई गई त्रुटि को ठीक करता है
devanshu_kaushik

10
मुझे प्यार है कि "क्या यह वास्तव में आप चाहते हैं?" ... मुझे इससे पहले एक संदेश मिला है "क्या आप सुनिश्चित हैं कि आप एक प्रसारण रिसीवर को अनजाने में कहीं भूल नहीं गए?" बहुत बढ़िया! हमारी मदद करने के लिए इन सभी छोटे संदेशों को रखने के लिए हमारी ओर से सलाम।
नेरडी बंज

1
मैं इस मुद्दे से मिला। जब मैंने 28 को targetSdkVersion को अपडेट किया।
भ्रम

जवाबों:


574

भी

  • अपने एडॉप्टर में कंस्ट्रक्टर के माध्यम से संदर्भ वस्तु को कैश करें, या
  • इसे अपने विचार से प्राप्त करें।

या अंतिम उपाय के रूप में,

  • जोड़ें - अपने इरादे के लिए FLAG_ACTIVITY_NEW_TASK ध्वज:

_

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

संपादित करें - मैं झंडे स्थापित करने से बचूंगा क्योंकि यह घटना और इतिहास के ढेर के सामान्य प्रवाह में हस्तक्षेप करेगा।


6
टेक्स्टव के ऑटोलिंक फ़ीचर के बारे में क्या जहां मैं सिस्टम द्वारा बनाए गए इरादे (और इस तरह से झंडे) को नियंत्रित नहीं कर सकता हूं?
एलेक्स सेमेनिएक

75
जब मैं कुछ इस तरह कर रहा था मैं इस अपवाद हो रही थी context.startActivity(intent);अभी-अभी बदली contextसे ApplicationContextकरने के लिए Activityलिखें। इससे समस्या ठीक हो गई।
सूफियान नोव

@AlexSemeniuk कभी कोई हल ढूंढे?

@AlexSemeniuk - ऑटोलिंक तब तक काम करेगा जब तक आप एडॉप्टर के संदर्भ में गतिविधि को पास करते हैं
Georges

मैंने कंस्ट्रक्टर के माध्यम से कॉन्टेक्ट ऑब्जेक्ट पारित किया, लेकिन इसके काम नहीं किया। लेकिन मेरे लिए FLAG_ACTIVITY_NEW_TASK बहुत अच्छी तरह से काम करता है धन्यवाद।
हिरेन

100

आप इसके बजाय addFlags के साथ इसे प्राप्त कर सकते हैंsetFlags

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

प्रलेखन के अनुसार यह करता है:

आशय में अतिरिक्त झंडे जोड़ें (या मौजूदा झंडे मूल्य के साथ)।


संपादित करें

अगर आप उन झंडों का उपयोग कर रहे हैं जिनके बारे में आप इतिहास में बदलाव करते हैं, तो एलेक्स वोलोवॉय के जवाब में कहें :

... झंडे लगाने से बचें क्योंकि यह घटना और इतिहास के ढेर के सामान्य प्रवाह में हस्तक्षेप करेगा।


1
मुझे एक समान समस्या है। क्या आपने इतिहास स्टैक के साथ किसी भी समस्या का अनुभव किया है या चीनी के ऊपर के उत्तर के रूप में कुछ और?
इयॉन सुंदरन

1
मुझे ठीक से पता नहीं है कि आप क्या देख रहे हैं, लेकिन आप इस तरह के इतिहास के बिना एक गतिविधि शुरू कर सकते हैं: इरादा इरादा = नया इरादा (Intent.ACTION_VIEW, "http: \\ www.google.com")), इरादा। addFlags (Intent.FLAG_ACTIVITY_NO_HISTORY); startActivity (आशय);
ब्रूनो बीरी

ऐसा क्यों है कि यहाँ जोड़ने के लिए अनुशंसित नहीं है? घटना और इतिहास के सामान्य प्रवाह में हस्तक्षेप करना कितना महत्वपूर्ण है?
जेसन क्र्स

@JasonKrs आप addFlags का उपयोग कर सकते हैं। बस इस बात से अवगत रहें कि आप जो झंडा जोड़ते हैं उसके आधार पर आप इतिहास के ढेर को बदल सकते हैं। इस स्थिति में FLAG_ACTIVITY_NEW_TASK का उपयोग किया जा सकता है। अधिक जानकारी के लिए पढ़ें: developer.android.com/reference/android/content/…
ब्रूनो बिएरी


40

अगर आपको नीचे की तरह create chooser का उपयोग करने में त्रुटि हुई है:

Intent sharingIntent = new Intent(Intent.ACTION_VIEW);
sharingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sharingIntent.setData(Uri.parse("http://google.com"));
startActivity(Intent.createChooser(sharingIntent, "Open With"));

इस तरह से चयनकर्ता बनाने के लिए ध्वज सेट करें:

Intent sharingIntent = new Intent(Intent.ACTION_VIEW);
sharingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sharingIntent.setData(Uri.parse("http://google.com"));

Intent chooserIntent = Intent.createChooser(sharingIntent, "Open With");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(chooserIntent);

4
यह बहुत उपयोगी था। वास्तव में चयनकर्ता के इरादे में यह ध्वज होना चाहिए!
महदी

2
यह सही soluction है, और वास्तव में क्या करना, intent.chooser में new_task है
राफेल Guimarães

15

इसके अलावा: यदि आप टुकड़े में सूची में लिंक दिखाते हैं , तो इसे इस तरह से न बनाएं

adapter = new ListAdapter(getActivity().getApplicationContext(),mStrings);

इसके बजाय कॉल करें

adapter = new ListAdapter(getActivity(),mStrings);

एडॉप्टर दोनों मामलों में ठीक काम करता है, लेकिन लिंक केवल पिछले एक में काम करते हैं।


@ user2676468: इसने मेरे लिए ऑटोलिंक समस्या को हल कर दिया।
हेड गीक

यह एक स्वीकृत उत्तर होना चाहिए, झंडे का उपयोग करने के बजाय यह बेहतर है !!
बजे गैस्टोन सेलेन

@ GastónSaillén, मैं उपयोग नहीं करता getApplicationContext()(आवेदन आरंभीकरण को छोड़कर), लेकिन इस अपवाद को पकड़ लिया। तो, परिस्थितियां अलग हो सकती हैं।
कूलमाइंड

यह मेरी समस्या थी, मैंने संदर्भ के लिए getApplicationContext () का उपयोग किया। thisसंदर्भ के रूप में सेट करना वर्तमान गतिविधि से संबंधित है।
ब्रज

14

मुझे लगता है कि शायद आप OnClickListener को गलत स्थान पर लागू कर रहे हैं - आमतौर पर आपको अपनी गतिविधि में एक OnItemClickListener को लागू करना चाहिए और इसे इसके बजाय ListView पर सेट करना चाहिए, या आपको अपनी घटनाओं के साथ समस्याएँ आएंगी ...


2
तुम मुझे समाधान की ओर ले चलो। मैं एक OnItemClickListener का उपयोग करने की जरूरत है, ListView को सौंपा। यहाँ किसी और के लिए कुछ लिंक दिए गए हैं: developer.android.com/reference/android/widget/… androidpeople.com/… मदद के लिए धन्यवाद।
सकोह 73

कृपया सामान्य उत्तर दें। नीचे दिए गए एलेक्स वोलोवॉय का जवाब समस्या को एक सामान्य तरीके से हल करता है।
देवांशु_कौशिक

पोस्टरिटी के लिए: यदि आप इसे सीधे सेटलाइनर (नए श्रोता) के रूप में परिभाषित करते हैं, तो एक घटक के लिए एक संदर्भ की आवश्यकता होती है, आप पूरी गतिविधि का एक अंतर्निहित संदर्भ बनाते हैं जो स्मृति को लीक कर देगा जैसे आप विश्वास नहीं करेंगे। इसे स्थिर आंतरिक श्रेणी श्रोता बनाकर या श्रोता को एक अलग वर्ग में ले जाने से दरकिनार किया जा सकता है, अगर इसे एक से अधिक मूल से इनपुट को संभालने में सक्षम होना चाहिए।
G_V

9
CustomAdapter mAdapter = new CustomAdapter( getApplicationContext(), yourlist);

या

Context mContext = getAppliactionContext();
CustomAdapter mAdapter = new CustomAdapter( mContext, yourlist);

नीचे बदलें

CustomAdapter mAdapter = new CustomAdapter( this, yourlist);

8

पर Android 28(Android P)startActivity

if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
        && (targetSdkVersion < Build.VERSION_CODES.N
                || targetSdkVersion >= Build.VERSION_CODES.P)
        && (options == null
                || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
    throw new AndroidRuntimeException(
            "Calling startActivity() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                    + " Is this really what you want?");
}

तो सबसे अच्छा तरीका है जोड़ना FLAG_ACTIVITY_NEW_TASK

Intent intent = new Intent(context, XXXActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);

यह 28 और ऊपर के उपकरणों के लिए आवश्यक है।
एमडी मोहसिन

7

देखें, यदि आप किसी विधि में एक सूची के भीतर एक इरादा बना रहे हैं

override onClick (View v).

फिर इस दृश्य के माध्यम से संदर्भ को कॉल करें:

v.getContext ()

वहाँ भी SetFlags की जरूरत नहीं होगी ...


और गलत स्थिति क्या थी? v.getApplicationContext ()?
कूलमैन्ड

3

Xamarin.Android (MonoDroid) पर किसी के लिए भी जब StartActivity गतिविधि से पुकारा जाता है - यह वास्तव में नए ART रनटाइम के साथ Xamarin बग है, https://bugzilla.xamarin.com/show_bod.cgi?id=17630 देखें


हाँ, आपको बस वही करना है जो ऊपर वर्णित किया गया है, लेकिन शब्दांकन बदल गया है ... अभिप्रेत। SeFlags (ActivityFlags.NewTask);
ल्यूक एल्डरटन

3

एलेक्स वोलोवॉय के जवाब को थोड़ा और विस्तृत करते हुए -

यदि आप को यह समस्या हो रही है, तो संदर्भ के लिए getActivity () ठीक काम करती है

अन्य मामलों में:

यदि आप उपयोग नहीं करना चाहते हैं-

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//not recommend

तो अपने बाहरी क्षेत्र में इस तरह के एक समारोह बनाने के लिए -

public void gettingContext(Context context){
    real_context = context;//where real_context is a global variable of type Context
}

अब, अपनी मुख्य गतिविधि में जब आप कभी भी एक नया आउटसाइडक्लास बनाते हैं, तो उपरोक्त गतिविधि को तर्क के रूप में गतिविधि के संदर्भ में देने के तुरंत बाद उपरोक्त विधि को कहें। अपनी मुख्य गतिविधि में भी एक कार्य करें-

public void startNewActivity(final String activity_to_start) {
    if(activity_to_start.equals("ACTIVITY_KEY"));
    //ACTIVITY_KEY-is a custom key,just to
    //differentiate different activities
    Intent i = new Intent(MainActivity.this, ActivityToStartName.class);
    activity_context.startActivity(i);      
}//you can make a if-else ladder or use switch-case

अब अपने बाहरी क्षेत्र में वापस आएं, और नई गतिविधि शुरू करने के लिए कुछ इस तरह करें-

@Override
public void onClick(View v) {
........
case R.id.any_button:

            MainActivity mainAct = (MainActivity) real_context;             
            mainAct.startNewActivity("ACTIVITY_KEY");                   

        break;
    }
........
}

इस तरह आप झंडे के साथ खिलवाड़ किए बिना अलग-अलग आउटसाइडक्लास से बुलाए गए विभिन्न गतिविधियों को शुरू कर पाएंगे।

नोट-प्रयास करें कि खंड के लिए रचनाकार के माध्यम से संदर्भ ऑब्जेक्ट को कैश न करें (एडॉप्टर, इसके ठीक) के साथ। एक टुकड़ा में एक खाली निर्माण होना चाहिए अन्यथा कुछ परिदृश्यों में एप्लिकेशन क्रैश हो जाता है।

कॉल करना याद रखें

OutsideClass.gettingContext(Context context);

onResume () फ़ंक्शन के रूप में अच्छी तरह से।


3

यह त्रुटि तब होती है जब सक्रियता को पता नहीं होता है कि उसकी गतिविधि कौन सी है। तो आपको सक्रियता शुरू करने से पहले जोड़ना होगा ()

आपको सेट करना होगा

context.startActivity(yourIntent);

यदि आप कॉल करते startActivityहैं Fragment, तो एक कॉलर अक्सर एक टुकड़ा हो सकता है, गतिविधि नहीं।
कूलमाइंड

2

मेरी राय startActivity()में, आपके कोड में बस की विधि का उपयोग करना बेहतर है Activity.class। यदि आप Adapterइसे या अन्य वर्ग में उपयोग करते हैं , तो इसका परिणाम यह होगा।


2

मेरी भी यही समस्या थी। आपके द्वारा पारित सभी संदर्भ देखें। ' लिंक ' के लिए इसे एक्टिविटी कॉन्सेप्ट चाहिए न कि एप्लिकेशन संदर्भ

यह वह जगह है जहां आपको जांच करनी चाहिए:

1.) यदि आपने LayoutInflater का उपयोग किया है, तो जांचें कि आपने किस संदर्भ में पास किया है।

2.) यदि आप किसी भी एडेप्टर का उपयोग कर रहे हैं, तो आप किस संदर्भ में पास हुए हैं।


2

मुझे भी यही समस्या थी। समस्या संदर्भ के साथ है। यदि आप कोई लिंक खोलना चाहते हैं (उदाहरण के लिए किसी भी लिंक को चॉसर के माध्यम से साझा करना) तो गतिविधि संदर्भ, न कि एप्लिकेशन संदर्भ।

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)यदि आप अपनी गतिविधि में नहीं हैं, तो जोड़ना न भूलें ।


2

अपने Adapter_Activity में इस कोड का उपयोग करें और उपयोग करें context.startActivity(intent_Object)औरintent_Object.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

ऐशे ही:

Intent n_act = new Intent(context, N_Activity.class);
n_act.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(n_act);

यह काम करता हैं....


1
Intent viewIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);    
viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    
startActivity(viewIntent);   

मुझे उम्मीद है कि यह काम करेगा।


1

फिर उसी मुद्दे को लागू किया गया

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

और समस्या हल हो गई।

एक और कारण हो सकता है जो सूची दृश्य एडाप्टर से संबंधित है।
आप इस ब्लॉग को देख सकते हैं , यह बहुत अच्छी तरह से वर्णित है।


उपयोगी ब्लॉग, धन्यवाद। :)
रुचा भट्ट जोशी

1

इस कोड का उपयोग करें। मेरे लिए ठीक काम करता है। किसी गतिविधि के बाहर से कुछ साझा करें:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");

// Append Text
String Text = "Your Text Here"

intent.putExtra(Intent.EXTRA_TEXT, Text);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Intent shareIntent = Intent.createChooser(intent,"Share . . . ");
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
G.context.getApplicationContext().startActivity(shareIntent);

झंडे स्थापित करना ढेर इतिहास को गड़बड़ कर देता है
एजियो

1

चूंकि झंडे जोड़ने से प्रभावित होता है event_flowऔर stack_historyगैर-गतिविधि के लिए 'एप्लिकेशन संदर्भ' को पास करना बेहतर होता है, जहां से आपको निम्नलिखित तरीके से गतिविधि वर्ग को कॉल करने की आवश्यकता होती है:

"ActivityClassName.this" (जब आप इस तरीके से संदर्भ पास करते हैं, तो इसमें वह सभी विवरण और जानकारी होगी जो आपको एक गैर-गतिविधि परिदृश्य से गतिविधि को कॉल करने की आवश्यकता होती है)

इसलिए झंडे लगाने या जोड़ने की कोई आवश्यकता नहीं है, यह हर मामले में ठीक काम करेगा।



0

यदि आप कॉर्डोवा प्लगइन में शेयर इंटेंट को आमंत्रित कर रहे हैं, तो फ्लैग सेट करने से मदद नहीं मिलेगी। इसके बजाय इसका उपयोग करें -

cordova.getActivity().startActivity(Intent.createChooser(shareIntent, "title"));

0

मेरी स्थिति थोड़ी अलग थी, मैं अपने ऐप का उपयोग करके परीक्षण कर Espressoरहा हूं और मुझे अपनी गतिविधि ActivityTestRuleको इंस्ट्रूमेंटेशन Context(जो कि एक से नहीं आ रहा है Activity) से लॉन्च करना था ।

fun intent(context: Context) = 
    Intent(context, HomeActivity::class.java)
        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

मुझे झंडे बदलने पड़े और or( |जावा में) एक बिट वाइज जोड़ना पड़ाIntent.FLAG_ACTIVITY_NEW_TASK

तो यह परिणाम है:

fun intent(context: Context) = 
    Intent(context, HomeActivity::class.java)
        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)

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