Java Android:将函数引用传递给AsyncTask

Java Android:将函数引用传递给AsyncTask,java,android,android-asynctask,Java,Android,Android Asynctask,我是android新手,非常习惯于网络开发。在javascript中,当您想要执行异步任务时,您将函数作为参数传递(回调): 我想知道我们是否可以对android的AsyncTask执行同样的操作,将函数引用传递给onPostExecute()方法,它就会运行它 有什么建议吗?是的,回调的概念在Java中也非常存在。在Java中,您可以定义如下回调: public interface TaskListener { public void onFinished(String result)

我是android新手,非常习惯于网络开发。在javascript中,当您想要执行异步任务时,您将函数作为参数传递(回调):

我想知道我们是否可以对android的
AsyncTask
执行同样的操作,将函数引用传递给
onPostExecute()
方法,它就会运行它


有什么建议吗?

是的,回调的概念在Java中也非常存在。在Java中,您可以定义如下回调:

public interface TaskListener {
    public void onFinished(String result);
}
public class ExampleTask extends AsyncTask<Void, Void, String> {

    public interface TaskListener {
        public void onFinished(String result);
    }

    ...
}
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);
        }
    }
}
ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
    @Override
    public void onFinished(String result) {
        // Do Something after the task has finished
    }
});

task.execute();
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();
public class ExampleTaskListener implements TaskListener {

    @Override
    public void onFinished(String result) {

    }
}
ExampleTask task = new ExampleTask(new ExampleTaskListener());    
task.execute();
人们通常会将此类侦听器定义嵌套在
AsyncTask
中,如下所示:

public interface TaskListener {
    public void onFinished(String result);
}
public class ExampleTask extends AsyncTask<Void, Void, String> {

    public interface TaskListener {
        public void onFinished(String result);
    }

    ...
}
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);
        }
    }
}
ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
    @Override
    public void onFinished(String result) {
        // Do Something after the task has finished
    }
});

task.execute();
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();
public class ExampleTaskListener implements TaskListener {

    @Override
    public void onFinished(String result) {

    }
}
ExampleTask task = new ExampleTask(new ExampleTaskListener());    
task.execute();
后台任务完成后,将立即调用
onPostExecute()
。你可以这样使用整个东西:

public interface TaskListener {
    public void onFinished(String result);
}
public class ExampleTask extends AsyncTask<Void, Void, String> {

    public interface TaskListener {
        public void onFinished(String result);
    }

    ...
}
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);
        }
    }
}
ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
    @Override
    public void onFinished(String result) {
        // Do Something after the task has finished
    }
});

task.execute();
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();
public class ExampleTaskListener implements TaskListener {

    @Override
    public void onFinished(String result) {

    }
}
ExampleTask task = new ExampleTask(new ExampleTaskListener());    
task.execute();
或者您可以完全单独定义
任务侦听器
,如下所示:

public interface TaskListener {
    public void onFinished(String result);
}
public class ExampleTask extends AsyncTask<Void, Void, String> {

    public interface TaskListener {
        public void onFinished(String result);
    }

    ...
}
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);
        }
    }
}
ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
    @Override
    public void onFinished(String result) {
        // Do Something after the task has finished
    }
});

task.execute();
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();
public class ExampleTaskListener implements TaskListener {

    @Override
    public void onFinished(String result) {

    }
}
ExampleTask task = new ExampleTask(new ExampleTaskListener());    
task.execute();
或者,您可以像下面这样子类化
TaskListener

public interface TaskListener {
    public void onFinished(String result);
}
public class ExampleTask extends AsyncTask<Void, Void, String> {

    public interface TaskListener {
        public void onFinished(String result);
    }

    ...
}
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);
        }
    }
}
ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
    @Override
    public void onFinished(String result) {
        // Do Something after the task has finished
    }
});

task.execute();
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();
public class ExampleTaskListener implements TaskListener {

    @Override
    public void onFinished(String result) {

    }
}
ExampleTask task = new ExampleTask(new ExampleTaskListener());    
task.execute();
然后像这样使用它:

public interface TaskListener {
    public void onFinished(String result);
}
public class ExampleTask extends AsyncTask<Void, Void, String> {

    public interface TaskListener {
        public void onFinished(String result);
    }

    ...
}
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);
        }
    }
}
ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
    @Override
    public void onFinished(String result) {
        // Do Something after the task has finished
    }
});

task.execute();
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();
public class ExampleTaskListener implements TaskListener {

    @Override
    public void onFinished(String result) {

    }
}
ExampleTask task = new ExampleTask(new ExampleTaskListener());    
task.execute();

当然,您可以重写
AsyncTask
onPostExecute()
方法,但不建议这样做,而且在大多数情况下实际上是非常糟糕的做法。例如,您可以这样做:

ExampleTask task = new ExampleTask() {
    @Override
    public void onPostExecute(String result) {
        super.onPostExecute(result);

        // Your code goes here
    }
};
使用单独的侦听器接口,这与上面的实现一样有效,但存在一些问题:

首先也是最重要的一点是,您可以将
ExampleTask
全部分解。这一切都归结于上面的
super.onPostExecute()
调用。如果作为开发人员,您像上面那样重写了
onPostExecute()
,忘记了包含超级调用,或者只是出于某种原因删除了超级调用,
ExampleTask
中的原始
onPostExecute()
方法将不再被调用。例如,由于对回调的调用是在
onPostExecute()
中实现的,因此使用
TaskListener
的整个侦听器实现将突然无法工作。您还可以通过在不知情或不知情的情况下影响
ExampleTask
的状态,以许多其他方式中断
tasklister
,使其不再工作

