Huzo
Huzo

Reputation: 1692

How or why do listener interfaces work? And do interfaces have any other use rather than being a listener?

Whenever we want to create a listener, we implement a listener interface. For example, lets implement SensorEventListener.

Now we have to override the methods of this listener interface.

public void onSensorChanged(SensorEvent event);

and

public void onAccuracyChanged(Sensor sensor, int accuracy);

What I don't understand is:

  1. Why and how these methods work when I automatically use them?
  2. Why does onAccuracyChanged method gets called when the accuracy changes?
  3. After all, onAccuracyChanged is just an empty method that we override because our formula (or the interface we implement) requires us to do so. If it is something magical caused by the lower levels
  4. When and why would someone actually use an interface in his/her self-project regardless of android?

Upvotes: 1

Views: 2607

Answers (4)

Gratien Asimbahwe
Gratien Asimbahwe

Reputation: 1614

In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information.(Wikipedia)

You may wish to respond to some events either system events or user events. But for that you need to know when the event you wish to capture occurs and also what must be done at that time.

And for that you open a confidential EAR to listen to events. But that will not be sufficient since you need to be notified too so that you can reply according to the event. You set callbacks that will notify when an event occur. Those empty body methods we create inside an interface.

A Listener is that interface that hears and notify back through callbacks.

So how can all that be used? And how all these do interact?

  • First create an interface with empty bodies methods that you intend to call when an event occurs:
public interface MyListener{

      void actionOneHappens(Object o);
      void actionTwo();
      void actionThree();

}
  • Create a class that handles something, for example counts:
public class MyCounter{
//create a member of type MyListener if you intend to exchange infos

private MyListener myListener;

//let's create a setter for our listener
public void setMyListener(MyListener listener)
{
this.myListener=listener;
}

  MyCounter(){

  }
//this method will help us count
public void startCounting()
{
  new CountDownTimer(10000,1000)
       {

           @Override
           public void onTick(long millisUntilFinished) {

            //I want to notify at third second after counter launched

            if(millisUntilFinished/1000==3)
            {
              // I notify if true :
              //as someone can forget to set the listener let's test if it's not //null
              if(myListener!=null){
                 myListener.actionThree();
              }


            }

           }

           @Override
           public void onFinish() {

           }
       }.start();
}




}
  • You can then create an object of type MyCounter and know when it's at three:

MyCounter myCounter=new MyCounter();

myCounter.setMyListener(new MyListener()
{
//then override methods here
  @override
  void actionOneHappens(Object o){
  }
  @override
  void actionTwo()
  {}

  @override
  void actionThree()
  {
   //Add you code here
   Toast.makeText(getApplicationContext(),"I'm at 3",Toast.LENGTH_LONG).show()
   }



});

//start your counter
myCounter.startCounting();

And it's done!! That's how we proceed.

Upvotes: 1

Themelis
Themelis

Reputation: 4245

Here is a suitable answer. Allow me to give you an example about listeners.

Listeners:

Suppose there is a class that fetches data in the background, the Worker, and another class that is interested in that data, the InterestedClass.

public class Worker extends Thread{
  interface DataFetchedListener{
    void onDataFetched(String data);
  }

  private DataFetchedListener listener;

  @Override
  public void run(){
   String data = fetchData();
   // Data fetched inform your listener so he can take action
   listener.onDataFetched(data);
  }

  public void setDataFetchedListener(DataFetchedListener listener){
   this.listener = listener;
  }

  private String fetchData(){
    // returns the fetched data after some operations
    return "Data";
  }
}


public class InterestedClass implements Worker.DatafetchedListener{

 @Override
 public void onDataFetched(String data){
  doSomethingWith(data);
 }

 private doSomethingWith(String data){
  // just print it in the console
  System.out.println("Data fetched is -> " + data);
 }

}

The Worker does not care which class will manipulate its data, as long as that class follows the contract of DataFetchedListener.

Equally this means that any class is able to do something with the data (InterestedClass just prints it in the console) but Worker does not need to know which class is that, just that it implements its interface.

The main could go like this...

public class Application{
  public static void main(String[] args){
   InterestedClass interested = new InterestedClass();
   Worker worker = new Worker();
   worker.setDataFetchedListener(intereseted);
   worker.start(); // Starts Worker's thread
  }
} 

When the Worker will fetch the data then it will notify its listener (currently the interested object) and the listener will act accordingly (interested will print the data to the console).

Upvotes: 2

hadi.mansouri
hadi.mansouri

Reputation: 828

There is no magic thing. Generally, the event-listener mechanism is as follow:

For some entities, there is the possibility to listen to some events on that entity (let name this entity as event generator). So some way should exist for other entities to listen to these changes (let name these entities as listeners). Now a listener registers itself as a listener of event generator. When an event occurs on the event generator, it calls the related method of registered listeners.

As a simple example assume a button. The button may generate an event for some actions such as click. Now if a listener wants to aware when the button is clicked, it should register itself as a listener of that button. On the other hand, the button should provide a unified way of registering the listeners. This unified way is the interface. Each entity which implements the interface could register itself as a listener for click on that button:

1- Listener implements the interface 2- Listener registers itself as a listener of button (Event Generator) 3- Event Generator calls the appropriate method of all registered listeners (this method is a method of the interface).

For your case, android provides a manager which you could register a listener on some sensors by it: android.hardware.SensorManager.registerListener(). All things occurs here (which is not magic!). When you register an entity (which implemented the related interface, SensorEventListener) as a sensor listener, changes in that sensor will cause to call methods of the listener).

Upvotes: 1

Mehdi
Mehdi

Reputation: 3763

Interfaces have no implementation and for using them we have two options:

  1. A class that implement them
  2. An anonymous class

And consider this code:

interface TestInterface {
    void doSomething();
}

class TestClass{
    private TestInterface ti;
    public TestClass(TestInterface ti){
        this.ti = ti;
    }

    public void testActionMethod(){
        ti.doSomething();
        //some other codes
    }
}

class OurOwnLauncherApp{
    public static void main(String[] args) {
        TestClass tc = new TestClass(new TestInterface() {
            @Override
            public void doSomething() {
                System.out.println("Hi!");
            }
        });

        tc.testActionMethod();

        TestClass tc2 = new TestClass(new TestInterface() {
            @Override
            public void doSomething() {
                System.out.println("Bye!");
            }
        });

        tc2.testActionMethod();
    }
}

In here we have:

  1. An Interface (Just like what you asked)
  2. A function class the uses that interface
  3. An application somewhere that we don't know (Maybe your phone app, maybe your friends phone app, etc)

What this code does, it gives an anonymous class (which implements TestInterface) to the testActionMethod and with calling doSomething method inside testActionMethod, we invert the calling back to our own method. that's why you will see this result:

Hi!

Bye!

This is exactly a simplified version of listener interfaces and how they work

Upvotes: 1

Related Questions