Start IntentService de Activité et rafraîchir Activité lorsque IntentService est terminé

Dans mon application Android, j'ai une simple liste avec un adaptateur. Il y a une requête lourde qui consiste à remplir la liste avec les données. Donc, je l'ai mis dans un IntentService qui s'exécute dans un autre thread.

L'IntentService fonctionne normalement séparément, uniquement pour interroger certaines données et l'insérer dans la base de données SQLite.

  • L'activité a tué / onCreate a appelé après avoir pris la photo par intention
  • L'intention de la caméra ou de la galerie détruit l'activité ancienne sur certains périphériques
  • Comment ouvrir un nouvel écran dans Android?
  • Accès à la base de données dans Android
  • Comment personnaliser le mécanisme de suggestion automatique "chips", tel qu'utilisé dans le domaine des destinataires de Gmail?
  • En appelant startIntentSenderForResult from Fragment (Android Billing v3)
  • Mais maintenant, j'aimerais avoir la possibilité suivante:

    1. L'activité démarre IntentService avec startService ().
    2. The IntentService fait son travail lourd.
    3. Lorsque le service Intent est terminé, il doit informer l'activité du résultat afin que l'activité puisse être actualisée pour afficher les nouvelles données.

    Est-ce possible? J'ai lu beaucoup de questions ici sur Stack Overflow sur ce sujet. Mais dans toutes les questions, il y avait une autre solution. Je souhaite donc vous poser la question suivante: quelle solution est la meilleure pour mon but?

    • Relier le service Intent à l'activité ne semble pas être la meilleure solution, car il peut y avoir des conflits avec les changements de configuration de l'activité, etc. Corrigez-vous?
    • Ce blog suggère d'utiliser AIDL avec Parcelables – ce qui me paraît très complexe. Il y a un moyen plus facile, n'est-ce pas?
    • On pourrait configurer un récepteur de diffusion dans l'activité et déclencher cette diffusion dans IntentService lorsqu'il est terminé.
    • Certaines personnes disent que vous devez utiliser createPendingResult () pour transmettre un PendingIntent au IntentService. Si l'IntentService trouve que PendingIntent dans ses extras, il utilise ceci pour déclencher onActivityResult () dans l'Activité. Est-ce la façon de choisir?

  • ANR dans l'utilisation aléatoire de l'application
  • Comment ouvrir une deuxième activité sur le bouton Cliquez sur le bouton dans l'application Android
  • Comment puis-je envoyer le contenu du contenu par courrier électronique?
  • L'activité a tué / onCreate a appelé après avoir pris la photo par intention
  • Terminer l'activité d'appel lorsque AsyncTask est terminé
  • SINGLE_TOP | CLEAR_TOP semble fonctionner à 95% du temps. Pourquoi les 5%?
  • 5 Solutions collect form web for “Start IntentService de Activité et rafraîchir Activité lorsque IntentService est terminé”

    Par exemple, j'utilise un ResultReceiver pour appeler notifyDataSetChanged() sur la carte de ma Activity (qui étend ListActivity ). Il peut être adapté pour faire tout ce dont vous avez besoin.

    Code ResultReceiver:

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

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

    Intent Code de service:

     Bundle resultBundle = new Bundle(); ResultReceiver resRec = intent.getParcelableExtra("resReceiver"); // Do some work then put some stuff in resultBundle here resRec.send(12345, resultBundle); 

    Lorsque l'IntentService est terminé, il devrait utiliser LocalBroadcastManager pour envoyer une intention à toute activité enregistrée.

    The IntentService contiendra un code comme celui-ci:

     private void sendBroadcast() { Intent intent = new Intent("myBroadcastIntent"); intent.putExtra("someName", someValue); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } 

    L'activité recevant la notification contiendra un code comme celui-ci:

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

    Pour plus de profondeur, consultez la publication du blog en utilisant LocalBroadcastManager en service aux communications d'activité .

    Aucune des autres réponses ne fait référence à la documentation officielle d'Android

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

    Cela indique clairement que pour la communication Activity-IntentService "La manière recommandée d'envoyer et de recevoir un statut est d'utiliser LocalBroadcastManager, ce qui limite l'émission des objets Intent aux composants de votre propre application"!

    Je suggérerais d'utiliser un récepteur de diffusion dans The Activity en attente du résultat. Votre service utiliserait simplement sendBroadcast avec une Intent personnalisée.

    Je pense que le bus d'événement est le chemin à parcourir. Communication interprocessus simple et efficace.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.