Обновление списка в фрагменте из широковещательного приемника

Мне нужно обновить список в фрагменте, если файл успешно загружается. Поэтому в диспетчере загрузки BroadcastReceiver я зарегистрирую этот новый широковещательный приемник:

Intent intent = new Intent();
intent.setAction("CONTENTS_NOTIFICATION");
context.sendBroadcast(intent);

И в моем фрагменте в onCreateView я добавляю следующий код для регистрации получателя:

IntentFilter filter = new IntentFilter("CONTENTS_NOTIFICATION");
getActivity().getApplicationContext().registerReceiver(myReceiver, filter);

то

private BroadcastReceiver myReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {

            SQLiteDatabase db = DatabaseManager.getInstance(getActivity()).getWritableDatabase();
              c = SelectedExperience.getSelectedExperiences(db);

              String id_esperienza = "Selected Experience";

              if (c.getCount() != 0) {
                  id_esperienza = c.getString(c.getColumnIndex(SelectedExperience.ID_ESPERIENZA));
              }

            populateListview(v, id_esperienza);

        }
    };

и в конце:

public void onDestroyView() {
      super.onDestroyView();
      getActivity().getApplicationContext().unregisterReceiver(myReceiver);
}

Мне нужно добавить два из этих широковещательных приемников для двух разных фрагментов. На первом все работает отлично. Если в приложении пользователь находится на фрагменте, он обновляется, а во втором фрагменте я получил следующие ошибки:

03-15 07:32:40.474: E/AndroidRuntime(1692): FATAL EXCEPTION: main
03-15 07:32:40.474: E/AndroidRuntime(1692): java.lang.RuntimeException: Error receiving broadcast Intent { act=CONTENTS_NOTIFICATION flg=0x10 } in [email protected]
03-15 07:32:40.474: E/AndroidRuntime(1692):     at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:768)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at android.os.Handler.handleCallback(Handler.java:725)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at android.os.Handler.dispatchMessage(Handler.java:92)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at android.os.Looper.loop(Looper.java:137)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at android.app.ActivityThread.main(ActivityThread.java:5191)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at java.lang.reflect.Method.invokeNative(Native Method)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at java.lang.reflect.Method.invoke(Method.java:511)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at dalvik.system.NativeStart.main(Native Method)
03-15 07:32:40.474: E/AndroidRuntime(1692): Caused by: java.lang.NullPointerException
03-15 07:32:40.474: E/AndroidRuntime(1692):     at sample.actionscontentview.fragment.ContentsFragment.populateListview(ContentsFragment.java:194)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at sample.actionscontentview.fragment.ContentsFragment.access$0(ContentsFragment.java:111)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at sample.actionscontentview.fragment.ContentsFragment$1.onReceive(ContentsFragment.java:107)
03-15 07:32:40.474: E/AndroidRuntime(1692):     at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:758)
03-15 07:32:40.474: E/AndroidRuntime(1692):     ... 9 more

и код тот же! Я не могу понять, почему он не работает. В нем говорится, что есть проблема с populatelistView, но одна и та же функция прекрасно работает внутри фрагмента, если не вызывается из широковещательного приемника.

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

Ответ 1

Попробуйте использовать EventBus от GreenRobot https://github.com/greenrobot/EventBus

Когда ваш файл успешно загружен, вы публикуете событие

EventBus.getDefault().post(YourData.Downloaded);

Ваш фрагмент будет регистрироваться для получения событий, предпочтительно в методе onStart()

EventBus.getDefault().register(this);

И он получит события в методе onEvent:

public void onEvent(Data.State) {}

а затем вы можете легко обновить список. Вы также можете отменить регистрацию событий в методе onStop(). Вы можете хранить данные в своем приложении или сохранять их. Это очень простое и приятное решение. Надеюсь, поможет. Вы можете зарегистрировать столько фрагментов, сколько хотите для этого события, поэтому, как только EventBus отправит событие, все доступные фрагменты, зарегистрированные для него, получат это событие.

Ответ 2

Я знаю, что это старо, но на случай, если вы сможете помочь мне в своем опыте, чем в моей проблеме:

У меня есть аналогичный вопрос: Приемники и фрагменты широковещания. Вы можете найти обходной путь, который я сделал, хотя я считаю, что должен быть лучший способ сделать это.

Некоторые предлагают, чтобы все трансляции отправлялись в Activity, в котором размещаются фрагменты, и через прослушиватель сообщают фрагментам, что они должны обновлять представление в зависимости от того, что было получено. Это может быть лучшим подходом, но также может включать в себя нулевые указатели, проверяющие представление фрагментов.