2009-12-16 11 views
19

तो मैं AsyncTask क्लास के साथ एंड्रॉइड का उपयोग करके अपना पहला बहु थ्रेडेड एप्लिकेशन काम कर रहा हूं। मैं इसे दूसरे थ्रेड में एक जियोकोडर से आग लगाने के लिए उपयोग करने की कोशिश कर रहा हूं, फिर यूपी को ऑनपोस्टएक्सक्यूट के साथ अपडेट करें, लेकिन मैं उचित संदर्भ के साथ किसी समस्या में चल रहा हूं।AsyncTask और Contexts

मैं मुख्य धागे पर संदर्भों का उपयोग करके अपना रास्ता घुमाता हूं, लेकिन मुझे बिल्कुल यकीन नहीं है कि संदर्भ क्या है या पृष्ठभूमि धागे पर इसका उपयोग कैसे किया जाए, और मुझे इस पर कोई अच्छा उदाहरण नहीं मिला है। कोई मदद?

public class GeoCode extends AsyncTask<GeoThread, Void, GeoThread> { 
    @Override 
    protected GeoThread doInBackground(GeoThread... i) { 
    List<Address> addresses = null; 
    Geocoder geoCode = null; 
    geoCode = new Geocoder(null); //Expects at minimum Geocoder(Context context); 
    addresses = geoCode.getFromLocation(GoldenHour.lat, GoldenHour.lng, 1); 
    } 
} 

यह अनुचित प्रसंग की वजह से, वहाँ छठे लाइन में नाकाम रहने रहता है: यहाँ मैं क्या कर रहा हूँ का एक अंश है।

उत्तर

2

मैंने कुछ और शोध किया, और किसी ने धागे को पास करने का सुझाव दिया (यकीन नहीं कि मैंने ऐसा क्यों नहीं सोचा था)। मैंने इसे एक तर्क के माध्यम से जियोकोडर थ्रेड में पास कर दिया, और इसी तरह, यह काम किया।

+4

कृपया आप आप क्या किया का एक उदाहरण पोस्ट और इस सवाल का सही जवाब को अपडेट कर सकता है? –

+0

@ यूजीन वैन डेर मेर्वे मेरा जवाब देखें, मुझे लगता है कि यह एक उदाहरण है कि वह क्या कर रहा था। –

4

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

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

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

1

एसिंक टास्क से यूआई को अपडेट करने में समस्या यह है कि आपको वर्तमान गतिविधि संदर्भ की आवश्यकता है। लेकिन संदर्भ हर उन्मुखीकरण परिवर्तन के लिए नष्ट हो गया है और फिर से बनाया गया है। कोड का निम्न भाग मेरे लिए काम करता Android AsyncTask context behavior

18

@Eugene वान डर मर्व

:

यहाँ अपने प्रश्न का एक अच्छा जवाब है) ->

public class ApplicationLauncher extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.applicationlauncher); 

    LoadApplication loadApplication = new LoadApplication(this); 
    loadApplication.execute(null); 
} 

private class LoadApplication extends AsyncTask { 

    Context context; 
    ProgressDialog waitSpinner; 
    ConfigurationContainer configuration = ConfigurationContainer.getInstance(); 

    public LoadApplication(Context context) { 
     this.context = context; 
     waitSpinner = new ProgressDialog(this.context); 
    } 

    @Override 
    protected Object doInBackground(Object... args) { 
     publishProgress(null); 
     //Parsing some stuff - not relevant 
     configuration.initialize(context); 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(Object... values) { 
     super.onProgressUpdate(values); 
     // Only purpose of this method is to show our wait spinner, we dont 
     // (and can't) show detailed progress updates 
     waitSpinner = ProgressDialog.show(context, "Please Wait ...", "Initializing the application ...", true); 
    } 

    @Override 
    protected void onPostExecute(Object result) { 
     super.onPostExecute(result); 
     waitSpinner.cancel(); 
    } 
} 
} 

चीयर्स,

तैयार 4Android

+0

धन्यवाद, एक आकर्षण की तरह काम करता है! – agentcurry

+27

इस कोड में एक संदर्भ रिसाव है। आप गतिविधि को AsyncTask में संदर्भ के रूप में सहेज रहे हैं, जो ठीक है, सिवाय इसके कि जब उपयोगकर्ता डिवाइस को घुमाता है, जो गतिविधि को पुन: उत्पन्न करता है। आपकी गतिविधि की पुरानी प्रतिलिपि के संदर्भ में AsyncTask चल रहा है, और अब आपके पास स्मृति में गतिविधि की दो प्रतियां हैं। –

+0

@ क्रिस्टोफरपेरी: AsyncTask में संदर्भ को कमजोर के रूप में संदर्भ को रिसाव को हल करेगा?या उपरोक्त समाधान को सुरक्षित रूप से ट्विक करने का कोई बेहतर तरीका है? – gcl1

0

यदि आपके जैसा नहीं दिखता है पैराम का उपयोग कर रहे हैं। आप Conetxt में पास करने के लिए इसका उपयोग कर सकते हैं।

public class GeoCode extends AsyncTask<Context, Void, GeoThread> { 
    @Override 
    protected GeoThread doInBackground(Context... params) { 
    List<Address> addresses = null; 
    Geocoder geoCode = null; 
    geoCode = new Geocoder(params[0]); //Expects at minimum Geocoder(Context context); 
    addresses = geoCode.getFromLocation(GoldenHour.lat, GoldenHour.lng, 1); 
    } 
} 
फिर अपनी गतिविधि के भीतर से

:

GeoCode myGeoCode = new GeoCode(); 
myGeoCode.execute(this); 
संबंधित मुद्दे