Android Fragment onAttach () पदावनत


326

मैंने नवीनतम समर्थन लाइब्रेरी (संस्करण 23.0.0) का उपयोग करने के लिए अपने ऐप को अपडेट किया है, मुझे पता चला है कि उन्होंने फ्रैगमेंट वर्ग के onAttach () फ़ंक्शन को हटा दिया है।

के बजाय:

onAttach (Activity activity)

यह बर्फ:

onAttach (Context context)

जैसा कि मेरा ऐप डेप्रिसिएशन से पहले पारित गतिविधि का उपयोग करता है, एक संभावित समाधान मुझे लगता है:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    activity = getActivity();
}

क्या ऐसा करने का सही तरीका होगा?

अपडेट करें:

अगर मैं 23 से कम API वाला उपकरण चलाता हूं, तो नया onAachach () भी नहीं बुलाया जा रहा है। मुझे आशा है कि यह वही नहीं है जो वे करने का इरादा रखते थे!

अद्यतन 2:

SDK के नवीनतम अद्यतनों के साथ समस्या का समाधान कर दिया गया है।

मैंने अपने API 22 डिवाइस पर परीक्षण किया है और onAttach (संदर्भ) कहा जा रहा है।

मैंने कुछ हफ़्ते पहले खोली गई बग रिपोर्ट और Google के लोगों के उत्तरों का अनुसरण करने के लिए यहाँ क्लिक करें


यदि आप अपने पास किए गए उदाहरण से विशिष्ट गतिविधि विधियों का उपयोग कर रहे हैं, तो क्या आपने अपनी गतिविधि के संदर्भ को दिखाने की कोशिश की है? याद रखें गतिविधि प्रसंग का एक उपवर्ग है। शायद एक कास्टिंग काम करेगा।
MarkSkayff

किसी कारण से, onAttach () को भी नहीं बुलाया जा रहा है! कोई विचार? क्या आपने नवीनतम समर्थन के लिए अद्यतन करने का प्रयास किया है।
तारेक खुरई

2
API क्यों ले जाया गया है Context? Activityएक टुकड़ा वैसे भी संलग्न करने और प्रदर्शित करने के लिए आपको एक की आवश्यकता नहीं है ? आप Contextपैरामीटर का उपयोग कैसे करेंगे ?
केनी वर्डेन

1
मैंने इसे एक बग के रूप में पोस्ट किया है, लिंक कोड देखें। http :
//www.p/android/issues/detail

6
नए onAttach(Context context)कहे जाने के लिए, आपको या तो एक डिवाइस का उपयोग करना होगा जिसमें कम से कम API 23 हो या android.support.v4.app.Forment का उपयोग करें। यहां
nevzo

जवाबों:


337

गतिविधि एक संदर्भ है, इसलिए यदि आप बस संदर्भ की जांच कर सकते हैं, तो गतिविधि है और यदि आवश्यक हो, तो उसे डालें।

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    Activity a;

    if (context instanceof Activity){
        a=(Activity) context;
    }

}

अद्यतन: कुछ दावा कर रहे हैं कि नया Contextओवरराइड कभी नहीं कहा जाता है। मैंने कुछ परीक्षण किए हैं और ऐसा परिदृश्य नहीं मिल सकता है जहां यह सत्य हो और स्रोत कोड के अनुसार, यह कभी भी सत्य नहीं होना चाहिए। सभी मामलों में मैंने परीक्षण किया, दोनों एसडीके 23 को प्री और पोस्ट किया, दोनों Activityऔर Contextसंस्करणों onAttachको बुलाया गया। यदि आप ऐसा परिदृश्य पा सकते हैं जहां ऐसा नहीं है, तो मैं आपको एक नमूना परियोजना बनाने का सुझाव दूंगा जो इस मुद्दे को दर्शाती है और इसे एंड्रॉइड टीम को रिपोर्ट करेगी ।

अपडेट 2: मैं केवल कभी एंड्रॉइड सपोर्ट लाइब्रेरी के टुकड़े का उपयोग करता हूं क्योंकि कीड़े वहां तेजी से तय हो जाते हैं। ऐसा लगता है कि उपरोक्त मुद्दा जहां ओवरराइड को सही ढंग से नहीं कहा जाता है केवल प्रकाश में आता है यदि आप फ्रेमवर्क टुकड़ों का उपयोग करते हैं।


