2 votes

Passage d'un paramètre d'une activité à un thread dans un service

J'ai une activité dans laquelle je lance un service, par exemple je staty MyService comme :

Intent intent1 = new Intent(this, MyService.class);
startService(intent1);

Dans mon service, je crée un thread et je l'exécute. Voici une partie de mon code :

public class MyService extends Service {
...
@Override
public void onStart(Intent intent, int startid) {
    Thread mythread= new Thread() {
        @Override
        public void run() {
            while(true)
            {
              ...
            }
        }
    };
    mythread.start();
}

}

Maintenant, au lieu de while(true) Je veux utiliser while(a)a est un paramètre qui est passé de mon activité à ce service. Veuillez noter que mon activité est une classe différente de mon service. Comment cela peut-il être fait ? Veuillez montrer un exemple spécifique avec quelques codes.

2voto

James McCracken Points 4181

Vous pouvez accéder à votre service en vous liant à lui. Modifiez votre classe de service pour qu'elle renvoie un IBinder onBind()

public class MyService extends Service {

    private static final String TAG = MyService.class.getSimpleName();
    private final IBinder binder = new ServiceBinder();
    private boolean a;

    @Override
    public IBinder onBind( Intent intent ) {

        return binder;
    }

    @Override
    public int onStartCommand( Intent intent, int flags, int startId ) {

        return super.onStartCommand( intent, flags, startId );
    }

    @Override
    public void onCreate() {

        super.onCreate();
    }

    public class ServiceBinder extends Binder {

        public MyService getService() {

            return MyService.this;
        }
    }

    public void setA(boolean a) {

        this.a = a;
    }
}

Maintenant, dans votre activité, vous devez gérer l'attachement et le désattachement à votre service. Dans cet exemple, le service reste en place, que vous soyez lié ou non. Si ce n'est pas la fonctionnalité que vous voulez, vous pouvez simplement ne pas appeler startService(...) :

public class MyActivity extends Activity {

    //...
    private MyService myService;
    private boolean bound;

    @Override    
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        Intent intent = new Intent( this, MyService.class );
        startService( intent );
        doBindService();
    }

    private final ServiceConnection serviceConnection = new ServiceConnection() {

        public void onServiceConnected( ComponentName className, IBinder service ) {

            myService = ( (MyService.ServiceBinder) service ).getService();
            bound = true;
        }

        public void onServiceDisconnected( ComponentName className ) {

            myService = null;
            bound = false;
        }
    };

    void doBindService() {

        boolean bound = bindService( new Intent( this, MyService.class ), serviceConnection, Context.BIND_AUTO_CREATE );
        if ( bound ) {

            Log.d( TAG, "Successfully bound to service" );
        }
        else {

            Log.d( TAG, "Failed to bind service" );
        }
    }

    void doUnbindService() {

        unbindService( serviceConnection );
    }
}

Maintenant, vous avez une référence à votre service lié dans votre activité et vous pouvez simplement appeler myService.setA(true) pour définir votre paramètre.

1voto

Mr.Me Points 4020

Au lieu d'appeler le service de démarrage, utilisez bindService qui vous permet d'accéder à l'objet service.

Voici un sujet détaillé à ce sujet Doc Android

Une fois que votre activité est liée à votre service, vous pouvez appeler depuis votre activité n'importe quelle méthode de votre service. Vous pourriez faire quelque chose comme ceci :

.... Activity Code
          mService.stopThread();

..... Service Code
         public void stopThread(){
             a = false;
         }

Voici comment je procède :

Dans votre activité, lorsque vous essayez de vous connecter au service :

    Intent serviceIntent = new Intent(this, MyService.class);
    bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE);

private ServiceConnection serviceConnection  = new ServiceConnection(){

    @Override
    public void onServiceConnected(ComponentName arg0, IBinder arg1) {
        mService = (MyService) ((MyService.LocalBinder) arg1)
                .getService();

    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        // TODO Auto-generated method stub
    }

};

Et à mon service : J'ajoute ce membre

private LocalBinder mBinder;

    protected void onCreate(Bundle bundle) {
               super.onCreate(bundle);
               mBinde = new LocalBinder();
         }

et cette classe :

public class LocalBinder extends Binder {
    public MyService getService() {
        // Return this instance of LocalService so clients can call public
        // methods
        return MyService.this;
    }
}

1voto

Sunny Points 3995

Utilisation simple

Intent intent1 = new Intent(this, MyService.class);
intent1.putExtra("key",value);
startService(intent1);

et le récupérer en service en utilisant

 a = intent.getStringExtra("key");// or Int, ArrayList whatever

1voto

iTech Points 7948

Je pense que la liaison de service sera inutile dans votre cas, puisque vous avez une interaction simple entre l'activité et votre service.

Comme suggéré, vous pouvez passer les paramètres en utilisant startService . Une autre solution consiste à utiliser LocalBroadcast, voici un exemple

En ce qui concerne votre fil de discussion, vous devrez peut-être le définir comme une classe distincte dans votre service. pas une classe anonyme, par exemple :

class MyThread extends Thread{
   private boolean a = true;
   public void setA(boolean a){
      this.a = a;
   }
   public void run() {
        while(a)
        {
          ...
        }
    }

}

0voto

Zedot Points 41

Si j'ai bien compris la question, c'est ce dont vous avez besoin :

Dans la classe d'activité, juste avant d'appeler startService(), ajoutez cette ligne :

intent1.putExtra("keyName","keyValue");

Dans le service, dans onStartCommand() :

Bundle extras = intent.getExtras();
String param = extras.getString("keyName");

param contiendra votre paramètre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X