From 45183df640516b1d75068c952f6915fd36ba2bbc Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Tue, 30 Apr 2024 17:02:05 +0800 Subject: [PATCH] Avoid packing/unpacking and use pre-allocated list --- .../hippo/unifile/DocumentsContractApi21.kt | 18 ---------- .../com/hippo/unifile/TreeDocumentFile.kt | 33 +++++++++++++++---- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/app/src/main/kotlin/com/hippo/unifile/DocumentsContractApi21.kt b/app/src/main/kotlin/com/hippo/unifile/DocumentsContractApi21.kt index e466ab022..a9fe10a70 100644 --- a/app/src/main/kotlin/com/hippo/unifile/DocumentsContractApi21.kt +++ b/app/src/main/kotlin/com/hippo/unifile/DocumentsContractApi21.kt @@ -21,11 +21,6 @@ import splitties.init.appCtx object DocumentsContractApi21 { private val resolver = appCtx.contentResolver - private val projection = arrayOf( - DocumentsContract.Document.COLUMN_DOCUMENT_ID, - DocumentsContract.Document.COLUMN_DISPLAY_NAME, - DocumentsContract.Document.COLUMN_MIME_TYPE, - ) fun createFile(self: Uri, mimeType: String, displayName: String) = runCatching { DocumentsContract.createDocument(resolver, self, mimeType, displayName) @@ -49,19 +44,6 @@ object DocumentsContractApi21 { ) } - fun listFiles(self: Uri) = sequence { - val childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(self, DocumentsContract.getDocumentId(self)) - resolver.query(childrenUri, projection, null, null, null)?.use { - while (it.moveToNext()) { - val documentId = it.getString(0) - val documentUri = DocumentsContract.buildDocumentUriUsingTree(self, documentId) - val displayName = it.getString(1) - val mimeType = it.getString(2) - yield(Triple(documentUri, displayName, mimeType)) - } - } - } - fun renameTo(self: Uri, displayName: String) = runCatching { DocumentsContract.renameDocument(resolver, self, displayName) }.getOrNull() diff --git a/app/src/main/kotlin/com/hippo/unifile/TreeDocumentFile.kt b/app/src/main/kotlin/com/hippo/unifile/TreeDocumentFile.kt index b5fcbeb35..67245713b 100644 --- a/app/src/main/kotlin/com/hippo/unifile/TreeDocumentFile.kt +++ b/app/src/main/kotlin/com/hippo/unifile/TreeDocumentFile.kt @@ -16,8 +16,10 @@ package com.hippo.unifile import android.net.Uri -import android.provider.DocumentsContract.Document.MIME_TYPE_DIR +import android.provider.DocumentsContract +import android.provider.DocumentsContract.Document import android.webkit.MimeTypeMap +import splitties.init.appCtx class TreeDocumentFile( override val parent: TreeDocumentFile?, @@ -28,9 +30,7 @@ class TreeDocumentFile( private var cachePresent = false private val allChildren by lazy { cachePresent = true - DocumentsContractApi21.listFiles(uri).mapTo(mutableListOf()) { (uri, name, mimeType) -> - TreeDocumentFile(this, uri, name, mimeType) - } + queryChildren() } private fun popCacheIfPresent(file: TreeDocumentFile) { @@ -73,7 +73,7 @@ class TreeDocumentFile( } else { val result = DocumentsContractApi21.createDirectory(uri, displayName) if (result != null) { - val d = TreeDocumentFile(this, result, displayName, MIME_TYPE_DIR) + val d = TreeDocumentFile(this, result, displayName, Document.MIME_TYPE_DIR) popCacheIfPresent(d) return d } @@ -96,7 +96,7 @@ class TreeDocumentFile( override val type: String? get() = mimeType.takeUnless { isDirectory } override val isDirectory: Boolean - get() = mimeType == MIME_TYPE_DIR + get() = mimeType == Document.MIME_TYPE_DIR override val isFile: Boolean get() = !type.isNullOrEmpty() @@ -164,3 +164,24 @@ private fun getFilenameForUri(uri: Uri): String { val path = requireNotNull(uri.path) return path.substringAfterLast('/') } + +private val projection = arrayOf( + Document.COLUMN_DOCUMENT_ID, + Document.COLUMN_DISPLAY_NAME, + Document.COLUMN_MIME_TYPE, +) + +private fun TreeDocumentFile.queryChildren(): MutableList { + val self = uri + val childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(self, DocumentsContract.getDocumentId(self)) + return appCtx.contentResolver.query(childrenUri, projection, null, null, null)?.use { c -> + MutableList(c.count) { + c.moveToNext() + val documentId = c.getString(0) + val documentUri = DocumentsContract.buildDocumentUriUsingTree(self, documentId) + val displayName = c.getString(1) + val mimeType = c.getString(2) + TreeDocumentFile(this, documentUri, displayName, mimeType) + } + } ?: mutableListOf() +}