¿Cómo regresar resultados de un IntentService a una Actividad?

Estoy usando un IntentService para manejar las comunicaciones de red con un servidor a través de JSON. La parte JSON / servidor funciona bien, pero tengo problemas para volver a obtener los resultados donde se necesitan. El siguiente código muestra cómo estoy comenzando el servicio de bash desde dentro de OnClick (), y luego hago que el servicio actualice una variable global para retransmitir los resultados a la actividad principal.

public class GXActivity extends Activity { private static final String TAG = "GXActivity"; @Override public void onCreate(Bundle savedInstanceState) { // === called when the activity is first created Log.i(TAG, "GXActivity Created"); super.onCreate(savedInstanceState); setContentView(R.layout.start); View.OnClickListener handler = new View.OnClickListener() { public void onClick(View v) { // === set up an application context to hold a global variable // === called user, to contain results from the intent service GXApp appState = ((GXApp) getApplicationContext()); User user = new User(-1); // initialize user id to -1 appState.setUser(user); // === next start an intent service to get JSON from the server; // === this service updates the user global variable with // === results from the JSON transaction Intent intent = new Intent(this, GXIntentService.class); startService(intent); // === check app context for results from intent service appState = ((GXApp) getApplicationContext()); if (appState.getUser().getId() != -1)... } } } } 

El problema que tengo es que el servicio intencionado que analiza el JSON no se invoca hasta que se completa onCreate (), por lo que mi código que busca los resultados se bloquea al buscar resultados no inicializados.

¿Qué debo hacer de manera diferente para que se llame al servicio de intención antes de verificar los resultados? ¿Funcionaría si sacara el oyente click de la función onCreate ()? ¿Hay otro / mejor para estructurar este código? Muchas gracias.

Debería considerar crear su propia subclase ResultReceiver en su actividad. ResultReceiver implementa Parcelable por lo que puede pasarse de su Activity a su Service como un extra en el Intent .

Tendrás que hacer algo como esto:

  1. Implemente una subclase de ResultReceiver dentro de su clase de actividad. El método clave para implementar es onReceiveResult() . Este método le proporciona un Bundle de datos de resultados que pueden usarse para pasar cualquier información que esté recuperando en su Service . Simplemente descomprima los datos que necesita y úselos para actualizar su actividad.

  2. En su actividad, cree una nueva instancia de su ResultReceiver personalizado y agréguelo a la Intent que usa para comenzar su servicio.

  3. En el método onStartCommand() su Service , recupere el ResultReceiver transferido en el Intent y almacénelo en una variable miembro local.

  4. Una vez que su Service complete su trabajo, haga que llame a send() en el ResultReceiver pasando los datos que desea devolver a la actividad en un Bundle .

Este es un patrón bastante efectivo y significa que no está almacenando datos en desagradables variables estáticas.

Hay muchas maneras de hacer cosas en segundo plano obteniendo un resultado (AsyncTask, enlazar una actividad a un servicio …), pero si quieres mantener el código de tu servicio de intendencia puedes simplemente:

1- envía un bash de transmisión (que contiene el estado en sus datos extendidos) al final del trabajo en su IntentService

2- implementar un LocalBroadcastReceiver en su actividad que consume los datos de la intención

Esta es también la forma recomendada en la documentación oficial (si desea mantener su IntentService):

https://developer.android.com/training/run-background-service/report-status.html

Si todo lo que necesita hacer es obtener un JSON del servidor sin bloquear el hilo de la interfaz de usuario, puede ser más simple usar AsyncTask .

Puedes usar la biblioteca de Otto . Otto es un proyecto de código abierto diseñado para proporcionar una implementación de bus de evento para que los componentes puedan publicar y suscribirse a eventos.