Courtesy of Andrés Nieto Porras (

Couchbase Lite runs replications (syncs) using background threads. Starting and stopping replications doesn’t happen synchronously. This can lead to mistakes in detecting the state of a replication.

The Replication class has, depending on platform, either a running property or a convenience routine like isRunning(). This is a lightweight way of checking the status of a replication.

Using it can lead to unexpected results, though. For example, I recently wrote a utility that uses continuous replications. I have a toggle button to start and stop them. It’s tempting to use isRunning to update the button state. Turns out this is a bad idea. Not surprising, given changes happen in the background, but easy to overlook.

Instead, the preferred approach uses a change listener. Here’s an example.

We have two classes. The database helper class wraps some standard operations for simplicity. I added an interface to employ a callback pattern. The client class has to implement it. The helper class digests the Couchbase Lite change notification before passing anything to the client. This gives a nice separation of concerns.

The code listings below are outlines. They only show essentials. Let’s look at the helper class first.

We see that DBHelper implements the Replication.ChangeListener interface. This is an interface defined by Couchbase Lite. In startReplication we add this listener to the replication. It has one method to override, changed. The ChangeEvent passed in can have several different values. In the example, I check for errors first and notify the user if one occurs. Otherwise I check to see if this is a replication state transition event. The destination state can be one of INITIAL, RUNNING, IDLE, OFFLINE, STOPPING, or STOPPED.

In this case I just want to know if the replication is shutting down, so I simplify the return value. I allow clients to register more than one listener, so the last bit of code loops over all the callbacks and invokes them.

The client class is even simpler. I have the class implement the needed interface from the helper class. Just register the listener during instance construction, and have onChange do whatever you need in the UI.

This code is drawn from a tool I built. Read about the tool itself in this post.You can find the source code on GitHub here.


Check out more resources on our developer portal and follow us on Twitter @CouchbaseDev.

You can post questions on our forums. And we actively participate on Stack Overflow.

Hit me up on Twitter @HodGreeley


Posted by Hod Greeley, Developer Advocate, Couchbase

Hod Greeley is a Developer Advocate for Couchbase, living in Silicon Valley. He has over two decades of experience as a software engineer and engineering manager. He has worked in a variety of software fields, including computational physics and chemistry, computer and network security, finance, and mobile. Prior to joining Couchbase in 2016, Hod led developer relations for mobile at Samsung. Hod holds a Ph.D. in chemical physics from Columbia University.


  1. […] comes from the DBService helper class. I wrote a bit about detecting the state of a replication here. For this app I just need to know whether a replication is running or not to keep the Sync button […]

  2. […] The other listener allows us to display a busy-wait spinner (indefinite progress bar) depending on the Replication state. You can read more about monitoring replication state here. […]

Leave a reply