Prevent callbacks called in main

This commit is contained in:
Mygod
2019-07-30 10:08:12 +08:00
parent 4f7f778114
commit 193a918fce
2 changed files with 35 additions and 27 deletions

View File

@@ -2,6 +2,8 @@ package be.mygod.vpnhotspot.net.monitor
import android.content.SharedPreferences import android.content.SharedPreferences
import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.App.Companion.app
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
abstract class FallbackUpstreamMonitor private constructor() : UpstreamMonitor() { abstract class FallbackUpstreamMonitor private constructor() : UpstreamMonitor() {
companion object : SharedPreferences.OnSharedPreferenceChangeListener { companion object : SharedPreferences.OnSharedPreferenceChangeListener {
@@ -21,19 +23,21 @@ abstract class FallbackUpstreamMonitor private constructor() : UpstreamMonitor()
fun unregisterCallback(callback: Callback) = synchronized(this) { monitor.unregisterCallback(callback) } fun unregisterCallback(callback: Callback) = synchronized(this) { monitor.unregisterCallback(callback) }
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
if (key == KEY) synchronized(this) { if (key == KEY) GlobalScope.launch { // prevent callback called in main
val old = monitor synchronized(this) {
val callbacks = synchronized(old) { val old = monitor
val callbacks = old.callbacks.toList() val callbacks = synchronized(old) {
old.callbacks.clear() val callbacks = old.callbacks.toList()
old.destroyLocked() old.callbacks.clear()
callbacks old.destroyLocked()
} callbacks
val new = generateMonitor() }
monitor = new val new = generateMonitor()
for (callback in callbacks) { monitor = new
callback.onLost() for (callback in callbacks) {
new.registerCallback(callback) callback.onLost()
new.registerCallback(callback)
}
} }
} }
} }

View File

@@ -3,6 +3,8 @@ package be.mygod.vpnhotspot.net.monitor
import android.content.SharedPreferences import android.content.SharedPreferences
import android.net.LinkProperties import android.net.LinkProperties
import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.App.Companion.app
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.lang.UnsupportedOperationException import java.lang.UnsupportedOperationException
import java.net.InetAddress import java.net.InetAddress
import java.util.* import java.util.*
@@ -26,20 +28,22 @@ abstract class UpstreamMonitor {
fun unregisterCallback(callback: Callback) = synchronized(this) { monitor.unregisterCallback(callback) } fun unregisterCallback(callback: Callback) = synchronized(this) { monitor.unregisterCallback(callback) }
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
if (key == KEY) synchronized(this) { if (key == KEY) GlobalScope.launch { // prevent callback called in main
val old = monitor synchronized(this) {
val (active, callbacks) = synchronized(old) { val old = monitor
val active = old.currentIface != null val (active, callbacks) = synchronized(old) {
val callbacks = old.callbacks.toList() val active = old.currentIface != null
old.callbacks.clear() val callbacks = old.callbacks.toList()
old.destroyLocked() old.callbacks.clear()
Pair(active, callbacks) old.destroyLocked()
} Pair(active, callbacks)
val new = generateMonitor() }
monitor = new val new = generateMonitor()
for (callback in callbacks) { monitor = new
if (active) callback.onLost() for (callback in callbacks) {
new.registerCallback(callback) if (active) callback.onLost()
new.registerCallback(callback)
}
} }
} }
} }