The following blogpost is a primer on architecting Android apps with RxJava and Pusher. It was written by Joe Birch, a Senior Android Engineer at Buffer. Buffer is a social media management platform, and a long time Pusher customer. Joe is a Google Developer Expert for Android, renowned blogger and public speaker. You can follow \[…\]
The following blogpost is a primer on architecting Android apps with RxJava and Pusher. It was written by Joe Birch, a Senior Android Engineer at Buffer. Buffer is a social media management platform, and a long time Pusher customer. Joe is a Google Developer Expert for Android, renowned blogger and public speaker. You can follow him on Medium, Twitter, or speaking at a conference near you.
When your application content reflects the state of data stored on a server, making sure you’re always displaying the most up-to-date state ensures a better experience for the user. Now, this can be achieved by the user themselves but it involves the manual refreshing of content. For example, the user may be required to pull-to-refresh in order to show the latest content in some form of content feed. In any app this is probably the simpler method to implement, but it’s not the best experience for our users.
And to build on this even further — in the case of Buffer, another team member within your account may have paused your queue, added a new update or rescheduled a post to go out on a different day — when this happens you may not be aware of it and without repeatedly manually refreshing, you would never know. That’s where Pusher comes in to help us out! Now in Buffer for Android (well, when it’s out of beta!), whenever content changes on the server-side the Android app will refresh the content shown to ensure that you’re always seeing the freshest state of content. The flow for this looks something like this:
As shown above, there are four different refresh events which are now triggered in the app:
The team over at Pusher made the process of implementing this in our app quite delightful by providing us with a helpful Java Client Library – pusher/pusher-websocket-java
Now, this is great work and super useful by itself. But the way in which we wanted to use it in our app, and the places where it would be used, meant that it wasn’t the exact representation which we felt was best for our needs. Because of that, we went ahead to create the Reactive-Pusher library – bufferapp/Reactive-Pusher
But why exactly did we decide to wrap the library in the first place?
RxPusher supports most of the functionality found within the Pusher Java Client library, here’s a quick look at what you can do with it and how:
You can use the observeConnection() method to observe the connection to the Pusher service, this won’t terminate so you will continue to receive connection updates regardless of how the Pusher connection status changes:
1reactivePusher.observeConnection().subscribe({ 2 when (it) { 3 ConnectionStatus.CONNECTED -> { } 4 ConnectionStatus.CONNECTING -> { } 5 ConnectionStatus.DISCONNECTING -> { } 6 ConnectionStatus.DISCONNECTED -> { } 7 ConnectionStatus.RECONNECTING -> { } 8 ConnectionStatus.UNKNOWN -> { } 9 } 10 }))
There is also an observeConnection(varargs filter: String) method available that allows you to pass a collection of ConnectionEvents which you wish to exclude the callback being triggered.
You can retrieve channels using either the getChannel(), getPrivateChannel()or getPresenceChannel() methods.
Calling getChannels() will return you an instance of a Channel, getPrivateChannel() a PrivateChannel instance and getPresenceChannel() a PresenceChannel instance. When calling this you just need to pass in the required channel name.
1reactivePusher.getChannel("some channel name") 2 .subscribe({ // do something with the channel })
You can also use the isChannelSubscribed(), isPrivateChannelSubscribed()and isPresenceChannelSubscribed()methods to check the subscription state of a channel.
When calling this method you need to pass in the desired channel name which you wish to check. Upon a successful request you will be returned a boolean value if the channel is subscribed to.
1reactivePusher.isChannelSubscribed("some channel name") 2 .subscribe({ 3 // do something with the channel subscription result 4 })
Using the subscribeToChannel(), subscribeToPrivateChannel() or bindToPrivateChannelEvent() methods allow you to subscribe to events from a given channel.
When subscribing to a channel you need to pass the channel name along with a collection of events that you wish to subscribe to, when binding you only need to pass a single event that you wish to bind to. When an event is received you will get an instance of a ChannelEvent from the callback.
1reactivePusher.subscribeToChannel("some channel name", events...) 2 .subscribe({ // do something with the channel event })
You can also trigger events from this library by using the triggerEvent() method. This just requires you to pass in the channel name, the event name and the data you wish to pass with that event.
1reactivePusher.triggerEvent("some channel name", "some event name", "some data") 2 .subscribe({ // do something with the trigger completion })
Using Pusher in our Android app has allowed us to introduced a more pro-active experience for our users, ensuring their always shown fresh content regardless of where the data was changed or who by. Creating Reactive Pusher has also allowed us to implement it in a way that fits in well with our architecture. Both of these together means not only our users our happier, but also our developers!
Are you using Pusher in your apps, thinking of doing so or even have questions about Reactive Pusher? Feel free to drop us a response or get in touch over on Twitter.
❤️ Kotlin? Fill in our State of Kotlin survey to help us discover how developers like you are picking up Kotlin, and get a chance to win a trip to KotlinConf in Amsterdam! Participate here.