एंड्रॉइड में कॉलबैक कैसे परिभाषित करें?


152

सबसे हालिया Google IO के दौरान, क्लाइंट क्लाइंट एप्लिकेशन को लागू करने के बारे में एक प्रस्तुति थी। दुर्भाग्य से, यह केवल उच्च स्तरीय चर्चा थी जिसके कार्यान्वयन का कोई स्रोत कोड नहीं था।

इस चित्र में, वापसी पथ पर अन्य विधियों के लिए विभिन्न कॉलबैक हैं।

Google io प्रस्तुति स्लाइड

मैं कैसे घोषित करता हूं कि ये तरीके क्या हैं?

मैं एक कॉलबैक के विचार को समझता हूं - कोड का एक टुकड़ा जो किसी निश्चित घटना के बाद कॉल किया जाता है, लेकिन मुझे नहीं पता कि इसे कैसे लागू किया जाए। मैंने अभी तक कॉलबैक लागू करने का एकमात्र तरीका विभिन्न तरीकों (उदाहरण के लिए onActivityResult) को ओवरराइड किया है।

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


3
बिल्कुल वही जो आपको चाहिए। मैं एक ही चीज़ की तलाश में था और इस पर आया: javaworld.com/javaworld/javatips/jw-javatip10.html
सिड

जवाबों:


218

कई मामलों में, आपके पास एक इंटरफ़ेस है और एक ऑब्जेक्ट के साथ गुजरता है जो इसे लागू करता है। उदाहरण के लिए संवाद में OnClickListener है।

एक यादृच्छिक उदाहरण के रूप में:

// The callback interface
interface MyCallback {
    void callbackCall();
}

// The class that takes the callback
class Worker {
   MyCallback callback;

   void onEvent() {
      callback.callbackCall();
   }
}

// Option 1:

class Callback implements MyCallback {
   void callbackCall() {
      // callback code goes here
   }
}

worker.callback = new Callback();

// Option 2:

worker.callback = new MyCallback() {

   void callbackCall() {
      // callback code goes here
   }
};

मैंने शायद विकल्प 2 में वाक्य रचना को गड़बड़ कर दिया है। यह जल्दी है।


5
इस तकनीक पर एक पकड़ पाने के लिए एक अच्छा उदाहरण है कि एक टुकड़ा को किसी अन्य टुकड़े के साथ कैसे साझा करना चाहिए, यह साझा किया जाता है गतिविधि: developer.android.com/guide/compenders/…
जॉर्डन

मैं एक नई गतिविधि में MyCallback इंटरफ़ेस को "लागू" करने का प्रयास करता हूं जो सफल नहीं है और सिस्टम को इसके लिए स्रोत पथ को संपादित करने की आवश्यकता है। तो मैं एक पुरानी गतिविधि से "कॉलबैक" को एक नई गतिविधि में कैसे ले जाऊंगा?
एंटोनी मूरियन

3
यह कहता है कि कार्यकर्ता वर्ग में कॉलबैक चर मेरे लिए अशक्त है
iYonatan 15

कोई कोटलिन के बराबर दे सकता है?
Tooniis

52

जब मेरे विचार में कुछ होता है, तो मैं एक ऐसी घटना को आग लगा देता हूं, जिसे मेरी गतिविधि सुन रही है:

// घोषित (कस्टम) देखें

    private OnScoreSavedListener onScoreSavedListener;
    public interface OnScoreSavedListener {
        public void onScoreSaved();
    }
    // ALLOWS YOU TO SET LISTENER && INVOKE THE OVERIDING METHOD 
    // FROM WITHIN ACTIVITY
    public void setOnScoreSavedListener(OnScoreSavedListener listener) {
        onScoreSavedListener = listener;
    }

// गतिविधि में शामिल किया गया

    MyCustomView slider = (MyCustomView) view.findViewById(R.id.slider)
    slider.setOnScoreSavedListener(new OnScoreSavedListener() {
        @Override
        public void onScoreSaved() {
            Log.v("","EVENT FIRED");
        }
    });

यदि आप टुकड़ों के बीच संचार (कॉलबैक) के बारे में अधिक जानना चाहते हैं, तो यहां देखें: http://developer.android.com/guide/computers/fragments.html#CommunicatingWithActivity


1
वह #CommunicatingWithActivity ट्यूटोरियल बहुत बढ़िया था। अंत में समझा गया कि कई परीक्षणों के बाद कॉलबैक का उपयोग कैसे किया जाए।
मोएजेस जिमेनेज

बहुत बढ़िया जवाब। धन्यवाद!
योनतन 18

सरल और समझने में आसान। धन्यवाद!
ग्लेन जे। श्वेर्कक

38

जब आप किसी मौजूदा का उपयोग कर सकते हैं, तो एक नए इंटरफ़ेस को परिभाषित करने की आवश्यकता नहीं है android.os.Handler.Callback:। कॉलबैक के ऑब्जेक्ट को पास करें, और कॉलबैक को लागू करें handleMessage(Message msg)


