android.函数传递,Android:将函数引用传递给AsyncTask

Xaver Kapell..

46

是的,回调的概念在Java中也非常存在.在Java中,您可以像这样定义一个回调:

public interface TaskListener {

public void onFinished(String result);

}

人们通常会将这些类型的侦听器定义嵌套在AsyncTask这样的内容中:

public class ExampleTask extends AsyncTask {

public interface TaskListener {

public void onFinished(String result);

}

...

}

并且在回调中的完整实现AsyncTask将如下所示:

public class ExampleTask extends AsyncTask {

public interface TaskListener {

public void onFinished(String result);

}

// This is the reference to the associated listener

private final TaskListener taskListener;

public ExampleTask(TaskListener listener) {

// The listener reference is passed in through the constructor

this.taskListener = listener;

}

@Override

protected String doInBackground(Void... params) {

return doSomething();

}

@Override

protected void onPostExecute(String result) {

super.onPostExecute(result);

// In onPostExecute we check if the listener is valid

if(this.taskListener != null) {

// And if it is we call the callback function on it.

this.taskListener.onFinished(result);

}

}

}

onPostExecute()在后台任务完成后立即调用.你可以使用这样的整个事情:

ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {

@Override

public void onFinished(String result) {

// Do Something after the task has finished

}

});

task.execute();

或者您可以TaskListener像这样完全单独定义:

ExampleTask.TaskListener listener = new ExampleTask.TaskListener() {

@Override

public void onFinished(String result) {

// Do Something after the task has finished

}

};

ExampleTask task = new ExampleTask(listener);

task.execute();

或者您可以TaskListener像这样子类:

public class ExampleTaskListener implements TaskListener {

@Override

public void onFinished(String result) {

}

}

然后像这样使用它:

ExampleTask task = new ExampleTask(new ExampleTaskListener());

task.execute();

你当然可以覆盖它的onPostExecute()方法AsyncTask,但不建议这样做,在大多数情况下实际上是非常糟糕的做法.例如,你可以这样做:

ExampleTask task = new ExampleTask() {

@Override

public void onPostExecute(String result) {

super.onPostExecute(result);

// Your code goes here

}

};

这将与上面的实现一样使用单独的侦听器接口,但是有一些问题:

首先,你可以真正打破ExampleTask所有这些.这一切都归结为super.onPostExecute()上面的呼吁.如果您作为开发人员覆盖onPostExecute()如上所述并忘记包含超级调用或只是删除它,无论出于何种原因,将不再调用原始onPostExecute()方法ExampleTask.例如,由于实现TaskListener了对回调的调用,因此整个监听器实现将突然不再起作用onPostExecute().你也可以TaskListener通过不知不觉或无意中影响其状态来打破许多其他方式,ExampleTask因此它将不再起作用.

如果你看一下覆盖这样的方法时实际发生的事情,那么它会变得更加清晰.通过重写onPostExecute()你正在创建一个新的子类ExampleTask.这与完成同样的事情:

public class AnotherExampleTask extends ExampleTask {

@Override

public void onPostExecute(String result) {

super.onPostExecute(result);

// Your code goes here

}

}

所有这些都隐藏在称为匿名类的语言功能之后.突然重写这样的方法似乎不那么干净和快速了吗?

总结一下:

覆盖这样的方法实际上会创建一个新的子类.你不只是添加一个回调,你正在修改这个类的工作方式,并且可以在不知不觉中破坏这么多东西.

像这样的调试错误不仅仅是a**的痛苦.因为没有明显的原因突然之间ExampleTask可能会抛出Exceptions或根本不再工作,因为你从未真正修改过它的代码.

每个类都必须在适当和有意的地方提供监听器实现.当然,您可以稍后通过覆盖添加它们,onPostExecute()但这总是非常危险.即使是拥有13k声望的@flup也忘了super.onPostExecute()在他的回答中包含这个电话,想象一下其他一些不像经验丰富的开发者可能做的事情!

一点抽象从不伤害任何人.编写特定的侦听器可能会稍微多一些代码,但它是一个更好的解决方案.代码将更清晰,更易读,更易于维护.使用像覆盖这样的快捷方式onPostExecute()基本上牺牲了代码质量,以方便一点.从来没有一个好主意,只会造成问题.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值