如果你看一下当你重写一个这样的方法时实际发生了什么,你就会更清楚发生了什么。通过重写
onPostExecute()
您正在创建
ExampleTask
的新子类。这与这样做完全一样:

public class AnotherExampleTask extends ExampleTask {

    @Override
    public void onPostExecute(String result) {
        super.onPostExecute(result);

        // Your code goes here
    }
}
所有这些都隐藏在一种叫做匿名类的语言特性后面。突然间重写这样的方法似乎不再那么干净和快速了,是吗

总结如下:

  • 重写这样的方法实际上会创建一个新的子类。您不仅添加了回调,还修改了这个类的工作方式,并可能在不知不觉中破坏很多东西
  • 像这样的调试错误可能不仅仅是**中的一种痛苦。因为突然
    ExampleTask
    可能会抛出
    异常
    或者因为没有明显的原因而不再工作,因为您从未真正修改过它的代码
  • 每个类都必须在适当和预期的位置提供侦听器实现。当然,您可以稍后通过重写
    onPostExecute()
    添加它们,但这总是非常危险的。即使拥有13k声誉的@flup也忘了在他的回答中加入
    super.onPostExecute()
    调用,想象一下其他一些没有经验的开发人员会做什么
  • 一点点抽象不会伤害任何人。编写特定的侦听器可能需要编写更多的代码,但这是一个更好的解决方案。代码将更干净、可读性更强、可维护性更强。使用诸如重写
    onPostExecute()
    这样的快捷方式,本质上牺牲了代码质量以获得一点便利。这绝不是一个好主意,从长远来看只会造成问题

    • 在Java中,函数不像JavaScript那样是一等公民。AsyncTask将回调作为类中的方法提供,您应该重写该方法

      有关AsyncTask的子类以及发出web请求的doInBackground的实现,请参阅

      若要使用不同的回调执行多个HTTP请求,可以覆盖RequestTask并使用不同的回调实现实现onPostExecute。 您可以使用匿名类来模拟JavaScript回调常用的闭包:

      new RequestTask(){
          @Override
          public void onPostExecute(String result) {
              // Implementation has read only access to 
              // final variables in calling scope. 
          }
      }.execute("http://stackoverflow.com");
      
      正如Xaver所示,您还可以为侦听器创建一个完整的接口。只有当您希望实现两个默认的onPostExecute函数并为特定调用选择其中一个默认实现时,这才对我有用

      在科特林

      首先,创建类AsyncTaskHelper,如下所示

      class AsyncTaskHelper() : AsyncTask<Callable<Void>, Void, Boolean>() {
      
          var taskListener: AsyncListener? = null
      
          override fun doInBackground(vararg params: Callable<Void>?): Boolean {
              params.forEach {
                  it?.call()
              }
              return true
          }
      
          override fun onPreExecute() {
              super.onPreExecute()
          }
      
          override fun onPostExecute(result: Boolean?) {
              super.onPostExecute(result)
              taskListener?.onFinished(result as Any)
          }
      
      }
      
      interface AsyncListener {
          fun onFinished(obj: Any)
      }
      
      类AsyncTaskHelper():AsyncTask(){
      var taskListener:AsyncListener?=null
      重写fun doInBackground(vararg参数:可调用?):布尔值{
      帕拉姆斯·弗雷奇{
      它?.call()
      }
      返回真值
      }
      覆盖乐趣onPreExecute(){
      super.onPreExecute()
      }
      重写onPostExecute(结果:布尔值?){
      super.onPostExecute(结果)
      taskListener?.onFinished(结果为任意)
      }
      }
      接口异步侦听器{
      完成的乐趣(对象:任何)
      }
      
      要使用异步任务时,可以使用下面的代码

          AsyncTaskHelper().let {
              it.execute(Callable<Void> {
                      //this area is the process do you want to do it in background
                      // dosomething()
                      }
                  }
                  null
              })
              it.taskListener = object : AsyncListener{
                  override fun onFinished(obj: Any) {
                      // this area is for the process will want do after finish dosomething() from Callable<Void> callback
      
      
                  }
      
              }
      
      AsyncTaskHelper()。让{
      it.execute(可调用{
      //此区域是您希望在后台执行的过程吗
      //dosomething()
      }
      }
      无效的
      })
      it.taskListener=对象:AsyncListener{
      覆盖未完成(对象:任何){
      //此区域用于可调用回调中的进程在完成dosomething()后要执行的操作
      }
      }
      
      从上面的代码。如果您想将流程划分为多个任务。您可以按照下面的代码进行操作

      AsyncTaskHelper().let {
                  it.execute(Callable<Void> {
                      // task 1 do in background
                      null
                  },Callable<Void>{
                      // task 2 do in background
                      null
                  },Callable<Void>{
                      // task 3 do in background
                      null
                  })
      
                  it.taskListener = object : AsyncListener {
                      override fun onFinished(obj: Any) {
                          // when task1,task2,task3 has been finished . it will do in this area
                      }
      
                  }
              }
      
      AsyncTaskHelper()。让{
      it.execute(可调用{
      //t