Pergunta

Estou tentando criar um aplicativo Android simples que tenha uma lista de atividades de informação, quando o aplicativo iniciar, pretendo iniciar um serviço que calcule constantemente os dados (ele estará mudando) e quero que a lista de atividades esteja sincronizada com o os dados que o serviço está calculando para a vida útil do aplicativo.

Como posso configurar minha atividade para ouvir o serviço? Esta é a melhor maneira de abordar esse problema?

Por exemplo, se você imaginar uma lista dos preços das ações - os dados estariam sendo alterados regularmente e precisariam estar sincronizados com o serviço (no meu caso) que está calculando/buscando os dados constantemente.

desde já, obrigado

Foi útil?

Solução

Como posso configurar minha atividade para ouvir o serviço? Esta é a melhor maneira de abordar esse problema?

Você tem três opções importantes, o que eu vejo:

  1. Votação. o Activity Periodicamente pergunta ao Service Para os dados mais recentes. IMHO, essa opção é péssima, mas é certamente possível.

  2. Retornos de chamada. Por resposta de Jax, o Activity registra um objeto de retorno de chamada ("observador") com o Service. o Service Invoca um método no retorno de chamada quando os dados mudarem, o que, por sua vez, atualiza a interface do usuário. Você pode ver um exemplo de usar isso com um Service aqui.

  3. Transmissão Intents. o Service transmite um Intent através da sendBroadcast() em uma mudança de dados. o Activity registra a BroadcastReceiver usando registerReceiver(), e essa BroadcastReceiver é notificado de uma transmissão recebida. Isso desencadeia o Activity para carregar os dados mais recentes do Service, ou possivelmente apenas para obter os dados mais recentes de extras na transmissão Intent. Você pode ver um exemplo de usar essa técnica com um Service aqui.

Outras dicas

Isso soa como um bom candidato para o padrão de observador. Basicamente, sua atividade (o observador) se registrará no serviço em segundo plano (o observável) e você pode pressionar ou extrair dados de sua atividade. Seu observador, neste caso, será sua atividade e o observável será o seu serviço.

Se você não sabe nada sobre os padrões de design, compre "Padrões de Primeiro Design da cabeça", é fácil de ler e está cheio de ótimas informações.

PS: Estou lendo agora.

Estou muito, realmente me perguntando por que ninguém mencionou uma abordagem simples usando um Eventbus por qualquer biblioteca. Obviamente, isso é se você não estiver usando o RX. Meu favorito pessoal é o Eventbus de GreenRobot.https://github.com/greenrobot/eventbus

Com apenas algumas linhas de código e sem interfaces. Demoie um evento e ouça onde quiser. É dissociado, é seguro e não travará seu aplicativo.

Você precisa usar o bindService () para vincular a atividade ao serviço em execução e se comunicar com ele.

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 seu serviço como:

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

Você terá um encadeamento de segundo plano em execução que calcula as alterações na lista. Este tópico agora precisa da possibilidade de notificar a GUI de que a lista foi atualizada.

Você pode usar algum tipo de Arrayadapter Para colocar os dados no ListView. O Arrayadapter tem um método chamado adpater.NotifyDataSetchanged () Toda vez que você chama esse método, o adaptador verá que os dados correspondentes foram alterados e notificarão o ListView que ele deve atualizar na próxima possibilidade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top