android - Inicie IntentService desde Activity y actualice Activity cuando IntentService finalice
multithreading android-intent (5)
Creo que el autobús del evento es el camino a seguir. Comunicación entre procesos simple y efectiva.
En mi aplicación Android, tengo una vista de lista simple con adaptador. Hay una gran consulta que es llenar la vista de lista con datos. Así que lo puse en un IntentService que se ejecuta en otro hilo.
IntentService normalmente se ejecuta por separado, solo, para consultar algunos datos e insertarlos en la base de datos SQLite.
Pero ahora me gustaría tener la siguiente posibilidad:
- La actividad inicia IntentService con startService ().
- IntentService hace su trabajo pesado.
- Cuando se finaliza el servicio de intención, debe informar a la actividad sobre el resultado para que la actividad se pueda actualizar para mostrar los datos nuevos.
es posible? Leí muchas preguntas aquí en Stack Overflow sobre este tema. Pero en cada pregunta, había otra solución. Entonces quiero preguntarles a todos: ¿Cuál solución es la mejor para mi propósito?
- Enlazar el servicio intencionado a la actividad no parece ser la mejor solución ya que puede haber conflictos con los cambios de configuración de la actividad, etc. ¿Correcto?
- Esta publicación de blog sugiere usar AIDL con Parcelables, lo que me parece muy complejo. Hay una manera más fácil, ¿no?
- Se podría configurar un receptor de difusión en la actividad y activar esta transmisión en el servicio de intención cuando se termine.
- Algunas personas dicen que debes usar createPendingResult () para pasar PendingIntent a IntentService. Si IntentService encuentra ese PendingIntent en sus extras, usa esto para desencadenar onActivityResult () en la Actividad. ¿Es esta la manera de elegir?
Cuando IntentService finaliza, debe usar LocalBroadcastManager para enviar un intento a cualquier actividad registrada.
IntentService contendrá un código como este:
private void sendBroadcast() {
Intent intent = new Intent("myBroadcastIntent");
intent.putExtra("someName", someValue);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
La actividad que recibe la notificación contendrá un código como este:
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String someValue = intent.getStringExtra("someName");
// ... do something ...
}
};
LocalBroadcastManager.getInstance(this)
.registerReceiver(receiver, new IntentFilter("myBroadcastIntent"));
}
Para obtener más información, consulte la publicación del blog Uso de LocalBroadcastManager en las comunicaciones de servicio a actividad .
Ninguna de las otras respuestas hace referencia a la documentación oficial de Android
https://developer.android.com/training/run-background-service/report-status.html
que indica claramente que para la comunicación Activity-IntentService "La forma recomendada para enviar y recibir el estado es usar un LocalBroadcastManager, que limita la difusión de los objetos de intención a los componentes en su propia aplicación".
Sugeriría usar un Receptor de Transmisión en The Activity esperando el resultado. Su Servicio solo usaría sendBroadcast
con un Intent
personalizado.
Como ejemplo, uso un ResultReceiver para llamar a notifyDataSetChanged()
en el adaptador de mi Activity
(que extiende ListActivity
). Se puede adaptar para hacer lo que necesites.
Código del receptor de resultados:
public class MyResultReceiver extends ResultReceiver {
private Context context = null;
protected void setParentContext (Context context) {
this.context = context;
}
public MyResultReceiver(Handler handler) {
super(handler);
}
@Override
protected void onReceiveResult (int resultCode, Bundle resultData) {
// Code to process resultData here
((BaseAdapter) ((ListActivity)context).getListAdapter()).notifyDataSetChanged();
}
}
Código de MyActivity:
public class MyActivity extends ListActivity {
private MyResultReceiver theReceiver = null;
...
private void callService () {
theReceiver = new MyResultReceiver(new Handler());
theReceiver.setParentContext(this);
Intent i = new Intent("com.mycompany.ACTION_DO_SOMETHING");
// Code to define and initialize myData here
i.putExtra("someData", myData);
i.putExtra("resReceiver", theReceiver);
startService(i);
}
}
Código de intención de servicio:
Bundle resultBundle = new Bundle();
ResultReceiver resRec = intent.getParcelableExtra("resReceiver");
// Do some work then put some stuff in resultBundle here
resRec.send(12345, resultBundle);