Android - Anything similar to the iPhone SDK Delegate Callbacks?
Asked Answered
G

6

27

I just switched over from iPhone to Android and am looking for something similar to where in the iPhone SDK, when a class finishes a certain task, it calls delegate methods in objects set as it's delegates.

I don't need too many details. I went through the docs and didn't find anything (the closest I got was "broadcast intents" which seem more like iOS notifications).

Even if someone can point me to the correct documentation, it would be great.

Thanks!

Girovard answered 23/9, 2010 at 19:14 Comment(2)
The iphone paradagm is rather different from the Android one. If you explain what you are trying to accomplish with this, someone might be able to help you find the Android way.Electrolyze
Well I'm using a singleton object that wraps the Android MediaPlayer object and has it's own set of methods to play a specific track, pause, play, etc. What I want is that when the track pauses or starts, it should "send a notification" to classes that reference the singleton object to update the play button's image to either a pause icon or a play icon. I hope this made things clear?Girovard
G
17

Never mind... found the answer here :)

http://www.javaworld.com/javaworld/javatips/jw-javatip10.html


Pasting from the article so as to preserve it:

Developers conversant in the event-driven programming model of MS-Windows and the X Window System are accustomed to passing function pointers that are invoked (that is, "called back") when something happens. Java's object-oriented model does not currently support method pointers, and thus seems to preclude using this comfortable mechanism. But all is not lost!

Java's support of interfaces provides a mechanism by which we can get the equivalent of callbacks. The trick is to define a simple interface that declares the method we wish to be invoked.

For example, suppose we want to be notified when an event happens. We can define an interface:

public interface InterestingEvent
{
    // This is just a regular method so it can return something or
    // take arguments if you like.
    public void interestingEvent ();
}

This gives us a grip on any objects of classes that implement the interface. So, we need not concern ourselves with any other extraneous type information. This is much nicer than hacking trampoline C functions that use the data field of widgets to hold an object pointer when using C++ code with Motif.

The class that will signal the event needs to expect objects that implement the InterestingEvent interface and then invoke the interestingEvent() method as appropriate.

public class EventNotifier
{
    private InterestingEvent ie;
    private boolean somethingHappened; 
    public EventNotifier (InterestingEvent event)
    {
    // Save the event object for later use.
    ie = event; 
    // Nothing to report yet.
    somethingHappened = false;
    } 
    //...  
    public void doWork ()
    {
    // Check the predicate, which is set elsewhere.
    if (somethingHappened)
        {
        // Signal the even by invoking the interface's method.
        ie.interestingEvent ();
        }
    //...
    } 
    // ...
}

In that example, I used the somethingHappened predicate to track whether or not the event should be triggered. In many instances, the very fact that the method was called is enough to warrant signaling the interestingEvent().

The code that wishes to receive the event notification must implement the InterestingEvent interface and just pass a reference to itself to the event notifier.

public class CallMe implements InterestingEvent
{
    private EventNotifier en; 
    public CallMe ()
    {
    // Create the event notifier and pass ourself to it.
    en = new EventNotifier (this);
    } 
    // Define the actual handler for the event.
    public void interestingEvent ()
    {
    // Wow!  Something really interesting must have occurred!
    // Do something...
    } 
    //...
}

That's all there is to it. I hope use this simple Java idiom will make your transition to Java a bit less jittery.

Girovard answered 24/9, 2010 at 16:36 Comment(2)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.Joettajoette
this example doesn't explain how to set reference of activity that implements the interfaceAuvil
L
6

The pendant for kotlin.

Define your interface: In my example I scan a credit card with an external library.

interface ScanIOInterface {
     fun onScannedCreditCard(creditCard: CreditCard)
}

Create a class where you can register your Activity / Fragment.

class ScanIOScanner {
  var scannerInterface: ScanIOInterface? = null

  fun startScanningCreditCard() {
      val creditCard = Library.whichScanCreditCard() //returns CreditCard model
      scannerInterface?.onScannedCreditCard(creditCard)
  }
}

Implement the interface in your Activity / Fragment.

class YourClassActivity extends AppCompatActivity, ScanIOInterface {
    //called when credit card was scanned
    override fun onScannedCreditCard(creditCard: CreditCard) {
        //do stuff with the credit card information
    }

    //call scanIOScanner to register your interface
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
       super.onViewCreated(view, savedInstanceState)

       val scanIOScanner = ScanIOScanner()
       scanIOScanner.scannerInterface = this
    }
} 

CreditCard is a model and could be define however you like. In my case it includes brand, digits, expiry date ...

After that you can call scanIOScanner.startScanningCreditCard() wherever you like.

Louvenialouver answered 21/1, 2019 at 16:32 Comment(0)
N
5

The main content of this video tutorial is to show how to use interfaces to delegate methods / data exchange between different Fragments and activities, but it is great example to learn how delegate pattern can be implemented in Java for Android.

enter image description here

Natator answered 6/5, 2014 at 1:35 Comment(0)
A
1

Java callback is not the same thing like ios delegate, in ios you can use a callback almost the same way like in Android. In Android there is startActivityForResult that can help you to implement the tasks for what ios delegate is used.

Amarillo answered 5/11, 2012 at 11:49 Comment(1)
Bam thanks for the response but this will only prove useful if the class launching the activity needs to know if something happens, and only when the user backs out of the launched activity. The solution I posted allows you to set a class as the 'delegate' of another without them having any sort of relation.Girovard
V
1

I believe ListAdapter is a example of delegation pattern in Android.

Verticillate answered 11/4, 2014 at 15:11 Comment(3)
Hi David, I half-agree. I would say it's more similar to DataSources in iOS :) Thanks for the input!Girovard
@Girovard Actually, DataSource is a special type of delegates.Verticillate
David, yes that's correct, and I'm aware, but what I was referring to is the contextual similarity. A ListAdapter is to a DataSource, what an OnItemClickListener on a List is to a Delegate.Girovard
L
0

Kotlin's official Delegation pattern:

interface Base {
    fun print()
}

class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}

class Derived(b: Base) : Base by b 

fun main() {
    val b = BaseImpl(10)
    Derived(b).print()
}

See: https://kotlinlang.org/docs/delegation.html

Limbic answered 19/3, 2021 at 1:59 Comment(1)
For what it's worth, I don't think Kotlin's Delegation pattern is equivalent to delgates in iOS/Cocoa. developer.apple.com/documentation/swift/… developer.apple.com/library/archive/documentation/General/…Miceli

© 2022 - 2024 — McMap. All rights reserved.