forked from GitHub-Mirror/riotX-android
Pause/Resume sync thread when app goes background/foreground
This commit is contained in:
@ -1,12 +1,13 @@
|
||||
package im.vector.matrix.android.api
|
||||
|
||||
import android.arch.lifecycle.ProcessLifecycleOwner
|
||||
import android.content.Context
|
||||
import com.evernote.android.job.JobManager
|
||||
import im.vector.matrix.android.api.auth.Authenticator
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.internal.auth.AuthModule
|
||||
import im.vector.matrix.android.internal.di.MatrixModule
|
||||
import im.vector.matrix.android.internal.di.NetworkModule
|
||||
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
|
||||
import io.realm.Realm
|
||||
import org.koin.standalone.KoinComponent
|
||||
import org.koin.standalone.StandAloneContext.loadKoinModules
|
||||
@ -16,16 +17,17 @@ import org.koin.standalone.inject
|
||||
class Matrix(matrixOptions: MatrixOptions) : KoinComponent {
|
||||
|
||||
private val authenticator by inject<Authenticator>()
|
||||
private val backgroundDetectionObserver by inject<BackgroundDetectionObserver>()
|
||||
|
||||
var currentSession: Session? = null
|
||||
|
||||
init {
|
||||
Realm.init(matrixOptions.context)
|
||||
JobManager.create(matrixOptions.context)
|
||||
val matrixModule = MatrixModule(matrixOptions)
|
||||
val networkModule = NetworkModule()
|
||||
val authModule = AuthModule()
|
||||
loadKoinModules(listOf(matrixModule, networkModule, authModule))
|
||||
ProcessLifecycleOwner.get().lifecycle.addObserver(backgroundDetectionObserver)
|
||||
}
|
||||
|
||||
fun authenticator(): Authenticator {
|
||||
|
@ -2,6 +2,7 @@ package im.vector.matrix.android.internal.di
|
||||
|
||||
import im.vector.matrix.android.api.MatrixOptions
|
||||
import im.vector.matrix.android.api.thread.MainThreadExecutor
|
||||
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
@ -22,5 +23,10 @@ class MatrixModule(private val options: MatrixOptions) : Module {
|
||||
single {
|
||||
MatrixCoroutineDispatchers(io = Dispatchers.IO, computation = Dispatchers.IO, main = MainThreadExecutor().asCoroutineDispatcher())
|
||||
}
|
||||
|
||||
single {
|
||||
BackgroundDetectionObserver()
|
||||
}
|
||||
|
||||
}.invoke()
|
||||
}
|
@ -34,7 +34,7 @@ class SyncModule : Module {
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
SyncThread(get(), get(), get())
|
||||
SyncThread(get(), get(), get(), get())
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,6 +7,7 @@ import im.vector.matrix.android.internal.events.sync.SyncRequest
|
||||
import im.vector.matrix.android.internal.events.sync.SyncTokenStore
|
||||
import im.vector.matrix.android.internal.events.sync.data.SyncResponse
|
||||
import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
|
||||
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
@ -14,8 +15,9 @@ private const val RETRY_WAIT_TIME_MS = 10_000L
|
||||
|
||||
class SyncThread(private val syncRequest: SyncRequest,
|
||||
private val networkConnectivityChecker: NetworkConnectivityChecker,
|
||||
private val syncTokenStore: SyncTokenStore
|
||||
) : Thread(), NetworkConnectivityChecker.Listener {
|
||||
private val syncTokenStore: SyncTokenStore,
|
||||
private val backgroundDetectionObserver: BackgroundDetectionObserver
|
||||
) : Thread(), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener {
|
||||
|
||||
enum class State {
|
||||
IDLE,
|
||||
@ -63,8 +65,9 @@ class SyncThread(private val syncRequest: SyncRequest,
|
||||
|
||||
override fun run() {
|
||||
Timber.v("Start syncing...")
|
||||
state = State.RUNNING
|
||||
networkConnectivityChecker.register(this)
|
||||
backgroundDetectionObserver.register(this)
|
||||
state = State.RUNNING
|
||||
while (state != State.KILLING) {
|
||||
if (!networkConnectivityChecker.isConnected() || state == State.PAUSED) {
|
||||
Timber.v("Waiting...")
|
||||
@ -94,6 +97,7 @@ class SyncThread(private val syncRequest: SyncRequest,
|
||||
}
|
||||
Timber.v("Sync killed")
|
||||
state = State.KILLED
|
||||
backgroundDetectionObserver.unregister(this)
|
||||
networkConnectivityChecker.unregister(this)
|
||||
}
|
||||
|
||||
@ -103,6 +107,15 @@ class SyncThread(private val syncRequest: SyncRequest,
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMoveToForeground() {
|
||||
restart()
|
||||
}
|
||||
|
||||
override fun onMoveToBackground() {
|
||||
pause()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,46 @@
|
||||
package im.vector.matrix.android.internal.util
|
||||
|
||||
import android.arch.lifecycle.Lifecycle
|
||||
import android.arch.lifecycle.LifecycleObserver
|
||||
import android.arch.lifecycle.OnLifecycleEvent
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* To be attached to ProcessLifecycleOwner lifecycle
|
||||
*/
|
||||
class BackgroundDetectionObserver : LifecycleObserver {
|
||||
|
||||
var isIsBackground: Boolean = false
|
||||
private set
|
||||
|
||||
private
|
||||
val listeners = ArrayList<Listener>()
|
||||
|
||||
fun register(listener: Listener) {
|
||||
listeners.add(listener)
|
||||
}
|
||||
|
||||
fun unregister(listener: Listener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_START)
|
||||
fun onMoveToForeground() {
|
||||
Timber.d("App returning to foreground…")
|
||||
isIsBackground = false
|
||||
listeners.forEach { it.onMoveToForeground() }
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
|
||||
fun onMoveToBackground() {
|
||||
Timber.d("App going to background…")
|
||||
isIsBackground = true
|
||||
listeners.forEach { it.onMoveToBackground() }
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
fun onMoveToForeground()
|
||||
fun onMoveToBackground()
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user