I have started a thread which connected to bluetooth device and streams data. I actually started this thread from a service(Thread not started from activity). So know I need to communicate to activity to show the list of input streams. I am not sure if event bus can provide a such a high frequently changing data. Can some one give me a better existing examples of how to use display the streams.
Please don't ask me for the source code.
I believe Event bus can be a good solution, also check bound services:
https://developer.android.com/guide/components/bound-services.html
I advise you to look into LiveData from the Android architecture components. You can observe the result from the activity, and it will "unsubscribe" for you when needed (onStop()). You can read about the advantages on the link I provided.
You could extend a LiveData and implement the logic inside it (like this example), or just use it to dispatch the updates, then observe it on the Activity. The postValue() method will ensure that it gets dispatched on the MainThread.
Related
When using Firebase Cloud Messaging on Android, it is often desirable to notify the current Activity of an incoming push notification. One of the recommended ways to do this has been to use LocalBroadcastManager to send an Intent from the FirebaseMessagingService implementation to the Activity (StackOverflow example answer).
However, as of version 1.1.0-alpha01 (2018-12-17), LocalBroadcastManager is deprecated:
LocalBroadcastManager is an application-wide event bus and embraces layer violations in your app: any component may listen events from any other. You can replace usage of LocalBroadcastManager with other implementation of observable pattern, depending on your usecase suitable options may be LiveData or reactive streams.
While it is highly likely that this class will remain available for a while longer, I would like to start cleaning up our applications anyway, so I want to migrate to something better before Google actually removes the old way.
Right now, there are two main roles that these local broadcasts have in our apps:
Update the UI with the new data from the push notification. The way this worked was that each Activity that cares about the incoming push data has a broadcast receiver that listens for the appropriate message and updates its own view data.
Force the user to log out if the server sends a notification to end the session. This works with each activity having an instance of a broadcast receiver that listens for a logout event, ends the Activity, and starts the Login Activity.
As I see it, these use-cases have issues with both of their suggested alternatives:
LiveData is easiest to use in an Activity or Fragment as part of a ViewModel. However, ViewModel is only meant to be used from those classes that directly deal with the UI. Accessing the ViewModel from within the FirebaseMessagingService takes an ugly hack and is a really bad idea from an architectural perspective. Also, different activities and fragments have different ViewModel objects, and I don't want the service to need to access them all.
I can create a Kotlin object (a.k.a. Singleton) with a bunch of LiveData properties, have the FirebaseMessagingService update those LiveData objects from the incoming messages, and have the Activity observe those changes and copy them into its own ViewModel's LiveData properties. The problem with that is twofold: first, it requires me to have two identical LiveData objects for each piece of data, one in the ViewModel and one in the object; and second, it doesn't help me with handling the "log out event", because LiveData is meant to handle changing data, not listening to a stream of events. (I may be able to handle the second issue using this LiveData Event Wrapper, but that still feels like a bad hack over something that isn't meant to work this way.)
While reactive streams, such as RxJava, will probably do what I need, I already forced my team to learn Kotlin, Android Databinding, Android ViewModel, and a bunch of other new stuff in the last few months, and I don't think they can take much more. RxJava is also a large thing to add for just this one use, and we have no plans to rewrite the entire application to take advantage of it in order to justify its addition.
One suggestion I found was to use Kotlin Coroutines with Channels or Flows. These can be used very similar to reactive streams, but (unlike RxJava) are intended to be used with Kotlin and benefit from Kotlin's improvements over Java. This option is especially attractive now that Google has announced that they are focusing on Kotlin for Android development instead of Java.
While this seems to me to be the best option, I have not managed to find any feedback from others about whether it works and if there are side-effects and/or pitfalls to such an implementation. The only thing I found was an open issue on the kotlinx.coroutines repository about the need for providing an example of an application like this. While I'd love to contribute such an example, I don't think I know enough about it to create a good example, and I don't want my production apps to be the guinea pig. I also don't know whether it is better (or proper) to use explicit couroutines with Channel or to use suspend with Flow for this case.
In summary:
Are Kotlin Coroutines and their associated concurrency structures a good way to handle communication between Android Service and Activity?
If yes, which Kotlin type makes more sense to use, Channel or Flow?
Coroutines don't really help with the handoff of data from one software component to another. They help with the processing multiple units of asynchronous work using syntax that appears as if they were synchronous. That's the bottom line for coroutines. They're analogous to async/await syntax in JavaScript. While you might use a coroutine to access data from asynchronous sources, it doesn't give you any primitves to proxy that data on to other components.
LiveData probably works just fine for what you're trying to do. Don't conflate ViewModel with LiveData - they solve different problems. While you're correct that ViewModel should only be accessed by code that deals with UI, that guideline doesn't extend to LiveData. It's perfectly reasonable to expose a LiveData that reflects current data from FirebaseMessagingService that is later picked up by a ViewModel, transformed, and passed on to a view. This LiveData could be a singleton, or obtained via whatever dependency injection infrastructure you choose.
Bear in mind that LiveData is really only supposed to be used for managing changes in state. It's not a "stream" of data that your app can listen to. You will need to make sure that your infrastructure is state-based in order for this to work out well. FCM itself is not state-based, but if you want your views to respond to messages from FCM, you'll need to retain enough context between each message to make sure your UI responds consistently to new messages (or the lack of messages altogether).
I have created a BluetoothManager much like the one in this example. This object is instantiated in a connection activity, reached from the main acitivty by clicking on a "Connect" button, which provides a ListView of selectable devices. Works great so far.
I am now connected and have a BluetoothManager.ConnectedThread running and the streams set up. I would now like to be able to send Bluetooth data from/to various other activities when they are running. For example, I will want to chart realtime values when the charting activity is running.
As far as I can tell, the pushing of the data out from the ConnectedThread will occur via a Handler, which is a new topic for me. What I am unclear on his how other activities might access the ConnectedThread's write() function.
First of all, even though a singleton could be a solution, android Service's are there for this purpose, since these are elements that can keep running when your UI is out. So my suggestion would be to create a sticky service an then you have two options:
Handle data using a handler between the activity and the Service. Maybe if you are not too familiar with the Handler api this will take some time to you. In this example of the official documentation you can also check how to use the handler.
Create a bound service, to which you can bind from the activities and send some data when required. Here you have the official information about bound services.
You can have a look to this tutorial to get more information about handlers.
I've been reading about how to share data between an Activity and a Service. I found some answers here and here. I'm planning on creating a singleton class as this seems like the lowest overhead mechanism to share state.
For my application, I have a service which is acquiring and logging various sensor data and is filling a data structure with the most current state, and then notifying the activity to update the UI with this info, if the activity is visible. If the activity is not visible, then when it becomes visible it consults the state information to update the UI.
I don't see any mention of whether synchronization is necessary. For instance, isn't it possible that the UI thread might be pulling data out of the structure and get interrupted by the service which then puts new data in, resulting in the UI being rendered incorrectly? Also, I want to put a flag on various pieces of data so the front end knows which pieces have been updated: the service would set a boolean and the activity would clear it. It seems like a similar problem could occur here.
Do I need to worry about this, or is it impossible for the UI thread in the activity and the (e.g.) Listener or Receiver thread in the service to interrupt each other. If they can, is it sufficient to use synchronized methods to access the data structure?
For instance, isn't it possible that the UI thread might be pulling data out of the structure and get interrupted by the service which then puts new data in, resulting in the UI being rendered incorrectly?
Possibly. A Service usually has background threads, whether you create them or you get them from specific Service implementations (e.g., the thread used by IntentService for onHandleIntent()). Synchronization is not an issue of components (activities, services, etc.), but rather an issue of threads.
If they can, is it sufficient to use synchronized methods to access the data structure?
Well, personally, I try to use synchronized objects and collections from java.util.concurrent and java.util.concurrent.atomic. Depending on what you're doing and how you're doing it, synchronized methods may be a fine solution.
I know that an activity can communicate with a local service using the IBinder interface; I am trying to find a way for communication between two services.
Specifically, I have my main service starting an IntentService to handle file uploads. I want this IntentService to inform back to the main service once it is done uploading, and before it dies.
Any ideas about how this would happen?
You have to use BroadcastReceiver to receive intents, and when you want to communicate simply make an Intent with appropriate values.
This way you should be able to make a 2-way communication between any component.
In Android, there is a special way of completing tasks like yours. Look at AIDL (it's not well documented in official docs, but there are some extra sources on the web). This is a way of implementing two-way communication between any components placed in separate processes. In comparison to BroadcastReceivers, using this you'd get direct calls and callbacks, that will be less dirty than relying on something would come from somewhere in BroadcastReceiver.
To reach the needed effect, you'll have to define an interface for a callback and an interface for performing actions (with a callback supplied, or register/unregister methods). Than, after you received some command using the second interface, you should perform the job and post back the result through callback. To reach the asynchronous completion add a key work "oneway" before method signature (return type). To separate in and out params (if you need it), use "in", "out" and "inout" keywords near params.
As it comes to restrictions, only primitives, arrays and parcelables (and parcelable arrays) might be transferred between processes.
To control your callbacks lifecycle and operations atomicity, use RemoteCallbacksList for storing registered callbacks and notifying recipients using the duplicate of your list got from beginBroadcast.
If you have any troubles, you're free to ask here.
I have a service that handles incoming data from and external source. Currently the data it recieves is forwarded to seperate DataManager that notifyAll() threads that the data has arrived. All threads check the data and the correct thread pops it off and processes it and then wait indefinitely until more data arrives. The basic idea of the thread is the class it is attached to holds all data and processing relevant towards a particular objective that may or may not be created in an Activity, but needs to be ready at any given moment.
I believe this is very inefficient and am attempting to redesign it. What I'm thinking is instead of using threads, use services and just use messenger to pass data around. Is this any more efficient or am I in the same boat?
Read this article - High-Performance Server Architecture - not saying you are doing it wrong but this might give you a new perspective.