2

I have a broadcast receiver that gets fired whenever a download finishes in the system. What i want to do is to send the result of this receiver to my fragment where i update the views. Currently i use this approach.

public class DownloadCompleteReceiver extends BroadcastReceiver {

    public interface DownloadListener {
        public void downloadCompleted(int appId);
    }

    private static List<DownloadListener> downloadListeners = new LinkedList<>();

    public static void registerDownloadListener(DownloadListener downloadListener){
        downloadListeners.add(downloadListener);
    }

    public static void unregisterDownloadListener(DownloadListener   downloadListener){
        downloadListeners.remove(downloadListener);
    }


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

        //whatever calculation needed to be done.

        for(DownloadListener listener: downloadListeners)
            if(listener != null)
                listener.downloadCompleted(appId);

    } 
}

and in my fragment onStart method i do this.

DownloadCompleteReceiver.registerDownloadListener(this);

and in onStop method

DownloadCompleteReceiver.unregisterDownloadListener(this);

then i implement the interface and i have the result! It's a straightforward solution that works perfectly fine. I wonder is something wrong with my code? do i miss something?! I spent hours searching on the matter but no one uses this approach! is there a reason why?

BTW i need to define my receiver in separate class because i want it to be fired even if my application is closed so inner classing my receiver is not an option here.

Alireza Ahmadi
  • 5,122
  • 7
  • 40
  • 67

2 Answers2

1

I don't see anything wrong with this approach, I used the same approach for my project.

If you are asking whether there are alternative ways of doing it, you can check out event-based libraries for asynchronous communication:

There have been questions comparing event-based framework with Android's LocalBroadcast also: Otto vs LocalBroadcast:

Community
  • 1
  • 1
hidro
  • 12,333
  • 6
  • 53
  • 53
0

There is nothing wrong with this approach.

First of all your receiver registered in onStart and Unregistered in onStop method.

So if your activity is running(i mean not stopped) and you remove or replace your fragment.then you will never be able to unregister your receiver.

So if you only uses this listeners for this fragment only you should register and unregister you receiver in onAttach and onDetach of fragment.

Hope it will help.Thanks.

Nirav Tukadiya
  • 3,367
  • 1
  • 18
  • 36
  • I'm assuming when my fragment is replaced with another fragment. onStop(), onDistroyView() and onDistroy() will be called on it. So it would be removed from listeners list. isn't it like so? – Alireza Ahmadi Feb 28 '15 at 12:38
  • onStop and onDestroy will be called when your activity is stop and destroyed not fragment because they are activity's lifecycle method not fragment's.Yes on DestroyView will be called for sure. – Nirav Tukadiya Feb 28 '15 at 13:03
  • register and unregister are called in onStart() and onStop() of the fragment not activity! note that this two methods are not Broadcast receiver methods, this are custom method i defined in my receiver and unlike broadcast recievers methods, this methods can be called on any java object including fragments! – Alireza Ahmadi Feb 28 '15 at 13:20
  • onStart and onStop are method of activity lifecycle.You just overriding them into your fragment.So if you remove your fragment and activity is still running then onStop of your fragment will never get called.Read this http://developer.android.com/reference/android/app/Fragment.html#Lifecycle onStop() fragment is no longer visible to the user either because its activity is being stopped or a fragment operation is modifying it in the activity. So if activity is stopped only then onstop of your fragment will be called otherwise never. – Nirav Tukadiya Feb 28 '15 at 13:35
  • onStop() will be called whenever you replace a fragment! then onDistroyview() and then onDistroy(). you can test this by putting a log message in fragment life-cycle! we are not overriding activity life-cycle in fragment! fragment has its own life-cycle that works with activity life-cycle. – Alireza Ahmadi Feb 28 '15 at 13:49