5
वास्तव में संदर्भ के साथ onAttach के समाधान को गतिविधि के साथ onAttach के समान नहीं कहा जाता है। यदि आपके पास इस गतिविधि के पैरामीटर के रूप में onAttach में कुछ आरंभीकरण कोड है तो यह परिवर्तन काम नहीं करेगा।
बडी

2
नहीं, यह कम से कम मेरे मामले में समान नहीं है। मैं onAttach में गतिविधि और संदर्भ का उपयोग नहीं करता, मैं इनिशियलाइज़ेशन करता हूँ। मैंने गतिविधि के साथ onAttach को संदर्भ के साथ बदलने की कोशिश की है और यह उसी तरह से नहीं मिलता है। इसलिए वे आसानी से विनिमेय नहीं हैं।
बडी

7
बडी के पास जो समस्‍याएं हैं ... onAttach(Context)उसे भी नहीं कहा जाता है।
स्टीफन

2
मैंने अपने कोड के माध्यम से कदम रखा है और मैं यह सत्यापित कर सकता हूं कि इसे onAttach(context)नहीं बुलाया जाना संभव है ।
चाड बिंघम

2
यदि हम उस गतिविधि को पुनः आरंभ करते हैं जिसे सिस्टम द्वारा पहले ही मंजूरी दे दी गई है, तो onAttach () को नहीं बुलाया जाएगा। लेकिन यह हमेशा से ऐसा नहीं है। मैंने onAttach (संदर्भ संदर्भ) में एक WeakReference का प्रारंभ रखा, RefActivity = नया WeakReference <> ((AppCompatActivity) संदर्भ)। और यह NullPointerException को OnCreateView () में कभी-कभी फेंक देता है।
किमी चिउ

45

यह गूगल ... सुझाव संशोधन से दूसरे महान परिवर्तन है: की जगह onAttach(Activity activity)के साथ onAttach(Context context)के बाद से पुराने एपीआई पर मेरी क्षुधा दुर्घटनाग्रस्त onAttach(Context context)देशी टुकड़े पर बुलाया नहीं किया जाएगा।

मैं मूल अंशों (android.app.Fragment) का उपयोग कर रहा हूं, इसलिए मुझे पुराने APIs (<23) पर इसे फिर से काम करने के लिए निम्न करना पड़ा।

मैंने जो किया था यह रहा:

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    // Code here
}

@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        // Code here
    }
}

Mr.Yoann Hercouet, यह समझा सकता है कि आप इसे एपीआई 23 से ऊपर कैसे कर सकते हैं, कृपया मेरी मदद करें, अग्रिम धन्यवाद, E / AndroidRuntime: FATAL EXCEPTION: main, java.lang.ClassCastException: com.ual.SMS_Activity@afd5683, Android पर। support.v4.app.ragmentManagerImpl.moveToState, android.support.v4.app.ragmentManagerImpl.execSingleAction पर। यहाँ मैंने आवश्यक लाइनें पोस्ट कीं जो मेरे बग को जानने के लिए u हैं।
मोहनराज एस

@MohanRajS यह एपीआई 24 (आपके द्वारा उपयोग किया गया) पर समान है, आपके कोड ऑफ कोड के अनुसार, आपकी समस्या को इसके साथ कुछ भी करना प्रतीत नहीं होता है।
योआन हरकौट

@YoannHercouet, आपके उत्तर के लिए धन्यवाद, मुझे जांचने और अपडेट करने दें।
मोहनराज एस ०

1
पुराने API के लक्ष्यीकरण में कठिनाई के कारण आप इसके बारे में Google से खुश नहीं हैं। ठीक है, आशीर्वाद पर विचार करें कि आप पुराने API को लक्षित कर सकते हैं, जबकि Apple, उदाहरण के लिए, बस आपको अपंग बना देगा और आपको केवल नवीनतम लोगों का समर्थन करने के लिए मजबूर करेगा।
स्टेन

39

यदि आप फ्रेमवर्क अंशों का उपयोग करते हैं और डिवाइस का एसडीके संस्करण 23 से कम है, OnAttach(Context context) इसे नहीं कहा जाएगा।

मैं इसके बजाय समर्थन अंशों का उपयोग करता हूं, इसलिए पदावनति निश्चित है और onAttach(Context context)हमेशा कॉल किया जाता है।


