Added lazy initialization of DownloadFile status for better SAF performance
Minor fixes
This commit is contained in:
parent
66e7732ec2
commit
d51544f927
|
@ -153,13 +153,27 @@ public class StreamProxy implements Runnable
|
|||
}
|
||||
|
||||
Timber.i("Processing request for file %s", localPath);
|
||||
if (!Storage.INSTANCE.isPathExists(localPath)) {
|
||||
Timber.e("File %s does not exist", localPath);
|
||||
return false;
|
||||
}
|
||||
if (Storage.INSTANCE.isPathExists(localPath)) return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
// Usually the .partial file will be requested here, but sometimes it has already
|
||||
// been renamed, so check if it is completed since
|
||||
String saveFileName = FileUtil.INSTANCE.getSaveFile(localPath);
|
||||
String completeFileName = FileUtil.INSTANCE.getCompleteFile(saveFileName);
|
||||
|
||||
if (Storage.INSTANCE.isPathExists(saveFileName)) {
|
||||
localPath = saveFileName;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Storage.INSTANCE.isPathExists(completeFileName)) {
|
||||
localPath = completeFileName;
|
||||
return true;
|
||||
}
|
||||
|
||||
Timber.e("File %s does not exist", localPath);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
|
|
|
@ -42,8 +42,8 @@ class DownloadFile(
|
|||
save: Boolean
|
||||
) : KoinComponent, Identifiable {
|
||||
val partialFile: String
|
||||
val completeFile: String
|
||||
private val saveFile: String = FileUtil.getSongFile(song)
|
||||
lateinit var completeFile: String
|
||||
val saveFile: String = FileUtil.getSongFile(song)
|
||||
var shouldSave = save
|
||||
private var downloadTask: CancellableTask? = null
|
||||
var isFailed = false
|
||||
|
@ -68,29 +68,30 @@ class DownloadFile(
|
|||
private val activeServerProvider: ActiveServerProvider by inject()
|
||||
|
||||
val progress: MutableLiveData<Int> = MutableLiveData(0)
|
||||
val status: MutableLiveData<DownloadStatus>
|
||||
|
||||
val lazyStatus: Lazy<DownloadStatus> = lazy {
|
||||
when {
|
||||
Storage.isPathExists(saveFile) -> {
|
||||
DownloadStatus.PINNED
|
||||
}
|
||||
Storage.isPathExists(completeFile) -> {
|
||||
DownloadStatus.DONE
|
||||
}
|
||||
else -> {
|
||||
DownloadStatus.IDLE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val status: MutableLiveData<DownloadStatus> by lazy {
|
||||
MutableLiveData(lazyStatus.value)
|
||||
}
|
||||
|
||||
init {
|
||||
val state: DownloadStatus
|
||||
|
||||
partialFile = FileUtil.getParentPath(saveFile) + "/" +
|
||||
FileUtil.getPartialFile(FileUtil.getNameFromPath(saveFile))
|
||||
completeFile = FileUtil.getParentPath(saveFile) + "/" +
|
||||
FileUtil.getCompleteFile(FileUtil.getNameFromPath(saveFile))
|
||||
|
||||
when {
|
||||
Storage.isPathExists(saveFile) -> {
|
||||
state = DownloadStatus.PINNED
|
||||
}
|
||||
Storage.isPathExists(completeFile) -> {
|
||||
state = DownloadStatus.DONE
|
||||
}
|
||||
else -> {
|
||||
state = DownloadStatus.IDLE
|
||||
}
|
||||
}
|
||||
|
||||
status = MutableLiveData(state)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -267,7 +267,8 @@ class Downloader(
|
|||
temp.addAll(downloadQueue)
|
||||
temp.addAll(
|
||||
playlist.filter {
|
||||
when (it.status.value) {
|
||||
if (!it.lazyStatus.isInitialized()) false
|
||||
else when (it.status.value) {
|
||||
DownloadStatus.DOWNLOADING -> true
|
||||
else -> false
|
||||
}
|
||||
|
|
|
@ -259,7 +259,8 @@ class CacheCleaner : CoroutineScope by CoroutineScope(Dispatchers.IO) {
|
|||
|
||||
for (downloadFile in downloader.value.all) {
|
||||
filesToNotDelete.add(downloadFile.partialFile)
|
||||
filesToNotDelete.add(downloadFile.completeOrSaveFile)
|
||||
filesToNotDelete.add(downloadFile.completeFile)
|
||||
filesToNotDelete.add(downloadFile.saveFile)
|
||||
}
|
||||
|
||||
filesToNotDelete.add(musicDirectory.path)
|
||||
|
|
|
@ -401,6 +401,14 @@ object FileUtil {
|
|||
return path.substringBeforeLast('/')
|
||||
}
|
||||
|
||||
fun getSaveFile(name: String): String {
|
||||
val baseName = getBaseName(name)
|
||||
if (baseName.endsWith(".partial") || baseName.endsWith(".complete")) {
|
||||
return "${getBaseName(baseName)}.${getExtension(name)}"
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file name of a .complete file of the given file.
|
||||
*
|
||||
|
|
|
@ -28,24 +28,32 @@ class StorageFile(
|
|||
|
||||
override val length: Long
|
||||
get() {
|
||||
val resolver = UApp.applicationContext().contentResolver
|
||||
val column = arrayOf(DocumentsContract.Document.COLUMN_SIZE)
|
||||
resolver.query(uri, column, null, null, null)?.use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getLong(0)
|
||||
try {
|
||||
val resolver = UApp.applicationContext().contentResolver
|
||||
val column = arrayOf(DocumentsContract.Document.COLUMN_SIZE)
|
||||
resolver.query(uri, column, null, null, null)?.use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getLong(0)
|
||||
}
|
||||
}
|
||||
} catch (_: IllegalArgumentException) {
|
||||
Timber.d("Tried to get length of $uri but it probably doesn't exists")
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
override val lastModified: Long
|
||||
get() {
|
||||
val resolver = UApp.applicationContext().contentResolver
|
||||
val column = arrayOf(DocumentsContract.Document.COLUMN_LAST_MODIFIED)
|
||||
resolver.query(uri, column, null, null, null)?.use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getLong(0)
|
||||
try {
|
||||
val resolver = UApp.applicationContext().contentResolver
|
||||
val column = arrayOf(DocumentsContract.Document.COLUMN_LAST_MODIFIED)
|
||||
resolver.query(uri, column, null, null, null)?.use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getLong(0)
|
||||
}
|
||||
}
|
||||
} catch (_: IllegalArgumentException) {
|
||||
Timber.d("Tried to get length of $uri but it probably doesn't exists")
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
@ -129,7 +137,6 @@ class StorageFile(
|
|||
val fileName = FileUtil.getNameFromPath(path)
|
||||
var file: StorageFile? = null
|
||||
|
||||
Timber.v("StorageFile getFromPath listing files on path: $path")
|
||||
parent.listFiles().forEach {
|
||||
if (it.name == fileName) file = it as StorageFile
|
||||
storageFilePathDictionary[it.path] = it as StorageFile
|
||||
|
|
Loading…
Reference in New Issue