Comment puis-je mettre à jour l'information dans une activité Android d'un service d'arrière-plan

StackOverflow https://stackoverflow.com/questions/2468874

Question

Je suis en train de créer une simple application Android qui a une ActivityList d'information, lorsque l'application démarre, je prévois de lancer un service qui sera calcule en permanence les données (il va changer) et je veux que le ActivityList être en synchronisation avec les données que le service est le calcul de la durée de vie de l'application.

Comment puis-je configurer mon activité à l'écoute du service? Est-ce la meilleure façon d'aborder ce problème?

Par exemple, si vous imaginez une liste des cours boursiers -. Les données seraient être changés régulièrement et doivent être en phase avec le (dans mon cas) de service qui calculait / récupérer les données en permanence

Merci d'avance

Était-ce utile?

La solution

  

Comment puis-je configurer mon activité à   l'écoute du service? Est-ce le   meilleure façon d'aborder ce problème?

Vous disposez de trois grandes options, comme je le vois:

  1. Polling. Le Activity demande périodiquement à la Service pour les données les plus récentes. À mon humble avis, cette option est nul, mais il est certainement possible.

  2. Callbacks. Par la réponse de Jax, le Activity enregistre un objet de rappel ( « observateur ») avec le Service. La Service invoque une méthode sur la fonction de rappel lorsque les changements de données, ce qui met à jour l'interface utilisateur. Vous pouvez voir un exemple d'utilisation que d'un Service .

  3. Diffusion Intents. La Service diffuse une Intent via sendBroadcast() sur un changement de données. Le Activity enregistre un BroadcastReceiver en utilisant registerReceiver(), et que BroadcastReceiver est informé d'une émission entrante. Cela déclenche la Activity pour charger les données les plus récentes de la Service, ou peut-être juste pour obtenir les données les plus récentes sur extras dans la Intent de diffusion. Vous pouvez voir un exemple d'utilisation de cette technique avec un Service .

Autres conseils

Ce son comme un bon candidat pour le motif d'observateur. Fondamentalement, votre activité (The Observer) s'inscrira avec le service d'arrière-plan (Le Observable) et vous pouvez pousser ou tirer des données de votre activité. Votre observateur dans ce cas sera votre activité et la Observable sera votre service.

Si vous ne savez rien sur les modèles de conception BUY "Head First Design Patterns", il est facile à lire et est plein de grande information.

PS. Je lis maintenant

Je suis vraiment, vraiment se demander pourquoi personne n'a mentionné une approche simple en utilisant un EventBus par quelque bibliothèque. Ceci est bien sûr si vous ne l'utilisez RX. Mon préféré est EventBus par GreenRobot. https://github.com/greenrobot/EventBus

Avec seulement quelques lignes de code, et aucune interface. Feu d'un événement, et écouter où vous voulez. Il est découplé, il est thread-safe, et il ne plantera pas votre application.

Vous devez utiliser bindService () pour lier l'activité avec un service en cours d'exécution et de communiquer avec elle.

public class BindingActivity extends Activity {
YourService mService;
boolean mBound = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

@Override
protected void onStart() {
    super.onStart();
    // Bind to Your Service
    Intent intent = new Intent(this, YourService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
    super.onStop();
    // Unbind from the service
    if (mBound) {
        unbindService(mConnection);
        mBound = false;
    }
}

/** Called when a button is clicked (the button in the layout file attaches to
  * this method with the android:onClick attribute) */
public void onButtonClick(View v) {
    if (mBound) {
        // Call a method from your Service.
        // However, if this call were something that might hang, then this request should
        // occur in a separate thread to avoid slowing down the activity performance.
        int num = mService.getRandomNumber();
        Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
    }
}

/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className,
            IBinder service) {
        // We've bound to the running Service, cast the IBinder and get instance
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
 };
}

et votre service comme:

public class LocalService extends Service {
    // Binder given to clients
   private final IBinder mBinder = new LocalBinder();
   // Random number generator
   private final Random mGenerator = new Random();

/**
 * Class used for the client Binder.  Because we know this service always
 * runs in the same process as its clients, we don't need to deal with IPC.
 */
public class LocalBinder extends Binder {
    LocalService getService() {
        // Return this instance of LocalService so clients can call public methods
        return LocalService.this;
    }
}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}

/** method for clients */
public int getRandomNumber() {
  return mGenerator.nextInt(100);
  }
}

Vous aurez une course de fil d'arrière-plan qui calcule les changements dans la liste. Ce fil a besoin maintenant une possibilité d'informer l'interface graphique que la liste a été mise à jour.

Vous pouvez utiliser une sorte de ArrayAdapter pour obtenir les données dans le ListView. Le ArrayAdapter a une méthode appelée adpater. notifyDataSetChanged () chaque fois que vous appelez cette méthode, l'adaptateur voir que les données correspondantes ont changé et informer le listview qu'il doit mettre à jour la possibilité suivante.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top