Android 在UserLoginTask中完成登录API完成块后,如何在doInBackground中返回结果

Android 在UserLoginTask中完成登录API完成块后,如何在doInBackground中返回结果,android,android-asynctask,kotlin,Android,Android Asynctask,Kotlin,我在Android Studio中使用了默认的LoginActivity,并创建了一个简单的登录视图。在我的应用程序中,身份验证任务和访问令牌生成由服务器通过API调用完成。但是,由于api调用必须有一个完成块,因此doInBackground中的登录函数也有。因此,验证结果存在于完成块的线程中,这使得原始doInBackground到onPostExecute的返回结果不正确。这些函数被重写,因此我无法更改它们的参数和格式。我还是android开发新手,对它的异步任务还不是很熟悉,所以我想问一

我在Android Studio中使用了默认的LoginActivity,并创建了一个简单的登录视图。在我的应用程序中,身份验证任务和访问令牌生成由服务器通过API调用完成。但是,由于api调用必须有一个完成块,因此
doInBackground
中的登录函数也有。因此,验证结果存在于完成块的线程中,这使得原始
doInBackground
onPostExecute
的返回结果不正确。这些函数被重写,因此我无法更改它们的参数和格式。我还是android开发新手,对它的异步任务还不是很熟悉,所以我想问一下,是否有什么方法可以在
doInBackground
中停止,并在completion块中等待结果?或者有没有更好的解决方案来解决我的API登录问题?谢谢

下面是我的UserLoginTask的代码(用kotlin编写,但我认为其概念与java相同):

内部类UserLoginTask内部构造函数(private val mUsername:String,private val mPassword):AsyncTask(){
重写fun doInBackground(vararg参数:Void?):布尔值{
var结果=错误
试一试{
《睡眠》(2000年)
}捕获(e:中断异常){
返回错误
}
MyLoginService().login(mUsername、mPassword、onCompleted={token->
//我想从这里获得登录结果并将其返回到onPostExecute
//如果我在这里将结果更改为true是没有用的,因为在完成之前已经返回了结果。
})
返回结果
}
重写onPostExecute(成功:布尔值?){
mAuthTask=null
显示进度(错误)
如果(成功!!){
完成()
}否则{
mPasswordView!!.error=getString(R.string.error\u密码不正确)
mPasswordView!!.requestFocus()
}
}
override fun onCancelled(){
mAuthTask=null
显示进度(错误)
}
}

你可以这样做,但这不是一个好主意。在您的情况下,最好使用Rx或futures之类的工具,而不是
AsyncTask

override fun doInBackground(vararg params: Void?): Boolean? {
  val exchanger = Exchanger<Boolean>()
  MyLoginService().login(mUsername, mPassword, onCompleted = { token ->
    exchanger.exchange(token != null)
  })

  return try {
    exchanger.exchange(false)
  } catch (exception: InterruptedException) {
    false
  }
}
override-fun-doInBackground(vararg参数:Void?):布尔值?{
val交换器=交换器()
MyLoginService().login(mUsername、mPassword、onCompleted={token->
exchanger.exchange(令牌!=null)
})
回击{
exchange.exchange(错误)
}捕获(异常:InterruptedException){
假的
}
}

你可以这样做,但这不是一个好主意。在您的情况下,最好使用Rx或futures之类的工具,而不是
AsyncTask

override fun doInBackground(vararg params: Void?): Boolean? {
  val exchanger = Exchanger<Boolean>()
  MyLoginService().login(mUsername, mPassword, onCompleted = { token ->
    exchanger.exchange(token != null)
  })

  return try {
    exchanger.exchange(false)
  } catch (exception: InterruptedException) {
    false
  }
}
override-fun-doInBackground(vararg参数:Void?):布尔值?{
val交换器=交换器()
MyLoginService().login(mUsername、mPassword、onCompleted={token->
exchanger.exchange(令牌!=null)
})
回击{
exchange.exchange(错误)
}捕获(异常:InterruptedException){
假的
}
}

异步任务重写函数的参数和返回类型取决于AsyncTask()中定义的参数。因此,将第三个参数Boolean更改为onpostExecute方法中所需的参数。您正在将“result”返回到postExecute。从这段代码中,“result”始终为false。。你永远不会改变它的价值?谢谢@ashmkansal告诉我如何改变返回类型,帮助很大!现在我可以试着只处理完成块…到,@sunilsunny是的,结果值没有更改,实际上在完成块中获得身份验证结果后更改它是没有用的,完成块在不同的位置运行。MyLoginService()。登录已经是一个异步调用,所以不需要在onBackgroundParameters中调用,异步任务重写函数的返回类型取决于AsyncTask()中定义的参数。因此,将第三个参数Boolean更改为onpostExecute方法中所需的参数。您正在将“result”返回到postExecute。从这段代码中,“result”始终为false。。你永远不会改变它的价值?谢谢@ashmkansal告诉我如何改变返回类型,帮助很大!现在我可以试着只处理完成块…到,@sunilsunny是的,结果值没有更改,实际上在完成块中获得身份验证结果后更改它是没有用的,完成块在不同的位置运行。MyLoginService()。登录已经是一个异步调用,因此,不需要在后台调用。最后,我将登录服务移动到主线程,解决了问题。不过,您提到的交换机似乎是一个有用的工具!学到了一些新东西,谢谢!最后,我将我的登录服务移动到主线程并解决了这个问题。不过,您提到的交换机似乎是一个有用的工具!学到了一些新东西,谢谢!