侦听器接口如何或为何工作?除了作为监听器之外,接口还有其他用途吗?
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);
我不明白的是:
- 为什么以及如何在我自动使用这些方法时起作用?
- 为什么当精度改变时调用
onAccuracyChanged
方法?
- 毕竟,
onAccuracyChanged
只是我们覆盖的一个空方法,因为我们的公式(或我们实现的接口)要求我们这样做。如果是下层造成的魔法
- 何时以及为什么有人会实际使用 his/her 中的界面
不考虑 android?
的自我项目
接口没有实现,要使用它们,我们有两个选择:
- 实现它们的 class
- 匿名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();
}
}
这里有:
- 一个接口(就像你问的那样)
- 一个函数class使用那个接口
- 某个我们不知道的应用程序(可能是您的 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();
大功告成!!我们就是这样进行的。
每当我们想要创建一个监听器时,我们都会实现一个监听器接口。例如,让我们实现 SensorEventListener
。
现在我们必须覆盖这个侦听器接口的方法。
public void onSensorChanged(SensorEvent event);
和
public void onAccuracyChanged(Sensor sensor, int accuracy);
我不明白的是:
- 为什么以及如何在我自动使用这些方法时起作用?
- 为什么当精度改变时调用
onAccuracyChanged
方法? - 毕竟,
onAccuracyChanged
只是我们覆盖的一个空方法,因为我们的公式(或我们实现的接口)要求我们这样做。如果是下层造成的魔法 - 何时以及为什么有人会实际使用 his/her 中的界面 不考虑 android? 的自我项目
接口没有实现,要使用它们,我们有两个选择:
- 实现它们的 class
- 匿名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();
}
}
这里有:
- 一个接口(就像你问的那样)
- 一个函数class使用那个接口
- 某个我们不知道的应用程序(可能是您的 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();
大功告成!!我们就是这样进行的。