Запустите IntentService из Activity и обновите Activity, когда IntentService закончен

В моем приложении Android у меня есть простой вид списка с адаптером. Есть тяжелый запрос, который должен заполнить представление списка данными. Поэтому я помещаю его в IntentService, который работает в другом потоке.

IntentService обычно запускается отдельно самостоятельно, просто для запроса некоторых данных и вставки его в базу данных SQLite.

Но теперь я хотел бы иметь следующую возможность:

  1. Действие запускает IntentService с помощью startService ().
  2. IntentService делает свою тяжелую работу.
  3. Когда IntentService будет завершен, он должен сообщить об этом действию, чтобы активность могла быть обновлена, чтобы показать новые данные.

Это возможно? Я прочитал много вопросов здесь о переполнении стека по этой теме. Но в каждом вопросе было другое решение. Поэтому я хочу спросить вас всех: какое решение лучше для моей цели?

  • Привязывание IntentService к Activity не кажется лучшим решением, поскольку могут возникнуть конфликты с изменениями конфигурации активности и т. Д. Правильно?
  • В этом сообщении в блоге предлагается использовать AIDL с Parcelables, что звучит очень сложно для меня. Есть более простой способ, не так ли?
  • Можно было настроить широковещательный приемник в своей деятельности и запустить эту трансляцию в IntentService, когда она будет завершена.
  • Некоторые люди говорят, что вы должны использовать createPendingResult () для передачи PendingIntent в IntentService. Если IntentService обнаруживает, что PendingIntent в своих дополнениях, он использует это для запуска onActivityResult () в Activity. Это выбор?

В качестве примера я использую ResultReceiver для вызова notifyDataSetChanged() на адаптере моей Activity (который расширяет ListActivity ). Он может быть адаптирован для того, чтобы делать все, что вам нужно.

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

Код 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); } } 

Код IntentService:

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

Когда IntentService завершает работу, он должен использовать LocalBroadcastManager для отправки намерения любой зарегистрированной активности.

IntentService будет содержать такой код:

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

Операция, получающая уведомление, будет содержать такой код:

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

Дополнительные сведения см. В сообщении блога. Использование LocalBroadcastManager в службе связи .

Ни один из других ответов не ссылается на официальную документацию по Android

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

Что ясно, что для взаимодействия Activity-IntentService «Рекомендуемым способом отправки и получения статуса является использование LocalBroadcastManager, который ограничивает использование объектов Intent компонентами в вашем собственном приложении»!

Я бы предложил использовать широковещательный приемник в ожидании результата. Ваша служба просто будет использовать sendBroadcast с пользовательским Intent .

Я думаю, что автобус событий – это путь. Простая и эффективная межпроцессная связь.