SyncThread: Fix issue when network is back and the app was in background: do not restart the thread

This commit is contained in:
Benoit Marty 2019-09-17 14:26:30 +02:00
parent 73ec0f5a83
commit 25e9a179d2
5 changed files with 30 additions and 27 deletions

View File

@ -36,7 +36,8 @@ internal class NetworkConnectivityChecker @Inject constructor(context: Context)
private val listeners = Collections.synchronizedSet(LinkedHashSet<Listener>())
// True when internet is available
private var hasInternetAccess = false
var hasInternetAccess = false
private set
init {
merlin.bind()
@ -63,7 +64,7 @@ internal class NetworkConnectivityChecker @Inject constructor(context: Context)
}
suspend fun waitUntilConnected() {
if (isConnected()) {
if (hasInternetAccess) {
return
} else {
suspendCoroutine<Unit> { continuation ->
@ -85,10 +86,6 @@ internal class NetworkConnectivityChecker @Inject constructor(context: Context)
listeners.remove(listener)
}
fun isConnected(): Boolean {
return hasInternetAccess
}
interface Listener {
fun onConnect() {

View File

@ -93,8 +93,8 @@ open class SyncService : Service() {
}
fun doSync(once: Boolean = false) {
if (!networkConnectivityChecker.isConnected()) {
Timber.v("Sync is Paused. Waiting...")
if (!networkConnectivityChecker.hasInternetAccess) {
Timber.v("No internet access. Waiting...")
//TODO Retry in ?
timer.schedule(object : TimerTask() {
override fun run() {

View File

@ -50,6 +50,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
private val lock = Object()
private var cancelableTask: Cancelable? = null
private var isStarted = false
init {
updateStateTo(SyncState.IDLE)
}
@ -60,19 +62,18 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
}
fun restart() = synchronized(lock) {
if (state is SyncState.PAUSED) {
if (!isStarted) {
Timber.v("Resume sync...")
updateStateTo(SyncState.RUNNING(afterPause = true))
isStarted = true
lock.notify()
}
}
fun pause() = synchronized(lock) {
if (state is SyncState.RUNNING) {
if (isStarted) {
Timber.v("Pause sync...")
updateStateTo(SyncState.PAUSED)
isStarted = false
cancelableTask?.cancel()
lock.notify()
}
}
@ -87,21 +88,31 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
return liveState
}
override fun onConnect() {
Timber.v("Network is back")
synchronized(lock) {
lock.notify()
}
}
override fun run() {
Timber.v("Start syncing...")
isStarted = true
networkConnectivityChecker.register(this)
backgroundDetectionObserver.register(this)
while (state != SyncState.KILLING) {
Timber.v("Entering loop, state: $state")
if (!networkConnectivityChecker.isConnected() || state == SyncState.PAUSED) {
Timber.v("No network or sync is Paused. Waiting...")
if (!networkConnectivityChecker.hasInternetAccess) {
Timber.v("No network. Waiting...")
updateStateTo(SyncState.NO_NETWORK)
synchronized(lock) {
lock.wait()
}
synchronized(lock) { lock.wait() }
Timber.v("...unlocked")
} else if (!isStarted) {
Timber.v("Sync is Paused. Waiting...")
updateStateTo(SyncState.PAUSED)
synchronized(lock) { lock.wait() }
Timber.v("...unlocked")
} else {
if (state !is SyncState.RUNNING) {
@ -169,16 +180,11 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
}
private fun updateStateTo(newState: SyncState) {
Timber.v("Update state to $newState")
Timber.v("Update state from $state to $newState")
state = newState
liveState.postValue(newState)
}
override fun onConnect() {
synchronized(lock) {
lock.notify()
}
}
override fun onMoveToForeground() {
restart()

View File

@ -33,7 +33,7 @@ internal class BackgroundDetectionObserver @Inject constructor() : LifecycleObse
private set
private
val listeners = ArrayList<Listener>()
val listeners = LinkedHashSet<Listener>()
fun register(listener: Listener) {
listeners.add(listener)

View File

@ -38,6 +38,6 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute
is SyncState.RUNNING -> if (newState.afterPause) View.VISIBLE else View.GONE
else -> View.GONE
}
syncStateNoNetwork.isVisible = newState is SyncState.NO_NETWORK
syncStateNoNetwork.isVisible = newState == SyncState.NO_NETWORK
}
}