SyncThread: Fix issue when network is back and the app was in background: do not restart the thread
This commit is contained in:
parent
73ec0f5a83
commit
25e9a179d2
|
@ -36,7 +36,8 @@ internal class NetworkConnectivityChecker @Inject constructor(context: Context)
|
||||||
private val listeners = Collections.synchronizedSet(LinkedHashSet<Listener>())
|
private val listeners = Collections.synchronizedSet(LinkedHashSet<Listener>())
|
||||||
|
|
||||||
// True when internet is available
|
// True when internet is available
|
||||||
private var hasInternetAccess = false
|
var hasInternetAccess = false
|
||||||
|
private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
merlin.bind()
|
merlin.bind()
|
||||||
|
@ -63,7 +64,7 @@ internal class NetworkConnectivityChecker @Inject constructor(context: Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun waitUntilConnected() {
|
suspend fun waitUntilConnected() {
|
||||||
if (isConnected()) {
|
if (hasInternetAccess) {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
suspendCoroutine<Unit> { continuation ->
|
suspendCoroutine<Unit> { continuation ->
|
||||||
|
@ -85,10 +86,6 @@ internal class NetworkConnectivityChecker @Inject constructor(context: Context)
|
||||||
listeners.remove(listener)
|
listeners.remove(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isConnected(): Boolean {
|
|
||||||
return hasInternetAccess
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Listener {
|
interface Listener {
|
||||||
fun onConnect() {
|
fun onConnect() {
|
||||||
|
|
||||||
|
|
|
@ -93,8 +93,8 @@ open class SyncService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doSync(once: Boolean = false) {
|
fun doSync(once: Boolean = false) {
|
||||||
if (!networkConnectivityChecker.isConnected()) {
|
if (!networkConnectivityChecker.hasInternetAccess) {
|
||||||
Timber.v("Sync is Paused. Waiting...")
|
Timber.v("No internet access. Waiting...")
|
||||||
//TODO Retry in ?
|
//TODO Retry in ?
|
||||||
timer.schedule(object : TimerTask() {
|
timer.schedule(object : TimerTask() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
|
|
|
@ -50,6 +50,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
|
||||||
private val lock = Object()
|
private val lock = Object()
|
||||||
private var cancelableTask: Cancelable? = null
|
private var cancelableTask: Cancelable? = null
|
||||||
|
|
||||||
|
private var isStarted = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
updateStateTo(SyncState.IDLE)
|
updateStateTo(SyncState.IDLE)
|
||||||
}
|
}
|
||||||
|
@ -60,19 +62,18 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
|
||||||
}
|
}
|
||||||
|
|
||||||
fun restart() = synchronized(lock) {
|
fun restart() = synchronized(lock) {
|
||||||
if (state is SyncState.PAUSED) {
|
if (!isStarted) {
|
||||||
Timber.v("Resume sync...")
|
Timber.v("Resume sync...")
|
||||||
updateStateTo(SyncState.RUNNING(afterPause = true))
|
isStarted = true
|
||||||
lock.notify()
|
lock.notify()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun pause() = synchronized(lock) {
|
fun pause() = synchronized(lock) {
|
||||||
if (state is SyncState.RUNNING) {
|
if (isStarted) {
|
||||||
Timber.v("Pause sync...")
|
Timber.v("Pause sync...")
|
||||||
updateStateTo(SyncState.PAUSED)
|
isStarted = false
|
||||||
cancelableTask?.cancel()
|
cancelableTask?.cancel()
|
||||||
lock.notify()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,21 +88,31 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
|
||||||
return liveState
|
return liveState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onConnect() {
|
||||||
|
Timber.v("Network is back")
|
||||||
|
synchronized(lock) {
|
||||||
|
lock.notify()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
Timber.v("Start syncing...")
|
Timber.v("Start syncing...")
|
||||||
|
isStarted = true
|
||||||
networkConnectivityChecker.register(this)
|
networkConnectivityChecker.register(this)
|
||||||
backgroundDetectionObserver.register(this)
|
backgroundDetectionObserver.register(this)
|
||||||
|
|
||||||
while (state != SyncState.KILLING) {
|
while (state != SyncState.KILLING) {
|
||||||
Timber.v("Entering loop, state: $state")
|
Timber.v("Entering loop, state: $state")
|
||||||
|
|
||||||
if (!networkConnectivityChecker.isConnected() || state == SyncState.PAUSED) {
|
if (!networkConnectivityChecker.hasInternetAccess) {
|
||||||
Timber.v("No network or sync is Paused. Waiting...")
|
Timber.v("No network. Waiting...")
|
||||||
updateStateTo(SyncState.NO_NETWORK)
|
updateStateTo(SyncState.NO_NETWORK)
|
||||||
|
synchronized(lock) { lock.wait() }
|
||||||
synchronized(lock) {
|
Timber.v("...unlocked")
|
||||||
lock.wait()
|
} else if (!isStarted) {
|
||||||
}
|
Timber.v("Sync is Paused. Waiting...")
|
||||||
|
updateStateTo(SyncState.PAUSED)
|
||||||
|
synchronized(lock) { lock.wait() }
|
||||||
Timber.v("...unlocked")
|
Timber.v("...unlocked")
|
||||||
} else {
|
} else {
|
||||||
if (state !is SyncState.RUNNING) {
|
if (state !is SyncState.RUNNING) {
|
||||||
|
@ -169,16 +180,11 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateStateTo(newState: SyncState) {
|
private fun updateStateTo(newState: SyncState) {
|
||||||
Timber.v("Update state to $newState")
|
Timber.v("Update state from $state to $newState")
|
||||||
state = newState
|
state = newState
|
||||||
liveState.postValue(newState)
|
liveState.postValue(newState)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onConnect() {
|
|
||||||
synchronized(lock) {
|
|
||||||
lock.notify()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMoveToForeground() {
|
override fun onMoveToForeground() {
|
||||||
restart()
|
restart()
|
||||||
|
|
|
@ -33,7 +33,7 @@ internal class BackgroundDetectionObserver @Inject constructor() : LifecycleObse
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private
|
private
|
||||||
val listeners = ArrayList<Listener>()
|
val listeners = LinkedHashSet<Listener>()
|
||||||
|
|
||||||
fun register(listener: Listener) {
|
fun register(listener: Listener) {
|
||||||
listeners.add(listener)
|
listeners.add(listener)
|
||||||
|
|
|
@ -38,6 +38,6 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute
|
||||||
is SyncState.RUNNING -> if (newState.afterPause) View.VISIBLE else View.GONE
|
is SyncState.RUNNING -> if (newState.afterPause) View.VISIBLE else View.GONE
|
||||||
else -> View.GONE
|
else -> View.GONE
|
||||||
}
|
}
|
||||||
syncStateNoNetwork.isVisible = newState is SyncState.NO_NETWORK
|
syncStateNoNetwork.isVisible = newState == SyncState.NO_NETWORK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue