2013-07-03 4 views
13

मैं एक व्यापक प्रश्न में इस बारी करने के वास्तव में कड़ी मेहनत की कोशिश करेंगे: के रूप में LocationManager और getLastKnownLocation() और सभी के द्वारा निर्धारित कियाएंड्रॉइड संदर्भ बिना किसी गतिविधि के? और अन्य गतिविधि-कम प्रोग्रामिंग?

मैं एक स्ट्रिंग एक Android डिवाइस के शहर का नाम शामिल है कि प्राप्त करने के लिए एक विधि लिख रहा हूँ, कि ।

तब मुझे एहसास हुआ कि मुझे एक और गतिविधि में एक ही चीज़ फिर से करने की ज़रूरत है, तो क्यों न केवल एक पूरी तरह से अलग वर्ग (LocationFinder) बनाना है कि मैं हर जगह डुप्लिकेट कोड लिखने के बजाय अपने प्रोग्राम में उपयोग कर सकता हूं?

लेकिन मैंने उन समस्याओं में भाग लिया है जो मुझे भ्रमित करते हैं। उदाहरण के लिए, यदि मैं इस वर्ग (LocationFinder) को बना देता हूं, तो क्या इसे गतिविधि का विस्तार करना चाहिए, भले ही इसे वास्तव में कभी कल्पना न किया जाए? इस कक्षा में सभी प्रकार के गेटर्स होंगे जैसे getLastKnownCity() या getCurrentCity() और स्ट्रिंग लौटें। मुझे लगता है कि इसे गतिविधि वर्ग का विस्तार नहीं करना पड़ेगा, क्योंकि यह वास्तव में एक गतिविधि नहीं है।

लेकिन तब क्या प्रसंग मैं के लिए प्रयोग करते हैं:

Geocoder geocoder = new Geocoder(Context context, Locale locale) 

?

इससे मुझे लगता है कि यह एक गतिविधि होनी चाहिए। इसलिए मैं गतिविधि बढ़ाया और

