A library that I am using has an Android activity. I would like to pass a callback to the activity to get notified of certain user events like when user enters a specific code or draws something on the screen. I am not able to find a way to pass callbacks to the android activity.
Note: I can edit the library, however, I prefer to leave the activity within the library for architectural reasons and ease of testing without integrating with the larger app.
What is the best possible way to solve this? Are there any Android design patterns?
What is the best possible way to solve this?
Modify the activity to post an event on an event bus (greenrobot's EventBus, Square's Otto, LocalBroadcastManager when these things occur. Then, listen for those events elsewhere in your app.
I prefer to leave the activity within the library for architectural reasons and ease of testing without integrating with the larger app
Then convince the developer of the library to modify the activity to post an event on an event bus (greenrobot's EventBus, Square's Otto, LocalBroadcastManager when these things occur. Then, listen for those events elsewhere in your app.
Or, convince the developer to offer some other means of accomplishing this (e.g., you subclass the activity and override certain methods to be notified of these events).
It sounds like you have access to the library src code, so create an AIDL interface for communication between your app and the lib. You can set up a callback via AIDL and have the lib send your app the data in real-time as it gets generated.
There's quite a bit of code involved but it is achievable. You can start here:
https://developer.android.com/guide/components/aidl
Related
I'm working on this project in Android in which an aspect requires a CountdownTimer with a foreground service. A few other answers on Stack Overflow mentioned that LocalBroadcastManager would be suitable for my needs.
The documentation in Android Developers, however, mentions that it has been deprecated. Any suggestions on what I should use in its place? The documentation mentioned about using LiveData, but I was wondering if there are any easier alternatives.
LocalBroadcastManager is basically an event bus with a lot of unnecessary ceremony around Intents and intent filters. So one replacement is easy, and functions quite similarly: you can use any event bus library. greenrobot's EventBus is a popular choice (here's a guide for it) and Guava also has one, if you're already using Guava (but Guava is pretty heavy to include just for an event bus).
But event buses suffer from the same problems that LocalBroadcastManager does that led to it being deprecated: it's global, it's not lifecycle-aware, and as your app gets larger, it becomes much more difficult to reason about the effects of a change to an event. For cases of observing data, LiveData solves this quite nicely because it's lifecycle-aware, so you won't get change notifications at the wrong time (like before your View is set up, or after onSaveInstanceState) - but it'll handle delivering the change notifications when you're in the right state again. It's also more tightly scoped - each piece of LiveData is accessed separately rather than having (typically) one event bus/LocalBroadcastManager for the entire app.
For cases where it's more of an event rather than a piece of data being changed, you can sometimes convert it to a piece of data. Consider if you have "login" and "logout" events - you could instead create a LiveData that stores an Account for logged-in users, and becomes null when the user is logged out. Components could then observe that.
There are certainly cases where it really is difficult to convert it to a piece of observable data (though I can't immediately think of any examples that would typically be used with an event bus patten). For those, consider writing your own listener interface, similar to how on-click listeners work.
For your example of a countdown timer, I think LiveData is a pretty straightforward solution, and will be much easier than an event bus or even LocalBroadcastManager would be. You can just have a LiveData of the timer's current value, and subscribe to it from whatever needs to show the value.
Is EventBus suitable for the tasks I am trying to complete? I need a callback whenever any application prints a document.
Yes it is good for getting callback.
But if you only need to use it single time then do not use EventBus library for that, you can use BroadcastReceiver or our own defined interface listener.
Because for using one time the library is not a good idea. If There are many use of callbacks then No-doubt EventBus is best.
I need a callback whenever any application prints a document.
Android does expose this information to apps.
Is EventBus suitable for the tasks I am trying to complete?
No, insofar as an event bus does not cause Android to provide you with information that it otherwise would not.
I am creating an application for Android which I want to turn into a library module and use its own logic as a common logic for several other application which differs in their UI. The library module got an Android service which can receive and send commands to a listener which is defined in the application itself (in my case in the main activity).
On the receiving side, The listener is the main activity of the application which then invokes callbacks according to the type of message from the service.
The issue is more with the sending commands to the service part. The API in question is the way of the application to send messages to the service. It simply gets the argument of the message to send and pass it along to the service.
The way I thought of doing it is making the library's main activity as the API which will allow both the sending and receiving events. The developer of a UI using this library will then simply need to make another module for the GUI alone, and make his main activity extend the library's main activity, thus being able to use the API and extend the listener's behavior.
What I want to know is possible technical issues, and not an opinion if the design itself is the best possible or not - Is there a problem with this design? For example issues with Android disposing of the activity? Any other issues?
The main risk with building your APIs based on the Activity is that you are basically tying your API to the activity lifecycle, I assume an API like that for messaging should be available on both the main and UI threads. I prefer using interfaces for designing API's. Dagger is very helpful for creating singletons which can be injected anywhere.
My app is heavily depended on Local broadcast ,for every activity invocation am invoking the broadcast registration method so is it good to move to any event bus.
Two primary concerns of using Local broadcast Manager.
Every activity require the registration
Registration method execution time(Around 10 actions are registered)
I think the event bus will improve overall execution and performance of my app.
Most event bus libraries provide reflection-based registration which is less efficient than LocalBroadcastManager. The main reason for using the event bus would be coding ease.
afaik, there are some benefits using event-bus instead of LocalBroadcastManager:
Code decoupling.
By decoupling your code, you will minimize your class which formerly using LocalBroadcastManager. Simpler code less error and improve code readability.
Ease of Maintenance.
This somewhat related to no.1, decoupled code make it easy to maintained.
Localizing error.
Avoids complex and error-prone dependencies and life cycle issues.
Avoid further bugs.
EventBus FAQ
How is EventBus different to Android’s BroadcastReceiver/Intent system?
Unlike Android’s BroadcastReceiver/Intent system, EventBus uses
standard Java classes as events and offers a more convenient API.
EventBus is intended for a lot more uses cases where you wouldn’t want
to go through the hassle of setting up Intents, preparing Intent
extras, implementing broadcast receivers, and extracting Intent extras
again. Also, EventBus comes with a much lower overhead.
I’ve written a library for Android, upon initialising the library I register for call backs for location updates, subscription status changes, library status changes and various other updates...
Originally, I wanted all these updates to call back to a controller in my android UI app, and then for the controller to launch activity A, pass on the messages from the controller to activity A and so on. Or launch activity B for signing up for a subscription and forward messages to this etc
However, it appears that there isn’t a way to achieve this - Because each activity is in isolation? Unless I’m mistaken?
So what are my options here? It sounds like I either have to use one activity for the whole app and swap the UI’s which after looking into it doesn’t appear to be the way to go?
I did try to subclass Application, which worked and gave me access to my library from an activity – but I want it the other way around. Is this possible? would wrapping the library in a service achieve what I want to do?
You could use broadcasts and send them from your library. Each of your activities would have to register a BroadcastReceiver in their onResume() method and unregister it in their onPause() method. This would be comparatively easy when you use a common base class for your activities. You could then send commands from your library to whatever activity is currently active.