2011-02-28 5 views
25

Je suis nouveau à cette android. J'utilise un service pour faire un travail de fond. donc je commence le service de mon activité comme suit.Comment démarrer le service dans un nouveau fil dans android

 getApplicationContext().bindService(
     new Intent(getApplicationContext(), MyAndroidUpnpServiceImpl.class), 
     serviceConnection, 
     Context.BIND_AUTO_CREATE 
    ); 

mais le problème est que l'activité androïde est bloquée. jusqu'à ce que le service,

  onServiceConnected(ComponentName className, IBinder service){ ..} 

est appelé back.so j'ai cherché à ce sujet. Je suis venu pour savoir que je dois commencer mon service dans le nouveau fil. alors s'il vous plaît quelqu'un m'aider à faire cela.

Répondre

34

Pour créer et démarrer un nouveau thread, à l'intérieur d'une activité, vous pouvez dire:

Thread t = new Thread(){ 
public void run(){ 
getApplicationContext().bindService(
     new Intent(getApplicationContext(), MyAndroidUpnpServiceImpl.class), 
     serviceConnection, 
     Context.BIND_AUTO_CREATE 
    ); 
} 
}; 
t.start(); 

En outre, mettre en cache la valeur retournée par bindservice, le cas échéant, si vous avez besoin pour une utilisation ultérieure.

+0

Merci Samuh je vais vérifier cela ... – bHaRaTh

+1

salut Samuh son travail. maintenant il ne bloque pas mon activité jusqu'à ce que le service soit commencé .. merci beaucoup pour votre aide .. et j'ai une autre question.Je vais placer dans le prochain commentaire .. – bHaRaTh

+0

une fois que nous lierons le service de la première activité et nous faisons usage de ce service, nous allons le délier. Supposons donc dans ma prochaine activité si nous voulons utiliser le même service, si nous devons le lier à nouveau correctement, ou si je me trompe dans le processus. – bHaRaTh

1

Si quelqu'un qui lit ceci recherche une solution impliquant de maintenir le fil de l'interface utilisateur dans une course fluide, il vaut mieux vérifier la tâche AsyncTaskhere. Bravo.

+4

AsyncTask ne sera pas utile lorsque vous devez exécuter du code sans lancer une application. – Erol

+0

Je parle de garder le fil de l'interface utilisateur libre, je ne vois pas la connexion à ce que vous avez dit ... btw, un service est une partie de l'application, tout cela fonctionne sous le même processus. Peut-être que vous vouliez dire exécuter du code en dehors de l'activité? – gor

14

Toute solution qui utilise Threads, Runnables, AsyncTask ou autre avec un service aura un problème commun .

Le service bloquera l'activité d'appel jusqu'à ce que le service soit démarré. Et donc ne pas effectivement enfiler le Service dans certains cas.

La solution à ceci est d'utiliser la sous-classe IntentService.

Exemple de mise en œuvre:

public class MyCustomService extends IntentService 
{ 
    private DatabaseAdapter mAdapter; 

    public MyCustomService() { 
     super("MyCustomService"); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     super.onStartCommand(intent, flags, startId); 
     Toast.makeText(this, "MyCustomService Started", Toast.LENGTH_LONG).show(); 

     // Don't let this service restart automatically if it has been stopped by the OS. 
     return START_NOT_STICKY; 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) 
    { 
     Toast.makeText(this, "MyCustomService Handling Intent", Toast.LENGTH_LONG).show(); 
     // INSERT THE WORK TO BE DONE HERE 
    } 
} 

onCreate() et OnDestroy peuvent également être écrasées tant que super.onWhatever() est appelé à l'intérieur.

+2

Vous ne pouvez pas faire toutes les choses avec IntentService. Le service a sa propre utilisation. – Saty

3

Old question, mais je réponds parce que quelqu'un a attiré mon attention dans une autre question.

Le problème de l'OP était évidemment causé par le onBind(...) du service qui prend beaucoup de temps et bloque le thread principal. La solution correcte est ne faites pas cela. Le service doit être repensé afin que onBind(...) revienne rapidement. Comme presque tout le reste dans l'API Android, vous devez toujours appeler bindService(...) dans le fil de discussion principal.

La raison est que la sécurité des threads dans Java n'est pas seulement une question d'atomicité, mais aussi visibility. (Faites défiler jusqu'à la section de visibilité.) En général, vous devez toujours supposer que chaque API Java est pas thread sûr, sauf si elle est explicitement documentée autrement.

1

Je recommanderais d'utiliser un IntentService, car un IntentService s'exécute par défaut sur un thread distinct. Mais encore si votre classe de service étend son service puis utilisez ce code:

Thread thread = new Thread() { 
    @Override 
    public void run() { 
     startService(new Intent(getApplicationContext(), YourService.class)); 
    } 
}; 
thread.start(); 
Questions connexes