mirror of
https://github.com/Aviortheking/Neo-Store.git
synced 2025-04-24 03:42:15 +00:00
Remove: Allowing queries on MainThread
This commit is contained in:
parent
251b6195d6
commit
d427968ccb
@ -86,7 +86,9 @@ class MainApplication : Application(), ImageLoaderFactory {
|
|||||||
val installedItems =
|
val installedItems =
|
||||||
packageManager.getInstalledPackages(Android.PackageManager.signaturesFlag)
|
packageManager.getInstalledPackages(Android.PackageManager.signaturesFlag)
|
||||||
.map { it.toInstalledItem() }
|
.map { it.toInstalledItem() }
|
||||||
db.installedDao.put(*installedItems.toTypedArray())
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
|
db.installedDao.put(*installedItems.toTypedArray())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun listenPreferences() {
|
private fun listenPreferences() {
|
||||||
|
@ -12,7 +12,6 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
@ -27,23 +26,23 @@ object ProductPreferences {
|
|||||||
fun init(context: Context) {
|
fun init(context: Context) {
|
||||||
db = DatabaseX.getInstance(context)
|
db = DatabaseX.getInstance(context)
|
||||||
preferences = context.getSharedPreferences("product_preferences", Context.MODE_PRIVATE)
|
preferences = context.getSharedPreferences("product_preferences", Context.MODE_PRIVATE)
|
||||||
db.lockDao.insert(*preferences.all.keys
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
.mapNotNull { pName ->
|
db.lockDao.insert(*preferences.all.keys
|
||||||
this[pName].databaseVersionCode?.let {
|
.mapNotNull { pName ->
|
||||||
Lock().apply {
|
this@ProductPreferences[pName].databaseVersionCode?.let {
|
||||||
package_name = pName
|
Lock().apply {
|
||||||
version_code = it
|
package_name = pName
|
||||||
|
version_code = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.toTypedArray()
|
||||||
.toTypedArray()
|
)
|
||||||
)
|
|
||||||
CoroutineScope(Dispatchers.Default).launch {
|
|
||||||
subject.collect { (packageName, versionCode) ->
|
subject.collect { (packageName, versionCode) ->
|
||||||
if (versionCode != null) db.lockDao.insert(Lock().apply {
|
if (versionCode != null) db.lockDao.insert(Lock().apply {
|
||||||
package_name = packageName
|
package_name = packageName
|
||||||
version_code = versionCode
|
version_code = versionCode
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
else db.lockDao.delete(packageName)
|
else db.lockDao.delete(packageName)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,9 @@ import androidx.room.Room
|
|||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
import com.looker.droidify.entity.Repository.Companion.defaultRepositories
|
import com.looker.droidify.entity.Repository.Companion.defaultRepositories
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
entities = [
|
entities = [
|
||||||
@ -42,11 +45,12 @@ abstract class DatabaseX : RoomDatabase() {
|
|||||||
"main_database.db"
|
"main_database.db"
|
||||||
)
|
)
|
||||||
.fallbackToDestructiveMigration()
|
.fallbackToDestructiveMigration()
|
||||||
.allowMainThreadQueries()
|
|
||||||
.build()
|
.build()
|
||||||
INSTANCE?.let { instance ->
|
INSTANCE?.let { instance ->
|
||||||
if (instance.repositoryDao.count == 0) defaultRepositories.forEach {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
instance.repositoryDao.put(it)
|
if (instance.repositoryDao.count == 0) defaultRepositories.forEach {
|
||||||
|
instance.repositoryDao.put(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,9 +99,11 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun sync(request: SyncRequest) {
|
fun sync(request: SyncRequest) {
|
||||||
val ids = db.repositoryDao.all.mapNotNull { it.trueData }
|
GlobalScope.launch {
|
||||||
.asSequence().filter { it.enabled }.map { it.id }.toList()
|
val ids = db.repositoryDao.all.mapNotNull { it.trueData }
|
||||||
sync(ids, request)
|
.asSequence().filter { it.enabled }.map { it.id }.toList()
|
||||||
|
sync(ids, request)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sync(repository: Repository) {
|
fun sync(repository: Repository) {
|
||||||
@ -332,92 +334,94 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
|
|
||||||
private fun handleNextTask(hasUpdates: Boolean) {
|
private fun handleNextTask(hasUpdates: Boolean) {
|
||||||
if (currentTask == null) {
|
if (currentTask == null) {
|
||||||
if (tasks.isNotEmpty()) {
|
GlobalScope.launch {
|
||||||
val task = tasks.removeAt(0)
|
if (tasks.isNotEmpty()) {
|
||||||
val repository = db.repositoryDao.get(task.repositoryId)?.trueData
|
val task = tasks.removeAt(0)
|
||||||
if (repository != null && repository.enabled) {
|
val repository = db.repositoryDao.get(task.repositoryId)?.trueData
|
||||||
val lastStarted = started
|
if (repository != null && repository.enabled) {
|
||||||
val newStarted =
|
val lastStarted = started
|
||||||
if (task.manual || lastStarted == Started.MANUAL) Started.MANUAL else Started.AUTO
|
val newStarted =
|
||||||
started = newStarted
|
if (task.manual || lastStarted == Started.MANUAL) Started.MANUAL else Started.AUTO
|
||||||
if (newStarted == Started.MANUAL && lastStarted != Started.MANUAL) {
|
started = newStarted
|
||||||
startSelf()
|
if (newStarted == Started.MANUAL && lastStarted != Started.MANUAL) {
|
||||||
handleSetStarted()
|
startSelf()
|
||||||
}
|
handleSetStarted()
|
||||||
val initialState = State.Connecting(repository.name)
|
}
|
||||||
publishForegroundState(true, initialState)
|
val initialState = State.Connecting(repository.name)
|
||||||
val unstable = Preferences[Preferences.Key.UpdateUnstable]
|
publishForegroundState(true, initialState)
|
||||||
lateinit var disposable: Disposable
|
val unstable = Preferences[Preferences.Key.UpdateUnstable]
|
||||||
disposable = RepositoryUpdater
|
lateinit var disposable: Disposable
|
||||||
.update(this, repository, unstable) { stage, progress, total ->
|
disposable = RepositoryUpdater
|
||||||
if (!disposable.isDisposed) {
|
.update(this@SyncService, repository, unstable) { stage, progress, total ->
|
||||||
scope.launch {
|
if (!disposable.isDisposed) {
|
||||||
mutableStateSubject.emit(
|
scope.launch {
|
||||||
State.Syncing(
|
mutableStateSubject.emit(
|
||||||
repository.name,
|
State.Syncing(
|
||||||
stage,
|
repository.name,
|
||||||
progress,
|
stage,
|
||||||
total
|
progress,
|
||||||
|
total
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe { result, throwable ->
|
||||||
|
currentTask = null
|
||||||
|
throwable?.printStackTrace()
|
||||||
|
if (throwable != null && task.manual) {
|
||||||
|
showNotificationError(repository, throwable as Exception)
|
||||||
|
}
|
||||||
|
handleNextTask(result == true || hasUpdates)
|
||||||
|
}
|
||||||
|
currentTask = CurrentTask(task, disposable, hasUpdates, initialState)
|
||||||
|
} else {
|
||||||
|
handleNextTask(hasUpdates)
|
||||||
|
}
|
||||||
|
} else if (started != Started.NO) {
|
||||||
|
val disposable = RxUtils
|
||||||
|
.querySingle { it ->
|
||||||
|
db.productDao
|
||||||
|
.query(
|
||||||
|
installed = true,
|
||||||
|
updates = true,
|
||||||
|
searchQuery = "",
|
||||||
|
section = ProductItem.Section.All,
|
||||||
|
order = ProductItem.Order.NAME,
|
||||||
|
signal = it
|
||||||
|
)
|
||||||
|
.use {
|
||||||
|
it.asSequence().map { it.getProductItem() }
|
||||||
|
.toList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe { result, throwable ->
|
.subscribe { result, throwable ->
|
||||||
currentTask = null
|
|
||||||
throwable?.printStackTrace()
|
throwable?.printStackTrace()
|
||||||
if (throwable != null && task.manual) {
|
currentTask = null
|
||||||
showNotificationError(repository, throwable as Exception)
|
handleNextTask(false)
|
||||||
|
if (result.isNotEmpty()) {
|
||||||
|
if (Preferences[Preferences.Key.InstallAfterSync])
|
||||||
|
runAutoUpdate(result)
|
||||||
|
if (hasUpdates && Preferences[Preferences.Key.UpdateNotify] &&
|
||||||
|
updateNotificationBlockerFragment?.get()?.isAdded == true
|
||||||
|
)
|
||||||
|
displayUpdatesNotification(result)
|
||||||
}
|
}
|
||||||
handleNextTask(result == true || hasUpdates)
|
|
||||||
}
|
}
|
||||||
currentTask = CurrentTask(task, disposable, hasUpdates, initialState)
|
if (hasUpdates) {
|
||||||
} else {
|
currentTask = CurrentTask(null, disposable, true, State.Finishing)
|
||||||
handleNextTask(hasUpdates)
|
} else {
|
||||||
}
|
scope.launch { mutableFinishState.emit(Unit) }
|
||||||
} else if (started != Started.NO) {
|
val needStop = started == Started.MANUAL
|
||||||
val disposable = RxUtils
|
started = Started.NO
|
||||||
.querySingle { it ->
|
if (needStop) {
|
||||||
db.productDao
|
stopForeground(true)
|
||||||
.query(
|
stopSelf()
|
||||||
installed = true,
|
|
||||||
updates = true,
|
|
||||||
searchQuery = "",
|
|
||||||
section = ProductItem.Section.All,
|
|
||||||
order = ProductItem.Order.NAME,
|
|
||||||
signal = it
|
|
||||||
)
|
|
||||||
.use {
|
|
||||||
it.asSequence().map { it.getProductItem() }
|
|
||||||
.toList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe { result, throwable ->
|
|
||||||
throwable?.printStackTrace()
|
|
||||||
currentTask = null
|
|
||||||
handleNextTask(false)
|
|
||||||
if (result.isNotEmpty()) {
|
|
||||||
if (Preferences[Preferences.Key.InstallAfterSync])
|
|
||||||
runAutoUpdate(result)
|
|
||||||
if (hasUpdates && Preferences[Preferences.Key.UpdateNotify] &&
|
|
||||||
updateNotificationBlockerFragment?.get()?.isAdded == true
|
|
||||||
)
|
|
||||||
displayUpdatesNotification(result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasUpdates) {
|
|
||||||
currentTask = CurrentTask(null, disposable, true, State.Finishing)
|
|
||||||
} else {
|
|
||||||
scope.launch { mutableFinishState.emit(Unit) }
|
|
||||||
val needStop = started == Started.MANUAL
|
|
||||||
started = Started.NO
|
|
||||||
if (needStop) {
|
|
||||||
stopForeground(true)
|
|
||||||
stopSelf()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ class ExploreFragment : MainNavFragmentX(), CursorOwner.Callback {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
viewModel.fillList(source)
|
//viewModel.fillList(source)
|
||||||
viewModel.db.repositoryDao.allFlowable
|
viewModel.db.repositoryDao.allFlowable
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
.flatMapSingle { list -> RxUtils.querySingle { list.mapNotNull { it.trueData } } }
|
.flatMapSingle { list -> RxUtils.querySingle { list.mapNotNull { it.trueData } } }
|
||||||
|
@ -80,7 +80,7 @@ class InstalledFragment : MainNavFragmentX(), CursorOwner.Callback {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
viewModel.fillList(source)
|
//viewModel.fillList(source)
|
||||||
viewModel.db.repositoryDao.allFlowable
|
viewModel.db.repositoryDao.allFlowable
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
.flatMapSingle { list -> RxUtils.querySingle { list.mapNotNull { it.trueData } } }
|
.flatMapSingle { list -> RxUtils.querySingle { list.mapNotNull { it.trueData } } }
|
||||||
|
@ -80,7 +80,7 @@ class LatestFragment : MainNavFragmentX(), CursorOwner.Callback {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
viewModel.fillList(source)
|
//viewModel.fillList(source)
|
||||||
viewModel.db.repositoryDao.allFlowable
|
viewModel.db.repositoryDao.allFlowable
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
.flatMapSingle { list -> RxUtils.querySingle { list.mapNotNull { it.trueData } } }
|
.flatMapSingle { list -> RxUtils.querySingle { list.mapNotNull { it.trueData } } }
|
||||||
|
@ -18,7 +18,7 @@ abstract class MainNavFragmentX : Fragment(), CursorOwner.Callback {
|
|||||||
internal fun setSearchQuery(searchQuery: String) {
|
internal fun setSearchQuery(searchQuery: String) {
|
||||||
viewModel.setSearchQuery(searchQuery) {
|
viewModel.setSearchQuery(searchQuery) {
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
viewModel.fillList(source)
|
//viewModel.fillList(source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@ abstract class MainNavFragmentX : Fragment(), CursorOwner.Callback {
|
|||||||
internal fun setSection(section: ProductItem.Section) {
|
internal fun setSection(section: ProductItem.Section) {
|
||||||
viewModel.setSection(section) {
|
viewModel.setSection(section) {
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
viewModel.fillList(source)
|
//viewModel.fillList(source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ abstract class MainNavFragmentX : Fragment(), CursorOwner.Callback {
|
|||||||
internal fun setOrder(order: ProductItem.Order) {
|
internal fun setOrder(order: ProductItem.Order) {
|
||||||
viewModel.setOrder(order) {
|
viewModel.setOrder(order) {
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
viewModel.fillList(source)
|
//viewModel.fillList(source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user