फ्रैगमेंट में Context प्राप्त करना - सही तरीके
एक फ्रैगमेंट Context नहीं है, लेकिन इसके पास कई मान्य स्रोतों के माध्यम से एक तक पहुंच है। गलत स्रोत चुनने से लीक, क्रैश, या गलत थीम/संसाधन होते हैं।
त्वरित संदर्भ तालिका
| स्रोत | उपलब्ध | जीवनचक्र | उपयोग-मामला |
|---|---|---|---|
requireContext() | onAttach के बाद | फ्रैगमेंट से जुड़ा | **डिफ़ॉल्ट विकल्प** — अधिकांश मामलों के लिए सुरक्षित, नॉन-नल |
getContext() | onAttach के बाद | फ्रैगमेंट से जुड़ा | requireContext() के समान लेकिन @Nullable |
requireActivity() | onAttach के बाद | गतिविधि जीवनचक्र | जब विशेष रूप से गतिविधि की आवश्यकता हो (उदाहरण: startActivityForResult) |
getActivity() | onAttach के बाद | गतिविधि जीवनचक्र | नल करने योग्य संस्करण |
getApplicationContext() | कभी भी | प्रक्रिया जीवनचक्र | सिंगलटन, डेटाबेस, लंबे समय तक चलने वाले ऑब्जेक्ट्स (UI नहीं) |
requireView().getContext() | onViewCreated के बाद | व्यू जीवनचक्र | व्यू-विशिष्ट संसाधन (थीम, आयाम) |
सर्वोत्तम अभ्यास
- डिफ़ॉल्ट रूप से
requireContext()का उपयोग करें — यह नल नहीं हो सकता जब फ्रैगमेंट जुड़ा हुआ हो, इरादा स्पष्ट करता है। - onAttach से पहले Context एक्सेस न करें —
onCreate, कंस्ट्रक्टर, या फील्ड इनिशियलाइज़र मेंgetContext()नल लौटाता है। - View-विशिष्ट संसाधनों के लिए (उदाहरण:
TypedArray, थीम विशेषताएं),requireView().getContext()का उपयोग करेंonViewCreatedमें। - लंबे समय तक चलने वाले ऑब्जेक्ट्स (कॉरआउटिन स्कोप, डेटाबेस, रिपॉजिटरी) के लिए
requireActivity().getApplicationContext()पास करें। - Context को फील्ड में स्टोर न करें — यह लीक का कारण बनता है; हर बार प्राप्त करें।
कोड उदाहरण
public class SampleFragment extends Fragment {
// ✅ अच्छा: ऑन-डिमांड, नॉन-नल
private void showToast(String msg) {
Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show();
}
// ✅ अच्छा: View-विशिष्ट संसाधनों के लिए
@Override
public void onViewCreated(@NonNull View view, Bundle saved) {
super.onViewCreated(view, saved);
Context viewContext = requireView().getContext();
int color = ContextCompat.getColor(viewContext, R.color.my_color);
view.findViewById(R.id.someView).setBackgroundColor(color);
}
// ✅ अच्छा: एप्लिकेशन-स्कोप्ड ऑब्जेक्ट्स के लिए
private void initRepository() {
MyRepository repo = new MyRepository(requireActivity().getApplicationContext());
}
// ❌ खराब: फील्ड में स्टोर करना
// private Context savedContext; // लीक!
// ❌ खराब: onCreate में getContext() — नल होगा
@Override
public void onCreate(Bundle saved) {
super.onCreate(saved);
// Context ctx = getContext(); // null!
}
}
आम बग
| लक्षण | कारण | समाधान |
|---|---|---|
| NPE getContext() पर | onAttach से पहले कॉल किया गया | requireContext() का उपयोग करें या onAttach/onViewCreated तक प्रतीक्षा करें |
| लीक की गई गतिविधि | Context को स्टेटिक/सिंगलटन में स्टोर किया गया | एप्लिकेशन कॉन्टेक्स्ट पास करें या WeakReference का उपयोग करें |
| गलत थीम/संसाधन | थीम वाले संसाधनों के लिए एप्लिकेशन कॉन्टेक्स्ट का उपयोग किया गया | requireContext() या requireView().getContext() का उपयोग करें |
मूल उदाहरण की समीक्षा
मूल कोड getActivity() को एक TextView में प्रिंट करता था बिना नल-चेक के, onCreateView में (जहां यह नॉन-नल है लेकिन नाजुक है)। ऊपर दिया गया पैटर्न सुरक्षित, आधुनिक उपयोग दिखाता है।