Files
ReSearch/app/src/main/java/com/example/research/ReSearchApplication.kt
T
OneWay 8c6e43f3db fix: latch terminal notification state and post pipeline progress on one thread
A late ImportState Success snapshot collected after the success
notification overwrote it with an ongoing progress record. Post
progress on Main behind a volatile terminal latch; notifications go
through NotificationPort, the pipeline lives in the coordinator, and
the service finish is injected.
2026-09-06 15:32:35 +08:00

131 lines
5.2 KiB
Kotlin

package com.example.research
import android.app.Application
import com.example.research.common.progress.DictionaryProgressStateHolder
import com.example.research.common.util.NotificationHelper
import com.example.research.data.local.preferences.PreferencesManager
import com.example.research.data.repository.LocalDictionaryRepository
import com.example.research.feature.download.DownloadManager
import com.example.research.feature.download.repository.DictionaryRepository
import com.example.research.common.util.FileStorageManager
import com.example.research.feature.import.DictionaryImportManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import okhttp3.Protocol
class ReSearchApplication : Application() {
lateinit var preferencesManager: PreferencesManager
private set
lateinit var localDictionaryRepository: LocalDictionaryRepository
private set
lateinit var downloadDictionaryRepository: DictionaryRepository
private set
lateinit var downloadManager: DownloadManager
private set
lateinit var dictionaryImportManager: DictionaryImportManager
private set
lateinit var okHttpClient: OkHttpClient
private set
lateinit var dictionaryProgressStateHolder: DictionaryProgressStateHolder
private set
lateinit var dictionaryProgressPresenter: com.example.research.common.progress.DictionaryProgressPresenter
private set
lateinit var dictionaryPipelineCoordinator: com.example.research.common.progress.DictionaryPipelineCoordinator
private set
private val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
override fun onCreate() {
super.onCreate()
val notificationHelper = NotificationHelper(this)
notificationHelper.cancelProgressNotification()
preferencesManager = PreferencesManager(this)
applicationScope.launch(Dispatchers.IO) {
preferencesManager.sanitizeDictionarySources()
}
localDictionaryRepository = LocalDictionaryRepository(this, preferencesManager = preferencesManager)
okHttpClient = OkHttpClient.Builder()
.protocols(listOf(Protocol.HTTP_1_1))
.build()
val fileStorageManager = FileStorageManager()
downloadDictionaryRepository = DictionaryRepository(
context = this,
preferencesManager = preferencesManager,
fileStorageManager = fileStorageManager,
client = okHttpClient
)
downloadManager = DownloadManager(
dictionaryRepository = downloadDictionaryRepository,
unknownErrorMessage = getString(R.string.unknown_error),
sourceUnavailableMessage = getString(R.string.download_file_not_found)
)
dictionaryImportManager = DictionaryImportManager(
application = this
)
dictionaryProgressStateHolder = DictionaryProgressStateHolder(
scope = applicationScope,
downloadManager = downloadManager,
dictionaryImportManager = dictionaryImportManager,
localDictionaryRepository = localDictionaryRepository,
)
dictionaryProgressPresenter = com.example.research.common.progress.DictionaryProgressPresenter(
scope = applicationScope,
progressSnapshot = dictionaryProgressStateHolder.progressSnapshot,
notifications = notificationHelper,
)
dictionaryPipelineCoordinator = com.example.research.common.progress.DictionaryPipelineCoordinator(
scope = applicationScope,
steps = com.example.research.common.progress.DefaultReindexingSteps(
localDictionaryRepository = localDictionaryRepository,
downloadDictionaryRepository = downloadDictionaryRepository,
),
importOperations = dictionaryImportManager,
ui = dictionaryProgressPresenter,
dictionaryPath = { preferencesManager.dictionaryPath },
finishService = {
val intent = android.content.Intent(
this,
com.example.research.feature.download.service.DictionaryForegroundService::class.java
).apply {
action = com.example.research.feature.download.service.DictionaryForegroundService.ACTION_FINISH
}
try {
startService(intent)
} catch (_: Exception) {
}
},
)
dictionaryImportManager.onFlowStarted = { dictionaryProgressPresenter.beginFlow() }
dictionaryImportManager.onTerminal = dictionaryPipelineCoordinator::onImportTerminal
downloadManager.onFlowStarted = { dictionaryProgressPresenter.beginFlow() }
downloadManager.onDownloadSuccess = dictionaryPipelineCoordinator::onDownloadSuccess
downloadManager.onTerminal = dictionaryPipelineCoordinator::onDownloadTerminal
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
if (::localDictionaryRepository.isInitialized) {
localDictionaryRepository.trimMemory(level)
}
}
}