music: fix threading problems
Fix issues with the current threading approach with the new parallel music loader.
This commit is contained in:
parent
1df1d40408
commit
4afe91e4e8
4 changed files with 17 additions and 6 deletions
|
@ -28,6 +28,7 @@ import androidx.core.database.getIntOrNull
|
|||
import androidx.core.database.getStringOrNull
|
||||
import java.io.File
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.yield
|
||||
import org.oxycblt.auxio.music.MusicSettings
|
||||
import org.oxycblt.auxio.music.library.RealSong
|
||||
import org.oxycblt.auxio.music.metadata.Date
|
||||
|
@ -231,6 +232,7 @@ private abstract class RealMediaStoreExtractor(private val context: Context) : M
|
|||
populateMetadata(cursor, rawSong)
|
||||
incompleteSongs.send(rawSong)
|
||||
}
|
||||
yield()
|
||||
}
|
||||
// Free the cursor and signal that no more incomplete songs will be produced by
|
||||
// this extractor.
|
||||
|
|
|
@ -22,6 +22,7 @@ import androidx.core.text.isDigitsOnly
|
|||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.MetadataRetriever
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.yield
|
||||
import org.oxycblt.auxio.music.library.RealSong
|
||||
import org.oxycblt.auxio.music.metadata.Date
|
||||
import org.oxycblt.auxio.music.metadata.TextTags
|
||||
|
@ -53,7 +54,13 @@ class MetadataExtractor(private val context: Context) {
|
|||
for (i in taskPool.indices) {
|
||||
val task = taskPool[i]
|
||||
if (task != null) {
|
||||
completeSongs.send(task.get() ?: continue)
|
||||
val finishedRawSong = task.get()
|
||||
if (finishedRawSong != null) {
|
||||
completeSongs.send(finishedRawSong)
|
||||
yield()
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
val result = incompleteSongs.tryReceive()
|
||||
if (result.isClosed) {
|
||||
|
@ -73,6 +80,7 @@ class MetadataExtractor(private val context: Context) {
|
|||
if (finishedRawSong != null) {
|
||||
completeSongs.send(finishedRawSong)
|
||||
taskPool[i] = null
|
||||
yield()
|
||||
} else {
|
||||
ongoingTasks = true
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.LinkedList
|
|||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -99,8 +100,9 @@ interface Indexer {
|
|||
* @param withCache Whether to use the cache or not when loading. If false, the cache will still
|
||||
* be written, but no cache entries will be loaded into the new library.
|
||||
* @param scope The [CoroutineScope] to run the indexing job in.
|
||||
* @return The [Job] stacking the indexing status.
|
||||
*/
|
||||
fun index(context: Context, withCache: Boolean, scope: CoroutineScope)
|
||||
fun index(context: Context, withCache: Boolean, scope: CoroutineScope): Job
|
||||
|
||||
/**
|
||||
* Request that the music library should be reloaded. This should be used by components that do
|
||||
|
@ -293,7 +295,7 @@ private class RealIndexer : Indexer {
|
|||
this.listener = null
|
||||
}
|
||||
|
||||
override fun index(context: Context, withCache: Boolean, scope: CoroutineScope) {
|
||||
override fun index(context: Context, withCache: Boolean, scope: CoroutineScope) =
|
||||
scope.launch {
|
||||
val result =
|
||||
try {
|
||||
|
@ -315,7 +317,6 @@ private class RealIndexer : Indexer {
|
|||
}
|
||||
emitCompletion(result)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun requestReindex(withCache: Boolean) {
|
||||
|
|
|
@ -119,11 +119,11 @@ class IndexerService : Service(), Indexer.Controller, MusicSettings.Listener {
|
|||
override fun onStartIndexing(withCache: Boolean) {
|
||||
if (indexer.isIndexing) {
|
||||
// Cancel the previous music loading job.
|
||||
indexScope.cancel()
|
||||
currentIndexJob?.cancel()
|
||||
indexer.reset()
|
||||
}
|
||||
// Start a new music loading job on a co-routine.
|
||||
indexer.index(this@IndexerService, withCache, indexScope)
|
||||
currentIndexJob = indexer.index(this@IndexerService, withCache, indexScope)
|
||||
}
|
||||
|
||||
override fun onIndexerStateChanged(state: Indexer.State?) {
|
||||
|
|
Loading…
Reference in a new issue