2010-11-04 7 views
1

J'ai créé une classe qui est une extension de Thread. Cette classe frappe un service Web et jette des données à l'écran. Je ne me soucie pas de la persistance de ces données (l'écran affiche les résultats de la recherche).Tuer des threads

Actuellement, l'utilisateur tape simplement dans un EditText et clique sur un bouton de recherche. Je voudrais supprimer le bouton de recherche et implémenter quelque chose de similaire à la recherche instantanée de Google, où, au fur et à mesure que vous tapez, les résultats de la recherche sont mis à jour.

Cela signifie que lorsque l'utilisateur tape, les paramètres de recherche changent. Je veux être en mesure de tuer le thread en cours d'exécution (si un est en cours d'exécution) et générer un nouveau avec la nouvelle chaîne de recherche. Comment cela peut il etre accompli? Puis-je le faire avec Thread ou dois-je utiliser un nouvel objet?

+0

Ce n'est pas quelque chose qui devrait arriver dans un appareil mobile. Vraisemblablement vous êtes sur 3g et pas de wifi et cela pourrait prendre un temps long pour même 1 résultat de recherche. Vous devez mettre en cache les résultats de recherche de toutes les combinaisons possibles que l'utilisateur pourrait taper. C'est insensé. Selon les données, vous voudrez probablement simplement obtenir toutes les données à la fois au démarrage, puis les rechercher localement en utilisant la saisie semi-automatique comme mentionné ci-dessous. Si vos données sont des pages Web, n'y pensez même pas. – Falmarri

+0

Les données recherchées pour une liste une liste de mots. Il renvoie, au plus, 25 mots. Lorsque vous tapez 'w', le service Web demande des mots commençant par 'w'. Si vous tapez 'wi', le service Web demande des mots commençant par 'wi'. Ce que je voudrais accomplir, c'est que si l'appel de service Web pour 'w' est toujours actif lorsque l'utilisateur tape 'i', il l'annule et tente l'appel de service Web pour 'wi'. En outre, j'ai placé un sommeil de 2 secondes avant que le service Web soit appelé; donc si l'utilisateur tape 'w' puis 'wi' dans les 2 secondes, aucune bande passante n'a été utilisée car le premier appel n'est jamais sorti. – Andrew

+0

Les appels de service Web se produisent dans les threads; Donc, en arrêtant l'appel de service Web, je veux dire en réalité d'arrêter le fil qui le contient. – Andrew

Répondre

2

Ceci est plus difficile que de simplement tuer un fil. Vous pouvez appeler interrupt() sur le thread, mais le thread devra vérifier son statut d'interruption périodiquement et s'auto-terminer.

Deuxièmement, vous ne voulez pas démarrer un thread immédiatement sur un utilisateur qui tape.Vous allez rapidement submerger le système avec la fonte du fil. Implémentez une période d'attente de 100 à 200 millisecondes avant d'effectuer la recherche afin de pouvoir être raisonnablement certain que l'utilisateur a fini de taper. Le serveur de Google peut gérer la charge, mais le combiné ne pourra pas le faire.

EDIT: pour développer mon premier point, les threads peuvent être difficiles à annuler. Dans ce cas, le thread de répartition des événements doit indiquer au thread en cours d'exécution qu'il doit s'arrêter. Vous pouvez utiliser la fonctionnalité interrupt intégrée dans les threads, mais elle a tendance à être sensible, comme indiqué par this article. Au lieu de cela, je voudrais simplement une variable boolean qui peut être définie sur cancelled par un thread externe. L'astuce (comme montré dans ce lien) sera que vous aurez besoin de vérifier périodiquement si le thread a été annulé, et si c'est le cas, vous devrez annuler manuellement.

Le prochain problème que vous rencontrerez est si un appel Web a déjà été fait à un serveur externe. Il bloquera dans ce fil jusqu'à ce qu'il revienne et le fil ne sera pas capable de se tuer. Cela pourrait prendre plusieurs secondes. Alors jouons-en - si un utilisateur tape un caractère et que le délai expire pour une raison quelconque et qu'un appel Web est effectué, l'utilisateur tape un autre caractère où le délai expire et un autre appel Web est effectué ? Si vos appels Web prennent 5 secondes, le premier thread continuera à s'exécuter, même si le thread d'envoi d'événement l'annule, pendant au moins 5 secondes. Vous avez maintenant deux threads faisant des appels Web.

Maintenant, développez cela. Que faire si un utilisateur fait cela et fait 4 ou 5 threads? C'est là que vous surchargez les ressources de votre téléphone. Je ne vous dis pas de ne pas poursuivre dans cette voie, en essayant simplement de souligner les problèmes potentiels que pose le territoire.

+0

Eh bien ce que j'avais l'intention de faire est, quand l'utilisateur tape un caractère, tout thread en cours d'exécution est annulé, les résultats de recherche sont effacés et un nouveau thread avec le nouveau paramètre de recherche est lancé. Quand un thread est lancé, il attend 2-3 secondes avant de frapper le webservice. Cela donne à l'utilisateur le temps de taper un autre caractère et d'annuler la recherche précédente avant d'utiliser la radio. Le problème est que je ne sais pas par programme comment faire cela (la partie annuler). – Andrew

+0

Merci pour votre réponse mise à jour. – Andrew

0

La création de fil est une opération très consommatrice. Je recommande donc d'avoir un thread qui appellera par la suite webservices avec de nouvelles chaînes de recherche.

0

Ce que vous voulez dire est Auto Complete. Je ne pense pas que vous ayez besoin de démarrer quelques threads pour gérer ça. Travailler avec Android Auto Complete et utiliser AutoCompleteTextView.

En outre, il n'est pas recommandé d'utiliser des threads en sous-classant le thread Java ou en implémentant l'interface. Vous pouvez utiliser AsyncTask pour effectuer des opérations longues en arrière-plan.

+0

Non, je ne veux pas dire Auto Complete. Ce que je voulais dire était la recherche instantanée. Lorsque l'utilisateur saisit EditText, les résultats de la recherche s'affichent dans la mise à jour de la liste. Je vais essayer d'utiliser AsyncTask au lieu de Thread, bien que tout type d'opération asynchrone me permette de faire ce que je veux, c'est ce que je devrai utiliser. – Andrew

2

Utilisez le widget AutoCompleteTextView. prélecture vos indications de recherche à partir de votre service Web pour les charger dans la matrice de saisie semi-automatique et définir son adaptateur. utilisez éventuellement un adaptateur de curseur personnalisé en fonction de la complexité de vos conseils.

quelque chose comme:

AutoCompleteTextView inputSearch; 
String[] autocompleteArray = new String[size of prefetched items]; 
//fill autocompleteArray with webservice data 

inputSearch = (AutoCompleteTextView)findViewById(R.id.inputSearch); 
searchAdapter = new ArrayAdapter<String>(context, R.layout.autcomplete_dropdown, autocompleteArray); 
inputSearch.setAdapter(searchAdapter); 

R.layout.autocomplete_dropdown pourrait ressembler à:

<?xml version="1.0" encoding="utf-8"?> 
<TextView 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/name" 
    android:singleLine="false" 
    android:textSize="15sp" 
    android:paddingLeft="3dip" 
    android:paddingRight="3dip" 
    android:paddingTop="15dip" 
    android:paddingBottom="15dip" 
    android:textColor="#000000" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" /> 

faire votre recherche dans l'application, la taille est le contenu que vous sera la recherche? pré-charger toutes les données dans sqlite et vérifier les données mises à jour sur le web de temps en temps peut-être peut-être? Autrement, je dirais que vous devriez limiter le nombre de fois que votre application essaie de démarrer un thread. configuration une sorte de minuterie qui: voir si ...

  1. un fil travaille déjà
  2. l'entrée a changé depuis la dernière fois ou a une valeur de recherche non vide
  3. l'utilisateur est même sur l'écran de recherche

si tout est OK, démarrer un fil pour obtenir des résultats

juste une pensée , n'ont pas essayé ceci

+0

Je suis désolé, je n'ai peut-être pas clarifié mes intentions. Je ne cherche pas à recréer la fonctionnalité d'auto-complétion de Google. Je cherche à recréer la recherche instantanée de Google. Lorsque l'utilisateur tape un mot de recherche dans EditText, les résultats sont mis à jour dans la liste. – Andrew