Domanda

Sto cercando di creare una semplice applicazione Android che ha un'ActivityList di informazioni, quando si avvia l'applicazione, ho intenzione di avviare un servizio che sarà calcolando costantemente i dati (che cambierà) e voglio l'ActivityList essere in sincronia con i dati che il servizio è il calcolo per la vita delle app.

Come faccio a impostare la mia attività ad ascoltare il servizio? È questo il modo migliore per affrontare questo problema?

Ad esempio, se si immagina un elenco dei prezzi delle azioni -. I dati sarebbero essere cambiati regolarmente e hanno bisogno di essere in sincronia con il (nel mio caso) Servizio che sta calcolando / recupero dei dati in continua

Grazie in anticipo

È stato utile?

Soluzione

  

Come faccio a impostare la mia attività di essere   ascoltando il servizio? E 'questo il   modo migliore per affrontare questo problema?

Sono disponibili tre opzioni principali, come la vedo io:

  1. Polling. Il Activity chiede periodicamente la Service per i dati più recenti. IMHO, questa opzione fa schifo, ma è certamente possibile.

  2. richiamate. Per la risposta di JAX, l'Activity registra un oggetto callback ( "osservatore") con la Service. Il Service invoca un metodo sul callback quando le modifiche dei dati, che a sua volta aggiorna l'interfaccia utente. Si può vedere un esempio di utilizzo che con un Service href="http://github.com/commonsguy/cw-andtutorials/tree/master/18-LocalService/" rel="noreferrer"> qui .

  3. Broadcast Intents. Il Service trasmette un Intent tramite sendBroadcast() su una modifica dei dati. Il Activity registra un BroadcastReceiver utilizzando registerReceiver(), e che BroadcastReceiver viene notificato di una trasmissione in entrata. Ciò fa scattare il Activity per caricare gli ultimi dati dal Service, o forse solo per ottenere i dati più recenti di extra in Intent trasmissione. Potete vedere un esempio di utilizzo di questa tecnica con un Service href="https://github.com/commonsguy/cw-omnibus/tree/master/Internet/Download" rel="noreferrer"> qui .

Altri suggerimenti

Questo suona come un buon candidato per il pattern Observer. Fondamentalmente la vostra attività (The Observer) si registrerà con il servizio in background (osservabile) e si può spingere o tirare i dati dalla vostra attività. Il tuo Observer in questo caso sarà la vostra attività e osservabile sarà il vostro servizio.

Se non sanno nulla di Design Patterns comprare "Head First Design Patterns", è facile da leggere ed è pieno di grandi informazioni.

PS:. Sto leggendo ora

Sono veramente, veramente chiedendo perché nessuno ha menzionato un approccio semplice utilizzando un EventBus con qualsiasi libreria. Questo è, naturalmente, se non si sta utilizzando RX. Il mio preferito è EventBus da GreenRobot. https://github.com/greenrobot/EventBus

Con solo un paio di righe di codice, e senza interfacce. Generare un evento, e ascoltare dove vuoi. Si è disaccoppiato, è thread-safe, e non andrà in crash l'applicazione.

È necessario utilizzare bindService () per associare l'attività con servizio in esecuzione e comunicare con esso.

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;
    }
 };
}

e il vostro servizio come:

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);
  }
}

Si avrà un thread in background in esecuzione che calcola i cambiamenti nella lista. Questo thread ora ha bisogno di una possibilità di notificare la GUI che l'elenco è stato aggiornato.

È possibile utilizzare una sorta di ArrayAdapter per ottenere i dati nel ListView. L'ArrayAdapter ha un metodo chiamato adpater. notifyDataSetChanged () ogni volta che si chiama questo metodo l'adattatore vedrà che i dati corrispondenti è cambiato e quindi notificare la listview che dovrebbe aggiornare alla prossima possibilità.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top