11

वर्तमान में onAttachफ्रैगमेंट कोड से, यह स्पष्ट नहीं Contextहै कि वर्तमान गतिविधि क्या है: स्रोत कोड

public void onAttach(Context context) {
    mCalled = true;
    final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    if (hostActivity != null) {
        mCalled = false;
        onAttach(hostActivity);
    }
}

यदि आप एक बार देख लेंगे तो आप एक getActivityही कॉल देखेंगे

/**
 * Return the Activity this fragment is currently associated with.
 */
final public Activity getActivity() {
    return mHost == null ? null : mHost.getActivity();
}

तो अगर आप यकीन है कि तुम हो रही है गतिविधि तो का उपयोग होना चाहते हैं getActivity()(में onAttachअपनी Fragment), लेकिन भूल जाते हैं के लिए जाँच करने के लिए नहीं है nullक्योंकि अगर mHostहै nullअपनी गतिविधि हो जाएगाnull


6
@Override
public void onAttach(Context context) {
    super.onAttach(context);

    Activity activity = context instanceof Activity ? (Activity) context : null;
}

5

हालांकि ऐसा लगता है कि ज्यादातर मामलों में यह पर्याप्त है onAttach(Context), कुछ फोन हैं (यानी: Xiaomi Redme Note 2) जहां इसे नहीं बुलाया जा रहा है, इस प्रकार यह NullPointerException का कारण बनता है। तो सुरक्षित पक्ष पर होने के लिए मैं पदावनत विधि को छोड़ने का सुझाव देता हूं:

// onAttach(Activity) is necessary in some Xiaomi phones
@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    _onAttach(activity);
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    _onAttach(context);
}

private void _onAttach(Context context) {
    // do your real stuff here
}

3

एसडीके प्रबंधक के साथ नवीनतम समर्थन पुस्तकालय डाउनलोड करें और शामिल करें

compile 'com.android.support:appcompat-v7:23.1.1'

gradle.app में और api 23 में संकलित संस्करण सेट करें


1

नीचे दिया गया उत्तर एंड्रॉइड डेवलपर वेबसाइट पर फ्रैगमेंट ट्यूटोरियल में होने वाली इस डेप्रिसिएशन चेतावनी से संबंधित है और ऊपर के पदों से संबंधित नहीं हो सकता है।

मैंने ट्यूटोरियल कोड पर इस कोड का उपयोग किया और इसने काम किया।

public void onAttach(Context context){
    super.onAttach(context);

    Activity activity = getActivity();

मैं चिंतित था कि गतिविधि शायद यह बताती है कि दस्तावेज क्या कहते हैं।

getActivity

FragmentActivity getActivity () FragmentActivity लौटें यह टुकड़ा वर्तमान में जुड़ा हुआ है। यदि खंड एक प्रसंग के साथ जुड़ा हुआ है, तो अशक्त हो सकता है।

लेकिन main_activity पर onCreate स्पष्ट रूप से दिखाता है कि टुकड़ा लोड किया गया था और इसलिए इस विधि के बाद, कॉल से गतिविधि को प्राप्त करने से main_activity वर्ग वापस आ जाएगा।

getSupportFragmentManager ()। प्रारंभ करना () .add (R.id.fragment_container, firstFragment) .commit ();

मुझे उम्मीद है कि मैं इसके साथ सही हूं। मैं एक पूर्ण नौसिखिया हूँ।


1

आप शायद उपयोग कर रहे हैं android.support.v4.app.Fragment। इसके लिए onAttachविधि के बजाय , केवल उस टुकड़े getActivity()को प्राप्त करने के लिए उपयोग करें FragmentActivityजिसके साथ टुकड़ा जुड़ा हुआ है। और आप onAttach(Context context)विधि का उपयोग कर सकते हैं ।


0

यह मेरे लिए तब काम आया जब मैंने यूजरडिफाइन्ड इंटरफेस 'टॉपसेंलिस्टनर', इसका ऑब्जेक्ट एक्टीवेन्डर:

  //This method gets called whenever we attach fragment to the activity
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    Activity a=getActivity();
    try {
        if(context instanceof Activity)
           this.activitycommander=(TopSectionListener)a;
    }catch (ClassCastException e){
        throw new ClassCastException(a.toString());}

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