@Override 
protected void onCreate(.............. 

साथ निर्माता की जगह है, लेकिन कुछ कारण यह है कि कभी नहीं समाप्त होता है कहा जाता हो रही है, यहां तक ​​कि जब मैं डाल के लिए

String city = new LocationFinder().getLastKnownCity(); 

मेरे LocationFinder के onCreate() की बहुत पहली पंक्ति है

System.out.println("HEY!") 

और यह कभी भी उस तक नहीं पहुंचता है। मुझे android.internal.os.LoggingPrintStream.println() और अन्य सामान पर एक शून्य सूचक मिलता है।

प्लस, गतिविधि कक्षाओं से आने वाले सिस्टम स्थिरांक का एक गुच्छा है। उदाहरण के लिए, मुझे LOCATION_SERVICE पर जाना होगा, जो एक स्ट्रिंग है, जिसे मैं गतिविधि को विस्तारित किए बिना प्राप्त नहीं कर सकता। निश्चित रूप से, मैं धोखा दे सकता हूं और केवल शाब्दिक स्ट्रिंग में डाल सकता हूं, लेकिन यह गलत लगता है।

उत्तर

10

अपनी कक्षा का निर्माण करते समय, आपके पास एक कंस्ट्रक्टर हो सकता है जो एक संदर्भ में लेता है और इसे आपकी कक्षा के भीतर एक स्थानीय संदर्भ ऑब्जेक्ट असाइन करता है।

public class LocationFinder { 
    private Context myContext; 
    private Geocoder geocoder; 

    public LocationFinder(Context context) 
    { 
     myContext = context; 
     geocoder = new Geocoder(myContext); 
    } 

} 

और फिर जब आप इस वर्ग तक पहुँचने का प्रयास, सुनिश्चित करें कि आप इसे पसंद आरंभ करते हैं:

public class TestActivity extends Activity { 
    protected void onCreate(Bundle savedInstanceState) 
    { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 
      LocationFinder lFinder = new LocationFinder(getApplication()); 
    } 
} 

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

LocationFinder lFinder = new LocationFinder(anyView.getApplication()); 
+0

धन्यवाद! बस सोच रहा है, क्या गतिविधि की संदर्भ में गुजरने के बजाय getAplicationContext() का उपयोग करना बुरा होगा, जैसा कि आप अनुशंसा करते हैं? मुझे अभी भी संदर्भों की समझ की कमी है, भले ही मैं उनकी परिभाषा को और अधिक पढ़ता रहता हूं ... मैं सिर्फ यह नहीं देखता कि एक गतिविधि का संदर्भ दूसरे से अलग क्या करता है। – andy

+0

सच है, जब संदर्भ की ऑनस्ट्राय को बुलाया जाता है तो संदर्भ का संदर्भ नष्ट हो जाएगा। – frogmanx

15

संपादित करें: यदि संभव हो, तो frogmanx के उत्तर का उपयोग करें। इसका उपयोग तब किया जाना चाहिए जब उसका उत्तर उपयोग करना संभव न हो। (यानी सिंगलेट्स जिन्हें बल्ले से सीधे संदर्भ की आवश्यकता होती है।)

लगता है जैसे आपको Application और गतिविधि नहीं बढ़ाना चाहिए।

public class MyApplication extends Application { 
    private static MyApplication instance; 

    public MyApplication() { 
     instance = this; 
    } 

    public static MyApplication getInstance() { 
     return instance; 
    } 

तब प्रकट के आवेदन टैग में यह विशेषता जोड़ें:

इस तरह अपने आवेदन कुछ बनाओ

<application android:name=".your.package.MyApplication" ... /> 

सब उसके बाद से MyApplication.getInstance() फोन करके आप एक संदर्भ प्राप्त कर सकते हैं, कहीं भी।

+0

बिल्कुल मेरा प्रश्न नहीं है लेकिन आपके उत्तर ने मेरी मदद की! धन्यवाद –

+2

बहुत बढ़िया +1 बिल्कुल मेरा मामला, सिंगलटन जिसे संदर्भ की आवश्यकता है। मुझे यह खोजने के लिए उम्र ले ली! – Juicy

2
should it extend Activity, even though it is never actually visualized? 

सं Android docs

एक गतिविधि से एक भी है, ध्यान केंद्रित बात उपयोगकर्ता ऐसा कर सकते हैं। लगभग सभी गतिविधियों, उपयोगकर्ता के साथ बातचीत तो गतिविधि वर्ग आप के लिए एक खिड़की है जिसमें आप setContentView (देखें) एक स्क्रीन उपयोगकर्ता के रूप में एक गतिविधि की

Think के साथ अपने यूआई जगह कर सकते हैं बनाने की ख्याल रखता है देखता है।

लेकिन तब क्या प्रसंग मैं जियोकोडर जियोकोडर = नए जियोकोडर (संदर्भ संदर्भ, लोकेल लोकेल)

Activity वर्ग फैली Context के लिए उपयोग करते हैं, के रूप में Application सहित अन्य वर्गों का एक बहुत करते हैं। एक संदर्भ कक्षा से जुड़े संसाधनों तक पहुंच प्रदान करता है जो संदर्भ को बढ़ाता है।

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

यदि आप कभी भी गतिविधि को विस्तारित करने के बाहर एक गतिविधि संदर्भ पास करते हैं, तो सुनिश्चित करें कि संदर्भ का दायरा और जीवन चक्र विस्तार गतिविधि से कम या बराबर है अन्यथा यदि गतिविधि है तो आप बड़ी मात्रा में स्मृति को रिसाव करेंगे जब कचरा कलेक्टर संदर्भ को संदर्भित करता है तब से कचरा कलेक्टर स्मृति को मुक्त नहीं कर सकता है।

यदि आप जियोकोडर के लिए निर्माता को देखते हैं तो आप देखेंगे कि यह एक संदर्भ के रूप में एक संदर्भ के रूप में संदर्भ लेता है, जैसा कि आप जानते हैं। वहाँ क्यों प्रसंग वर्णन में की जरूरत है के रूप में एक सुराग है:

 Geocoder(Context context, Locale locale) 
Constructs a Geocoder whose responses will be localized for the given Locale. [1]: 

कारण संदर्भ की आवश्यकता है मंच स्थानों और मौजूदा प्रणाली स्थान के बारे में सिस्टम जानकारी तक पहुँचने के लिए है।

तो अपने उदाहरण में, आप बस ऐप्लिकेशन संदर्भ निर्माता है, जो आप getApplicationContext() साथ

उदाहरण के लिए, मैं LOCATION_SERVICE है, जो एक स्ट्रिंग है पर प्राप्त करने की आवश्यकता के लिए एक संदर्भ प्राप्त कर सकते हैं करने के लिए, दे सकते हैं जो मुझे गतिविधि

विस्तारित किए बिना प्राप्त नहीं कर सकता है, आप इसे एप्लिकेशन संदर्भ से प्राप्त कर सकते हैं।

+0

धन्यवाद! बस सोच रहा है, क्या Geocoder (संदर्भ संदर्भ ...) में मेरे संदर्भ के रूप में getAplicationContext() का उपयोग करना मूर्ख नहीं होगा? अन्य ने इस नई कक्षा को तत्काल करने वाली गतिविधि से संदर्भ में गुजरने की सिफारिश की है, और मुझे यकीन नहीं है कि सबसे अच्छा तरीका कौन सा है। एक बार फिर धन्यवाद। – andy

+0

कुंजी है, क्या आपको 'जिओकोडर' से अपनी 'गतिविधि' तक पहुंच की आवश्यकता है? अच्छा डिजाइन कहता है नहीं। यदि आपको अपनी 'गतिविधि' में मूल्यों को पास करने की आवश्यकता है तो श्रोता का उपयोग करें। कस्टम कॉलबैक करने के लिए आप हमेशा अपना 'इंटरफेस' परिभाषित कर सकते हैं, उदा। 'TextView' को अपडेट करने के लिए। आवेदन संदर्भ का उपयोग करने में कुछ भी "बुरा" नहीं है। यह एक सिंगलटन होने की गारंटी है और आवेदन जीवन चक्र के लिए लगातार मौजूद है, इसलिए सवाल पूछा जाता है कि "मुझे गतिविधि संदर्भ की आवश्यकता क्यों है"? – Simon

संबंधित मुद्दे