2010-11-24 2 views
1

Je suis un noob android qui cherche quelques conseils sur la façon d'utiliser correctement un service dans Android. Je construis une application qui va se connecter à un serveur sur Internet pour obtenir un flux de données via TCP. Ces données doivent ensuite être envoyées à un autre périphérique connecté via un port série Bluetooth. Je veux que cela continue à fonctionner en arrière-plan pendant que l'utilisateur regarde une activité différente.Conception de services Android - commencez avec l'activité ou seulement si nécessaire?

L'application sera un client NTRIP, qui récupère les données de correction RTK en temps réel sur Internet et les envoie à un récepteur GPS RTK auquel je me connecte via bluetooth. Le débit de données sera d'environ 500 octets/seconde. L'interface utilisateur est un bouton unique pour connecter ou déconnecter le flux de données et du texte pour montrer l'état du récepteur GPS. Il y a aussi quelques paramètres qui devront être configurés par l'utilisateur tels que l'IP/le port du serveur auquel se connecter et le périphérique Bluetooth avec lequel communiquer.

Je pense que j'ai besoin que l'activité principale génère un service local, puis que le service génère un thread pour le flux TCP et un autre thread pour la connexion bluetooth. Est-ce que ça sonne bien?

Quel est le meilleur modèle pour le service dans ce scénario? -Démarre (lier) le service chaque fois que l'activité démarre et que le bouton de connexion/déconnexion envoie des commandes au service pour démarrer/arrêter les threads. Si je vais cette route, le service continuera à fonctionner après que l'utilisateur se déconnecte et se rende à une autre application. Le service aurait besoin d'un temporisateur d'inactivité pour se terminer.

-Démarre et arrête le service lorsque l'utilisateur appuie sur le bouton de connexion/déconnexion. Le service s'exécute uniquement lorsque les données sont en mouvement. Si je fais cela, l'activité devra voir si le service est en cours d'exécution au démarrage de l'activité, afin de savoir s'il doit se lier au service ou dire à l'utilisateur que le lien est déconnecté.

Merci.

Répondre

1

J'irais avec votre deuxième option. Vérifier si un service est en cours ou non est une tâche facile et vous ne consommerez pas de temps de traitement inutile, ce qui sera meilleur pour la vie de la batterie. Ce n'est pas parce que vous pouvez exécuter un service pendant longtemps en arrière-plan que vous devez le faire également. Du moins pas tout le temps.

0

Comme Android prend en charge plus d'un point d'entrée dans l'application, vous pouvez définir deux points d'entrée dans le fichier Manifest.xml. <category android:name="android.intent.category.LAUNCHER" /> définit que cette classe peut être démarrée à partir du lanceur. Je suppose que cela fonctionnerait aussi pour un service. Je ferais deux points d'entrée. Celui qui engendre l'activité en premier et donne à l'utilisateur un certain contrôle de configuration. Et un autre qui engendre simplement le service.

Comme vous n'avez aucun contrôle sur la durée de vie d'une activité, je ne suggère pas de faire quoi que ce soit qui ne devrait pas être terminé par le système. Si vous avez un appel entrant, votre activité va simplement mourir. Si l'utilisateur démarre le service, vous pouvez créer un widget avec le bouton. Si l'utilisateur démarre l'activité, vous pouvez démarrer le service et le widget. Et si l'utilisateur démarre le widget, l'utilisateur décide, ce qui devrait arriver avec le service.

+0

Partiellement faux et l'autre partie est totalement confuse et pas claire peut-être même mal aussi. –

0

Je ne suis pas un programmeur Java ou Android alors prenez ce que je dis avec un grain de sel. La manière normale de gérer les E/S bloquantes en Java consiste à utiliser des threads. Il semble que le flux de données soit unidirectionnel mais pour une flexibilité maximale, je créerais 3 threads, un pour l'interface utilisateur, un pour la connexion TCP et un pour la connexion bluetooth.La communication entre l'interface utilisateur et deux threads de travail peut être effectuée en utilisant des variables partagées (attention à la synchronisation, aux conditions de course, etc.). Je transmettrais les données NTRIP de données à l'autre travailleur en utilisant une structure de données de file d'attente multi-thread.

Le thread de travail pour les données NTRIP serait à peu près:

while (app running) { 
    if (connection enabled) { 
     if (not connected) { 
     c = connect to remote 
     } 
     data = get data from c 
     queue.put(data) 
     if (options reconfigured) { 
     close c 
     } 
    } 
} 

Pour le fil Bluetooth:

while (app runnning) { 
    data = queue.get() 
    if (UI settings changed and connected) { 
     close connection 
    } 
    if (not connected) { 
     c = connect to remote 
    } 
    send data over connection 
} 

Dans l'état normal, les travailleurs bloquent sur IO et consommeront essentiellement pas de temps CPU. Basé sur mon expérience, je vous recommande d'écrire votre code pour gérer les erreurs de communication. Pour que votre code fonctionne bien dans le monde réel, vous devez gérer les connexions de fermeture, de suspension, etc. Le rendre robuste sera probablement la partie la plus longue du développement.