我想停止我的函数执行,这是写在延迟后,每当我用textchangedlistener在Kotlin中断它



我有一个在OntextChangedListner中编写的函数,它从edittext输入并使用它来调用API,每次你在edittext中键入一些东西即(如果我正在写一些字符串长度为10的东西它调用API 10次)。

我想它不应该每次我在edittext中写一些东西都调用API,每当我停止写作时就应该击中API,所以我试图给一个延迟,以便每当我停止写作时它就会调用API,但它不像我预期的那样工作(如果我的字符串长度是10,那么它在一些延迟后调用API 10时间)

这是我的代码

override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
val runnable = Runnable {
val lengthoftext = searchCompany.text.length
mycompanies.clear()
callforapi(s.toString())
}

val handler = Handler(Looper.getMainLooper())
handler.postDelayed({ runnable.run() }, 500)
}

fun callforapi(tempchar: String){
val queue = Volley.newRequestQueue(this)
val url = "SomeAPI" + tempchar
val jsonObjectRequest = JsonObjectRequest(
Request.Method.GET, url, null,
{ response ->
var tempcomparray = response.getJSONArray("companies")
var objlength = tempcomparray.length()
adapter?.clear()
for (i in 0 until objlength)
{
var tempcompobj = tempcomparray.getJSONObject(i)
mycompanies.add(tempcompobj.getString("name"))

}
Log.d("checktheobj", mycompanies.toString())
},
{ error ->
Log.d("check", "Something is Wrong ")
}
)
queue.add(jsonObjectRequest)
return
}

我正在使用volly库调用API。

请告诉我怎么做。

Thankyou in Advance.

在kotlin中使用协程的最佳方式。如果你不知道协程或者不想使用它。然后你可以使用Timer

private Timer timer = new Timer();
private final long DELAY = 500; // Milliseconds
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int){
timer.cancel();
timer = new Timer();
timer.schedule(
new TimerTask() {
@Override
public void run() {
// TODO: Do what you need here.
val lengthoftext = searchCompany.text.length
mycompanies.clear()
callforapi(s.toString())
}
},
DELAY
);
}
}
}

您可以保留对上次发出的请求和处理程序的属性引用,并使用它们在每次键入信件时取消任何现有的请求和任何挂起的处理程序消息。因此,当一个字母被键入时,任何已经开始的API调用都可以被取消,任何尚未完成等待延迟的已发布的可运行程序也将在它开始之前被取消。

注意,您最终应该将API调用拆分为ViewModel,以便在旋转屏幕时进行适当的封装和行为,但我将把它留给您,因为ViewModels是一个需要学习的大主题,在这里解释太多了。

// Class properties:
val apiCallHandler = Handler(Looper.getMainLooper())
val lastApiCallRequest: Request<*>? = null
// In listener:
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
apiCallHandler.removeCallbacksAndMessages()
apiCallHandler.postDelayed({
val lengthoftext = searchCompany.text.length
mycompanies.clear()
callforapi(s.toString())
}, 500)
}
// ...
fun callforapi(tempchar: String){
// your existing code
// then right before returning:
lastApiCallRequest?.cancel()
lastApiCallRequest = jsonObjectRequest
}

可以在协程中延迟启动api调用。保存它对属性的引用,并在每次调用onTextChanged时取消它。如果在延迟前未取消Job,则实现api调用。

private var textChangeJob: Job? = null
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
// job is cancelled on each character, if no character added in specified delay
// job won't be canceled, hence api will be called
textChangeJob?.cancel()
// You could also use lifecycleScope or viewModelScope, depends if you want to make the call
// to api if fragment is destroyed
textChangeJob = GlobalScope.launch {
delay(300) // how long to wait for next character
// call your code here
callforapi(s.toString())
}
}

最新更新