侦听器接口如何或为何工作?除了作为监听器之外,接口还有其他用途吗?

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

每当我们想要创建一个监听器时,我们都会实现一个监听器接口。例如,让我们实现 SensorEventListener

现在我们必须覆盖这个侦听器接口的方法。

public void onSensorChanged(SensorEvent event);

public void onAccuracyChanged(Sensor sensor, int accuracy);

我不明白的是:

  1. 为什么以及如何在我自动使用这些方法时起作用?
  2. 为什么当精度改变时调用 onAccuracyChanged 方法?
  3. 毕竟,onAccuracyChanged 只是我们覆盖的一个空方法,因为我们的公式(或我们实现的接口)要求我们这样做。如果是下层造成的魔法
  4. 何时以及为什么有人会实际使用 his/her 中的界面 不考虑 android?
  5. 的自我项目

接口没有实现,要使用它们,我们有两个选择:

  1. 实现它们的 class
  2. 匿名class

并考虑这段代码:

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();
    }
}

这里有:

  1. 一个接口(就像你问的那样)
  2. 一个函数class使用那个接口
  3. 某个我们不知道的应用程序(可能是您的 phone 应用程序,可能是您的朋友 phone 应用程序等)

这段代码的作用是,它为 testActionMethod 提供匿名 class(实现 TestInterface)并调用 doSomething 方法内部 testActionMethod我们将调用反转回我们自己的方法。 这就是为什么你会看到这个结果:

Hi!

Bye!

这正是监听器接口及其工作方式的简化版本

没有神奇的东西。一般事件监听机制如下:

对于某些实体,可以侦听该实体上的某些事件(我们将此实体命名为事件生成器)。因此,其他实体应该存在某种方式来监听这些更改(让这些实体命名为监听器)。现在一个监听器将自己注册为事件生成器的监听器。当事件生成器发生事件时,它会调用已注册监听器的相关方法。

举一个简单的例子,假设有一个按钮。该按钮可能会为某些操作(例如单击)生成事件。现在,如果监听器想知道按钮何时被单击,它应该将自己注册为该按钮的监听器。另一方面,按钮应该提供一种统一的方式来注册听众。这种统一的方式就是接口。每个实现该接口的实体都可以将自己注册为单击该按钮的侦听器:

1-监听器实现接口 2- 监听器将自己注册为按钮的监听器(事件生成器) 3- Event Generator 调用所有已注册监听器的相应方法(此方法是接口的方法)。

对于您的情况,android 提供了一个管理器,您可以通过它在某些传感器上注册监听器:android.hardware.SensorManager.registerListener()。所有的事情都发生在这里(这不是魔法!)。当您将一个实体(实现了相关接口,SensorEventListener)注册为传感器侦听器时,该传感器的更改将导致调用侦听器的方法)。

这里是suitable answer。请允许我举一个关于听众的例子。

听众:

假设有一个 class 在后台获取数据 Worker,另一个 class 对该数据感兴趣,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);
 }

}

Worker不关心哪个class会操纵它的数据,只要class遵守的契约DataFetchedListener

同样,这意味着 任何 class 都能够对数据做一些事情(InterestedClass 只是在控制台打印它)但是 Worker 不需要知道 class 是哪个 只是它实现了它的接口 .

主要可以这样走...

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
  }
} 

Worker 获取数据时,它会通知它的侦听器(当前是 interested 对象),侦听器会相应地采取行动(interested 会将数据打印到控制台)。

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

您可能希望响应一些系统事件或用户事件。但是为此,您需要知道您希望捕获的事件何时发生以及当时必须做什么。

为此,您打开机密的 EAR 来收听事件。但这还不够,因为您还需要收到通知,以便您可以根据事件进行回复。您设置 回调 将在事件发生时发出通知。我们在接口中创建的那些空体方法。

监听器是通过回调监听和通知的接口。

那么这一切怎么用呢?所有这些如何相互作用?

  • 首先创建一个带有空主体方法的接口,您打算在事件发生时调用这些方法:
public interface MyListener{

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

}
  • 创建一个 class 来处理一些事情,例如计数:
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();
}




}
  • 然后您可以创建一个 MyCounter 类型的对象并知道它何时在三:

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();

大功告成!!我们就是这样进行的。