हां जावा में कॉलबैक की अवधारणा भी बहुत अधिक मौजूद है। जावा में आप इस तरह एक कॉलबैक को परिभाषित:
public interface TaskListener {
public void onFinished(String result);
}
एक अक्सर घोंसला AsyncTask
इस तरह अंदर श्रोता परिभाषाएँ इस तरह होगा:
public class ExampleTask extends AsyncTask<Void, Void, String> {
public interface TaskListener {
public void onFinished(String result);
}
...
}
और AsyncTask
में कॉलबैक का एक पूरा कार्यान्वयन लगेगा इस तरह:
public class ExampleTask extends AsyncTask<Void, Void, String> {
public interface TaskListener {
public void onFinished(String result);
}
// This is the reference to the associated listener
private final TaskListener taskListener;
public ExampleTask(TaskListener listener) {
// The listener reference is passed in through the constructor
this.taskListener = listener;
}
@Override
protected String doInBackground(Void... params) {
return doSomething();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// In onPostExecute we check if the listener is valid
if(this.taskListener != null) {
// And if it is we call the callback function on it.
this.taskListener.onFinished(result);
}
}
}
onPostExecute()
जैसे ही पृष्ठभूमि कार्य पूर्ण होने के रूप में कहा जाता है। आप इस तरह पूरी बात का उपयोग कर सकते हैं:
ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
@Override
public void onFinished(String result) {
// Do Something after the task has finished
}
});
task.execute();
या आप इस तरह पूरी तरह से अलग TaskListener
परिभाषित कर सकते हैं:
ExampleTask.TaskListener listener = new ExampleTask.TaskListener() {
@Override
public void onFinished(String result) {
// Do Something after the task has finished
}
};
ExampleTask task = new ExampleTask(listener);
task.execute();
या आप इस तरह TaskListener
उपवर्ग कर सकते हैं:
public class ExampleTaskListener implements TaskListener {
@Override
public void onFinished(String result) {
}
}
और फिर इसे इस तरह उपयोग करें:
ExampleTask task = new ExampleTask(new ExampleTaskListener());
task.execute();
आप निश्चित रूप से सिर्फ AsyncTask
की onPostExecute()
विधि ओवरराइड कर सकते हैं, लेकिन यह सिफारिश की और ज्यादातर मामलों में नहीं है वास्तव में बहुत बुरा व्यवहार। उदाहरण के लिए आप ऐसा कर सकता है:
ExampleTask task = new ExampleTask() {
@Override
public void onPostExecute(String result) {
super.onPostExecute(result);
// Your code goes here
}
};
यह एक अलग श्रोता इंटरफेस के साथ ऊपर कार्यान्वयन के रूप में बस के रूप में अच्छी तरह से काम करेगा, लेकिन इसके साथ कुछ समस्याएं हैं:
सबसे पहले आप वास्तव में तोड़ सकते हैं ExampleTask
सभी एक साथ। यह सब ऊपर super.onPostExecute()
कॉल पर आता है। यदि आप डेवलपर के रूप में ऊपर की तरह onPostExecute()
ओवरराइड करते हैं और सुपर कॉल को शामिल करना भूल जाते हैं या में मूल onPostExecute()
विधि को किसी भी कारण से हटा दें तो उसे अब और नहीं कहा जाएगा। उदाहरण के लिए TaskListener
के साथ पूरे श्रोता कार्यान्वयन अचानक काम नहीं करेगा क्योंकि कॉलबैक पर कॉल onPostExecute()
में लागू किया गया है। आप TaskListener
को अनजाने में या अनजाने में ExampleTask
की स्थिति को प्रभावित करके कई अन्य तरीकों से तोड़ सकते हैं, इसलिए यह अब और काम नहीं करेगा।
यदि आप इस तरह की विधि को ओवरराइड करते समय वास्तव में क्या हो रहा है, तो यह और अधिक स्पष्ट हो जाता है कि क्या हो रहा है।onPostExecute()
ओवरराइड करके आप ExampleTask
का नया उप-वर्ग बना रहे हैं। ऐसा करने के समान ही यह होगा:
public class AnotherExampleTask extends ExampleTask {
@Override
public void onPostExecute(String result) {
super.onPostExecute(result);
// Your code goes here
}
}
यह सब सिर्फ अज्ञात वर्ग नामक भाषा सुविधा के पीछे छिपा हुआ है। इस तरह की एक विधि को अचानक ओवरराइड करना इतना साफ और त्वरित नहीं लगता है?
संक्षेप में:
- इस तरह की एक विधि वास्तव में एक नया उपवर्ग बनाता ओवरराइड करना। आप केवल कॉलबैक नहीं जोड़ रहे हैं, आप संशोधित कर रहे हैं कि यह वर्ग कैसे काम करता है और अनजाने में ओह इतनी सारी चीज़ें तोड़ सकता है।
- इस तरह की त्रुटियों को डिबग करना ** में केवल दर्द से कहीं अधिक हो सकता है। क्योंकि अचानक
ExampleTask
Exceptions
फेंक सकता है या किसी भी स्पष्ट कारण के लिए अब और काम नहीं कर सकता है, क्योंकि आपने वास्तव में कभी भी अपना कोड संशोधित नहीं किया है।
- प्रत्येक वर्ग को उन स्थानों पर श्रोता कार्यान्वयन प्रदान करना पड़ता है जहां यह उचित और इरादा है। निश्चित रूप से आप उन्हें बाद में
onPostExecute()
ओवरराइड करके जोड़ सकते हैं लेकिन यह हमेशा बहुत खतरनाक होता है। यहां तक कि उनकी 13k प्रतिष्ठा के साथ @flup भी super.onPostExecute()
को अपने उत्तर में कॉल करने के लिए भूल गया है, कल्पना करें कि कुछ अन्य अनुभवी डेवलपर क्या कर सकते हैं!
- थोड़ा अबास्ट्रक्शन किसी को चोट नहीं पहुंचाता है। विशिष्ट श्रोताओं को लिखना थोड़ा और कोड हो सकता है, लेकिन यह एक बेहतर समाधान है। कोड क्लीनर, अधिक पठनीय और बहुत अधिक रखरखाव योग्य होगा।
onPostExecute()
ओवरराइड करने जैसे शॉर्टकट का उपयोग करना अनिवार्य रूप से थोड़ी सी सुविधा के लिए कोड गुणवत्ता को बलिदान देता है। यह कभी भी एक अच्छा विचार नहीं है कि एक इच्छा लंबे समय तक समस्याओं का कारण बन जाएगी।
यह नहीं है कि आप इसे कैसे करते हैं^_ ^। आप एसिंक कार्य का उपयोग करके पृष्ठभूमि थ्रेड बनाते हैं और आपका कोड उर्फ httprequest doInBackground() विधि में जाता है और आप इसके लिए रिटर्नटाइप परिभाषित करते हैं। पृष्ठभूमि ऑपरेशन को समाप्त करने के बाद पोस्टस्टेक्स्यूट() को कॉल किया जाता है जिसमें आप प्रतिक्रिया को संभालने के लिए कोड लिखते हैं क्योंकि अब आप दृश्यों को अपडेट कर सकते हैं और सभी। एक प्रगतिशील विधि है जो परिभाषित प्रगति पर पहुंचने पर ट्रिगर होती है। मुझे थोड़ी देर में प्रलेखन लिंक मिलेगा – Rico
http://developer.android.com/reference/android/os/AsyncTask.html – Rico