Tengo una actividad en la que un usuario escribe un texto de edición, pulsa un botón de búsqueda y la aplicación consulta un servicio web y coloca los resultados en un ListView.Búsqueda automática como tipos de usuario
Me gustaría eliminar el botón de búsqueda.
Obviamente, no quiero que todos los caracteres que el usuario escriba lleguen al servicio web. Solo quiero ejecutar 1 llamada de servicio web cuando el usuario termine de escribir.
La forma en que estoy lograr esto es así:
que tienen una variable miembro que mantiene una AsyncTask. Cuando el texto en EditText cambia, la AsyncTask se dispara. Dentro de doInBackground(), se golpea una llamada a Thread.sleep(). Este período de suspensión es esencialmente un temporizador esperando para ver si el usuario escribe algo más. Después de la llamada de espera, la llamada al servicio web se realiza si la AsyncTask no se ha cancelado. Si el usuario escribe otra letra, se llama a cancel() en AsyncTask (para evitar que se llame al servicio web), la variable miembro que contiene AsyncTask se establece en nulo y se crea una nueva instancia de AsyncTask.
Tengo algunas preguntas aquí: ¿Tengo pérdida de memoria? ¿Esto es particularmente malo de alguna manera? Entiendo que puede que no sea lo más eficiente, ¿pero voy a ralentizar seriamente el teléfono de alguien? ¿Hay una mejor manera de hacer esto?
private SearchTask mSearchTask = null;
...
mSearchText.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Auto-generated method stub
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// Auto-generated method stub
}
public void afterTextChanged(Editable s) {
if (s != null && s.length() > 0) {
// stop any current search thread
if (mSearchTask != null && !mSearchTask.isCancelled()) {
mSearchTask.cancel(false);
}
// search for products
SearchCriteria crit = new SearchCriteria();
crit.strSearchWord = mSearchText.getText().toString().trim();
mSearchTask = null;
mSearchTask = new SearchTask();
mSearchTask.execute(crit);
}
}
});
...
private class SearchTask extends AsyncTask<SearchCriteria, Integer, Boolean> {
protected Boolean doInBackground(SearchCriteria... params) {
SearchCriteria crit = null;
if (params.length > 0) {
crit = params[0];
if (crit != null) {
try {
Thread.sleep(1000L);
if (!isCancelled()) {
// perform search
return true;
}
}
catch(Exception e) {
}
}
}
return false;
}
protected void onPostExecute(Boolean success) {
if (success != null && success == true) {
// do something
}
else {
// do something else
}
}
}
Aconsejaría esto, usar AsyncTask es más seguro que usar Runnables y tener que manejar los hilos por su cuenta. – blindstuff
He usado este método anteriormente sin problemas ni pérdida de memoria. Fuera de interés, ¿qué problemas pueden surgir al usar este método? – Martyn
No me refiero a que esté mal en absoluto. AsyncTask es justo lo que el equipo de Android diseñó para que no tengas que usar Handlers y administrar varios hilos al mismo tiempo. Su método funciona, pero tiene herramientas para facilitar su uso. – blindstuff