लेकिन इसे कैसे करें?
मजूरगेटर्टन

26

इंटरफ़ेस का उपयोग करके कॉलबैक विधि को लागू करने के लिए उदाहरण।

इंटरफ़ेस को परिभाषित करें, NewInterface.java

पैकेज javaapplication1;

public interface NewInterface {
    void callback();
}

एक नया वर्ग बनाएं, NewClass.java । यह मुख्य वर्ग में कॉलबैक पद्धति को कॉल करेगा।

package javaapplication1;

public class NewClass {

    private NewInterface mainClass;

    public NewClass(NewInterface mClass){
        mainClass = mClass;
    }

    public void calledFromMain(){
        //Do somthing...

        //call back main
        mainClass.callback();
    }
}

इंटरफ़ेस NewInterface - कॉलबैक () पद्धति को लागू करने के लिए मुख्य वर्ग, JavaApplication1.java। यह न्यूक्लास ऑब्जेक्ट बनाएगा और कॉल करेगा। फिर, न्यूक्लास ऑब्जेक्ट कॉलबैक होगा जो कॉलबैक () विधि है।

package javaapplication1;
public class JavaApplication1 implements NewInterface{

    NewClass newClass;

    public static void main(String[] args) {

        System.out.println("test...");

        JavaApplication1 myApplication = new JavaApplication1();
        myApplication.doSomething();

    }

    private void doSomething(){
        newClass = new NewClass(this);
        newClass.calledFromMain();
    }

    @Override
    public void callback() {
        System.out.println("callback");
    }

}

1
अब तक हम कॉलबैक के लिए इंटरफेस का उपयोग कर रहे थे, लेकिन अब स्क्वायर ने ईवेंट-बस ओटो के रूप में एक काम विकसित किया है। यह वास्तव में तेज़ और सहायक है।
अमोल पाटिल

20

ड्रैगन के जवाब पर थोड़ा स्पष्ट करने के लिए (क्योंकि मुझे यह पता लगाने में कुछ समय लगा कि मुझे क्या करना है Handler.Callback):

Handlerवर्तमान या किसी अन्य थ्रेड में कॉलबैक निष्पादित करने के लिए उपयोग किया जा सकता है, इसे पास करके MessageMessageरखती डेटा कॉलबैक से इस्तेमाल किया जा रहा। एक Handler.Callbackके निर्माता को पारित किया जा सकता Handlerआदेश सीधे हैंडलर विस्तार से बचने के लिए। इस प्रकार, वर्तमान थ्रेड से कॉलबैक के माध्यम से कुछ कोड निष्पादित करने के लिए:

Message message = new Message();
<set data to be passed to callback - eg message.obj, message.arg1 etc - here>

Callback callback = new Callback() {
    public boolean handleMessage(Message msg) {
        <code to be executed during callback>
    }
};

Handler handler = new Handler(callback);
handler.sendMessage(message);

संपादित करें: बस एहसास हुआ कि एक ही परिणाम प्राप्त करने का एक बेहतर तरीका है (कॉलबैक निष्पादित करने के लिए ठीक से माइनस नियंत्रण):

post(new Runnable() {
    @Override
    public void run() {
        <code to be executed during callback>
    }
});

1
आपकी Runnable पोस्ट हैंडल मेसेजेज मेथड के अंदर है?
इगोरगानपोलस्की

सर्वश्रेष्ठ उत्तर के लिए +1। मुझे Callbackसंस्करण बेहतर पसंद है क्योंकि आपके पास आवश्यक रूप Runnable.run()से उस समय आपके द्वारा आवश्यक डेटा तक पहुंच नहीं हो सकती है
किर्बी

नोट: "जब संदेश का निर्माता सार्वजनिक होता है, तो इनमें से किसी एक को प्राप्त करने का सबसे अच्छा तरीका Message.obtain () या Handler.obtainMessage () विधियों में से एक है, जो उन्हें पुनर्नवीनीकरण वस्तुओं के पूल से खींच लेगा।" - यहां से
jk7

10

आप LocalBroadcastइस उद्देश्य के लिए भी उपयोग कर सकते हैं । यहाँ एक त्वरित क्विड है

एक प्रसारण रिसीवर बनाएँ:

   LocalBroadcastManager.getInstance(this).registerReceiver(
            mMessageReceiver, new IntentFilter("speedExceeded"));

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Double currentSpeed = intent.getDoubleExtra("currentSpeed", 20);
        Double currentLatitude = intent.getDoubleExtra("latitude", 0);
        Double currentLongitude = intent.getDoubleExtra("longitude", 0);
        //  ... react to local broadcast message
    }

यह आप इसे कैसे ट्रिगर कर सकते हैं

Intent intent = new Intent("speedExceeded");
intent.putExtra("currentSpeed", currentSpeed);
intent.putExtra("latitude", latitude);
intent.putExtra("longitude", longitude);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

ऑन-प्रेज में अपंजीकृत रिसीवर:

protected void onPause() {
  super.onPause();
  LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.