Android BroadcastReceiver or a simple callback method?

In my projects, I use BroadcastReceiver as a callback from a long running thread (for example, notifies me that the operation is completed and send some response data from Worker Thread so that the activity can display the corresponding message to the user ..). In order to use BroadcastReceiver , I have to be careful to register and unregister the broadcast receiver each time I use it, and also take care which messages to send esspecialy when I use this method for more different actions (e.g. downloading, creating WebService calls, etc.). And also for sending custom objects via translation, I also need to make Parcelable objects.

Unlike this approach, I also looked at the callback methods approach, which looks simpler than the method I use. Callback methods are a simple implementation of front-end methods that can be used to achieve the same effect as BroadcastRecaiver in application messaging. This approach does not require a Parcelable implementation to return complex objects, and it does not use keys such as BroadcastReceiver .. I think the bad part is that I need to check the callback object for a null value before I want to call the callback method calling .., and also to make sure that I run the code from the implementation in the user interface thread, so I can update the interface without errors.

Well, I hope you understand what I wanted to say :).

Now the question is, how do you think the callback method is better (easier, cleaner, faster ..) than the BroadcastReceiver approach, when they are used only within one application? (Note that I do not use the Android Service for background work. Just AsyncTask and Thread s)

Thank!

+48
android multithreading callback broadcastreceiver
May 13 '12 at 21:03
source share
5 answers

This is a very interesting question, and I ran into the same problem. In my opinion, both mechanisms can be used as a whole, and the correct approach to use depends on your use case. Here are some points to consider before making a decision.

Using a callback mechanism has some advantages, but there are also limitations:

PRO

  • It is simple and easy to implement.
  • You get type safety between components that interact with each other.
  • You can return arbitrary objects.
  • This makes testing easier because you only need to introduce a mock-callback (e.g. generated via mockito or something similar) in unit tests.

CONTRA

  • You need to switch to the main thread to perform manipulations with the user interface.
  • You can only have a 1 to 1 connection. A 1-in-n connection (observer pattern) is not implemented without further work. In this case, I would prefer the Android Observer / Observable mechanism.
  • As you said, you always need to check for null before calling the callback functions if the callback may be optional.
  • If your component needs to offer a kind of service API with various service functions, and you do not want to have a callback interface with only a few common callback functions, you need to decide whether to provide a special callback interface for each service function or if you provide One callback interface with many callback functions. In a later case, all callback clients used to call the service in your API must implement the full callback interface, although most of the method bodies will be empty. You can get around this by implementing a stub with empty bodies and making your callback client inherit from this stub, but this is not possible if it is already inheriting from another base class. Maybe you can use some kind of dynamic proxy callback (see http://developer.android.com/reference/java/lang/reflect/Proxy.html ), but then it gets very complicated, and I think that you are using a different mechanism.
  • The client for callback calls must be distributed through various methods / components if it is not directly accessible to the caller of the service.

Some points related to BroadcastReceiver -approach:

PRO

  • You get free communication between your components.
  • You may have a 1-to-n ratio (including 1-to-0).
  • The onReceive() method is always executed in the main thread.
  • You can notify components throughout your application, so communication components do not need to โ€œseeโ€ each other.

CONTRA

  • This is a very general approach, so sorting and marking up data transmitted using Intent is an additional source of errors.
  • You must make your Intent actions unique (for example, by adding a package name) if you want to eliminate correlations with other applications, since their initial goal is to make translations between applications.
  • You need to manage BroadcastReceiver registration and registration. If you want to do this in a more convenient way, you can implement custom annotation to annotate your activity with actions that need to be registered, and implement the base class Activity , which performs registration and unregistration using IntentFilter in its onResume() respectively. onPause() methods.
  • As you said, data sent from Intent must implement the Parcelable interface, but there is also a strict size limit, and this will cause performance problems if you transfer large amounts of data using your Intent . See http://code.google.com/p/android/issues/detail?id=5878 for a discussion of this. Therefore, if you want to send images, for example, you must store them temporarily in the repository and send the corresponding identifier or URL to access the image from the recipient of your Intent , which removes it from the repository after use. This leads to further problems if there are several receivers (when should the image be deleted from storage and who should do this?).
  • If you abuse this notification mechanism, the control flow of your application may be hidden, and during debugging you finish drawing graphs with Intent sequences to understand what caused a certain error or why this notification chain is broken at some point.

In my opinion, even a mobile application should have an architecture base on at least 2 levels: the UI layer and the main level (with business logic, etc.). In general, long tasks are performed in their own thread (possibly through AsyncTask or HandlerThread when using MessageQueue s) inside the main level, and the user interface should be updated after this task is completed. In general, with callbacks you achieve a tight connection between your components, so I would prefer to use this approach only inside the layer, and not for communication across the borders of the layers. To broadcast messages between the UI and the base layer, I would use BroadcastReceiver approach, which allows you to separate your user interface level from the logical level.

+77
May 20 '12 at 10:31
source share

I do not see what you are getting using BroadcastReceiver in your case. Callbacks or, best of all, Handlers are a way to do this. BroadcastReceiver good when you do not know who the subscribers are.

+6
May 13 '12 at 9:27
source share

I'll just add one more option to the other great answers you already got ...

You do not need to create a broadcast receiver to receive intentions. In your Android manifest file, you can register any activity to receive intentions:

 <activity android:name=".MyActivity"> <intent-filter > <action android:name="intent.you.want.to.receive" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> .... </activity> 

Then override the onNewIntent(Intent) method in your activity to get it.

To send an intent, use the Context.startActivity(Intent) method. Most likely, you will want to add the FLAG_ACTIVITY_SINGLE_TOP flag to your intention so that it does not create a new instance of your activity if it is already running.

EDIT: I just noticed that you are working in the same application. Therefore, a simple callback is probably best. The solution above works in one application, but is more suitable for different applications. I will leave it here just in case it helps someone. Good luck

+3
May 16 '12 at 16:15
source share

Must use Broadcastreceivers. If you need to send broadcasts across all applications, while callbacks (or handlers suggested by Alex) are best used in your situation.

If you want to use other than these two, consider using Observer (the interface is included in android) and delegate.

For the delegate, please consider this SO post.

Hope this solves your problem.

+1
May 16 '12 at 12:55
source share

not sure what the goal is, but if you want to keep the same idea of โ€‹โ€‹using intentions and broadcasts, and want to improve performance and security than regular broadcast applications, you can try this demo, available in the Android support library:

http://developer.android.com/resources/samples/Support4Demos/src/com/example/android/supportv4/content/LocalServiceBroadcaster.html

If not, you can always use asyncTask, service, handlers, etc.

+1
May 16 '12 at 20:30
source share



All Articles