use*_*376 15 java android android-asynctask
我是android的新手,非常习惯于web开发.在javascript中,当您要执行异步任务时,您将函数作为参数传递(回调):
http.get('www.example.com' , function(response){
//some code to handle response
});
Run Code Online (Sandbox Code Playgroud)
我想知道我们是否可以对android做同样的事情AsyncTask,传递方法的函数引用onPostExecute(),它将运行它.
有什么建议 ?
Xav*_*ler 46
是的,回调的概念在Java中也非常存在.在Java中,您可以像这样定义一个回调:
public interface TaskListener {
public void onFinished(String result);
}
Run Code Online (Sandbox Code Playgroud)
人们通常会将这些类型的侦听器定义嵌套在AsyncTask这样的内容中:
public class ExampleTask extends AsyncTask<Void, Void, String> {
public interface TaskListener {
public void onFinished(String result);
}
...
}
Run Code Online (Sandbox Code Playgroud)
并且在回调中的完整实现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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
onPostExecute()在后台任务完成后立即调用.你可以使用这样的整个事情:
ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
@Override
public void onFinished(String result) {
// Do Something after the task has finished
}
});
task.execute();
Run Code Online (Sandbox Code Playgroud)
或者您可以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();
Run Code Online (Sandbox Code Playgroud)
或者您可以TaskListener像这样子类:
public class ExampleTaskListener implements TaskListener {
@Override
public void onFinished(String result) {
}
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
ExampleTask task = new ExampleTask(new ExampleTaskListener());
task.execute();
Run Code Online (Sandbox Code Playgroud)
你当然可以覆盖它的onPostExecute()方法AsyncTask,但不建议这样做,在大多数情况下实际上是非常糟糕的做法.例如,你可以这样做:
ExampleTask task = new ExampleTask() {
@Override
public void onPostExecute(String result) {
super.onPostExecute(result);
// Your code goes here
}
};
Run Code Online (Sandbox Code Playgroud)
这将与上面的实现一样使用单独的侦听器接口,但是有一些问题:
首先,你可以真正打破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
}
}
Run Code Online (Sandbox Code Playgroud)
所有这些都隐藏在称为匿名类的语言功能之后.突然重写这样的方法似乎不那么干净和快速了吗?
总结一下:
ExampleTask可能会抛出Exceptions或根本不再工作,因为你从未真正修改过它的代码.onPostExecute()但这总是非常危险.即使是拥有13k声望的@flup也忘了super.onPostExecute()在他的回答中包含这个电话,想象一下其他一些不像经验丰富的开发者可能做的事情!onPostExecute()基本上牺牲了代码质量,以方便一点.从来没有一个好主意,只会造成问题.| 归档时间: |
|
| 查看次数: |
13614 次 |
| 最近记录: |