侦听器界面如何或为什么起作用?接口除了用作侦听器外还有其他用途吗?

时间:2018-12-01 15:04:46

标签: java android listener implements

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

现在,我们必须重写此侦听器接口的方法。

public void onSensorChanged(SensorEvent event);

public void onAccuracyChanged(Sensor sensor, int accuracy);

我不明白的是:

  1. 为什么这些方法以及如何在我自动使用它们时起作用?
  2. 为什么精度改变时会调用onAccuracyChanged方法?
  3. 毕竟,onAccuracyChanged只是一个空方法,我们会对其进行覆盖,因为我们的公式(或我们实现的接口)要求我们这样做。如果是由较低级别引起的魔法
  4. 何时以及为何有人在他/她中实际使用界面 自己计划而不考虑android?

4 个答案:

答案 0 :(得分:2)

这里是suitable answer。请允许我给您一个有关侦听器的示例。

听众:

假设存在一个在后台获取数据的类Worker,而另一个对数据感兴趣的类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不在乎哪个类将操纵其数据,只要该类遵守DataFetchedListener的合同即可。

同样,这意味着任何类都可以对数据进行处理(InterestedClass只是在控制台中进行打印),但是Worker不需要知道哪个类就是,只是实现了其接口

主体可能会这样...

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将数据打印到控制台)

答案 1 :(得分:1)

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

  1. 实现它们的类
  2. 一个匿名班

并考虑以下代码:

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. 使用该接口的函数类
  3. 我们不知道的地方的应用程序(也许是您的电话应用程序,也许是您的朋友的电话应用程序等)

此代码的作用是,它为 testActionMethod 提供一个匿名类(实现TestInterface),并在 testActionMethod 中调用 doSomething 方法, 我们将调用转换回我们自己的方法。这就是为什么您会看到以下结果的原因:

  

嗨!

     

再见!

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

答案 2 :(得分:1)

没有神奇的东西。通常,事件监听器机制如下:

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

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

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

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

答案 3 :(得分:1)

  

在计算中,接口是一个共享的边界,计算机系统的两个或多个单独的组件在该边界上交换信息。(维基百科)

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

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

侦听器是用于侦听并通过回调通知的接口。

那么如何使用所有这些?以及所有这些如何相互作用?

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

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

}
  • 创建一个处理某些内容的类,例如计数:
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();

就完成了!!我们就是这样进行的。