我是android新手,非常习惯于网络开发。在javascript中,当您要执行异步任务时,可以将函数作为参数传递(回调):
http.get('www.example.com' , function(response){
//some code to handle response
});
我想知道我们是否可以对android进行相同的操作AsyncTask
,将函数引用传递给onPostExecute()
方法,然后它将运行它。
有什么建议 ?
是的,回调的概念在Java中也非常存在。在Java中,您可以这样定义一个回调:
public interface TaskListener {
public void onFinished(String result);
}
人们通常会在AsyncTask
这样的内部嵌套这些侦听器定义:
public class ExampleTask extends AsyncTask<Void, Void, String> {
public interface TaskListener {
public void onFinished(String result);
}
...
}
回调的完整实现AsyncTask
如下所示:
public class ExampleTask extends AsyncTask<Void, Void, String> {
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
通过不知不觉或无意地影响s的状态来以其他多种方式破坏s的状态ExampleTask
。
如果您查看重写此类的方法时实际发生的情况,则将比现在更清楚地了解发生了什么。通过覆盖,onPostExecute()
您将创建的新子类ExampleTask
。这样做完全相同:
public class AnotherExampleTask extends ExampleTask {
@Override
public void onPostExecute(String result) {
super.onPostExecute(result);
// Your code goes here
}
}
所有这些都隐藏在称为匿名类的语言功能的后面。突然重载这样的方法似乎不再那么干净快捷了吗?
总结一下:
ExampleTask
可能由于Exceptions
没有明显的原因而抛出或根本无法工作,因为您从未真正修改过它的代码。onPostExecute()
但这始终非常危险。甚至@flup以其13k的声誉也忘记了将super.onPostExecute()
电话包含在他的答案中,想象一下其他一些没有经验的开发人员会做什么!onPostExecute()
实际上会牺牲代码质量,从而带来一些便利。这绝不是一个好主意,从长远来看只会造成问题。问题内容: 考虑一个非fx的现有应用程序,将其称为。 公开一个对象,该对象又公开了一些属性。也接受这些属性的侦听器。 我的问题是关于 将 JavaFx gui 添加 到此类应用程序。将明显延长,将需要一个参考对象。 在寻找将非String参数传递给我的解决方案时,我发现了几种不同的方法: 静态方法:例如,已初始化对in 的静态引用。在这里可以看到使用静电的一个示例。 JavaFx 9方法:如此处所
问题内容: 我有一个C函数声明如下: 如今,我的cython包装器代码使用了numpy数组中的缓冲区语法: 我想使用新的memoryview语法,我的问题是,使用memoryview时如何将指针传递给数据? 我试过了: 当我尝试编译模块时,出现了“无法将类型’long [:]’分配给’long *’”的错误。有没有什么方法可以在调用C函数之前将指针传递给numpy数组而不将其强制转换为numpy数
要将数组参数传递给函数,需指定不带方括号的数组名。例如,如果数组hourlyTemperatures声明如下: int hourlyTemperatures[24]; 则下列函数调用语句: modifyArray(hourlyTemperatutes,24); 将数组 hourlyTemperatures 及其长度传递给函数 modifyArray。将数组传递给函数时,通常也将其长度传递给函数,使
问题内容: 我有一个用Java实现的javascript接口,该接口由Web视图中加载的javascript代码调用。 JS Inside webview: Java: 通过webview加载的字符串最终是: 我有一些想法: 一个。在JS中以字符串形式构建回调。 b。在将回调传递给Android.myFunction()之前,先调用回调的toString(); 我的问题是,最好的方法是什么?我希望
问题内容: 我希望一个长时间运行的进程通过一个队列(或类似的东西)返回其进度,该队列将被馈送到进度栏对话框。该过程完成后,我还需要结果。这里的测试示例以失败。 我已经能够得到这个使用单独的进程对象的工作(在这里我 很 alowed传递一个队列引用),但是我没有一个池来管理许多过程我想推出。有什么更好的模式建议吗? 问题答案: 以下代码似乎有效: 请注意,队列是从manager.Queue()而不是
我很好奇在Spark中把一个RDD传递给一个函数到底做了什么。 假设我们如上定义一个函数。当我们调用函数并传递一个现有的RDD[String]对象作为输入参数时,这个my_function是否将这个RDD作为函数参数进行“复制”?换句话说,是按引用调用还是按值调用?