diff --git a/ImagePickerLib/build.gradle b/ImagePickerLib/build.gradle index ca446ab975c4c3511681f6ed46549c712a805940..ea6f2d68e0f82c180970e48c5e5da86f56ba3425 100644 --- a/ImagePickerLib/build.gradle +++ b/ImagePickerLib/build.gradle @@ -33,7 +33,7 @@ afterEvaluate { groupId = 'com.mx.imgpicker' artifactId = 'MXImagePicker' - version = '1.5.3' + version = '1.5.4' } } } diff --git a/ImagePickerLib/src/main/java/com/mx/imgpicker/adapts/FolderAdapt.kt b/ImagePickerLib/src/main/java/com/mx/imgpicker/adapts/FolderAdapt.kt index dc11677a553497f1eaa18c0e840b9b279e55fdd4..548ec8e5f46158e39e38dee9a8081c013965b453 100644 --- a/ImagePickerLib/src/main/java/com/mx/imgpicker/adapts/FolderAdapt.kt +++ b/ImagePickerLib/src/main/java/com/mx/imgpicker/adapts/FolderAdapt.kt @@ -5,14 +5,18 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.lifecycle.LifecycleCoroutineScope import androidx.recyclerview.widget.RecyclerView import com.mx.imgpicker.MXImagePicker import com.mx.imgpicker.R import com.mx.imgpicker.app.picker.MXPickerVM import com.mx.imgpicker.models.MXDirItem +import kotlinx.coroutines.launch -internal class FolderAdapt(private val vm: MXPickerVM) : - RecyclerView.Adapter() { +internal class FolderAdapt( + private val vm: MXPickerVM, + private val lifecycleScope: LifecycleCoroutineScope +) : RecyclerView.Adapter() { var onItemClick: ((item: MXDirItem) -> Unit)? = null class FolderVH(itemView: View) : RecyclerView.ViewHolder(itemView) { @@ -32,8 +36,16 @@ internal class FolderAdapt(private val vm: MXPickerVM) : override fun onBindViewHolder(holder: FolderVH, position: Int) { val item = vm.dirList.getOrNull(position) ?: return val isSelect = (item.path == vm.selectDirLive.value?.path) + + if (item.lastItem == null) { + lifecycleScope.launch { + item.lastItem = vm.sourceDB.queryLastItem(item.path, vm.pickerType) + this@FolderAdapt.notifyItemChanged(position) + } + } + + holder.img.setImageResource(R.drawable.mx_icon_picker_image_place_holder) item.lastItem?.let { imgItem -> - holder.img.setImageResource(R.drawable.mx_icon_picker_image_place_holder) MXImagePicker.getImageLoader()?.invoke(imgItem, holder.img) } holder.folderNameTxv.text = item.name diff --git a/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/MXImgPickerActivity.kt b/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/MXImgPickerActivity.kt index 8d59f92bdecfad27305c3c2c7839cae2d537f797..36a23eaa8aed2244805cab469748b9a8908a7582 100644 --- a/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/MXImgPickerActivity.kt +++ b/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/MXImgPickerActivity.kt @@ -62,6 +62,9 @@ class MXImgPickerActivity : AppCompatActivity() { (intent.getSerializableExtra(MXPickerBuilder.KEY_INTENT_BUILDER) as? MXConfig) ?: MXConfig() ) + lifecycleScope.launch { + vm.reloadMediaList() + } MXUtils.log("启动") val permissions = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE) diff --git a/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/MXPickerVM.kt b/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/MXPickerVM.kt index 5f83b66049ea446440760a251179484f11cf7dac..bdc3ac02f4c25b13ca7ab9eb855134ab1445c471 100644 --- a/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/MXPickerVM.kt +++ b/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/MXPickerVM.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File +import java.util.concurrent.atomic.AtomicBoolean internal class MXPickerVM : ViewModel() { companion object { @@ -25,7 +26,7 @@ internal class MXPickerVM : ViewModel() { private val allResStr by lazy { MXImagePicker.getContext().resources.getString(R.string.mx_picker_string_all) } - private val sourceDB by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + val sourceDB by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { MXDBSource(MXImagePicker.getContext()) } private var isRelease = false @@ -68,19 +69,20 @@ internal class MXPickerVM : ViewModel() { val needCompress = MutableLiveData(true) // 是否需要压缩 val fullScreenSelectIndex = MutableLiveData(0) // 是否需要压缩 + private val scanLock = AtomicBoolean(false) fun startScan() { viewModelScope.launch { + if (scanLock.get()) return@launch + scanLock.set(true) MXUtils.log("开始扫描--> <--") val context = MXImagePicker.getContext() - reloadMediaList() - val scanResult: ((List) -> Boolean) = { list -> viewModelScope.launch { val hasSave = withContext(Dispatchers.IO) { mediaList.containsAll(list) } if (hasSave) return@launch - MXUtils.log("扫描结果--> ${list.size}") +// MXUtils.log("扫描结果--> ${list.size}") sourceDB.addSysSource(list) reloadMediaList() } @@ -98,6 +100,7 @@ internal class MXPickerVM : ViewModel() { reloadMediaList() MXUtils.log("结束扫描--> <--") + scanLock.set(false) } } @@ -106,14 +109,10 @@ internal class MXPickerVM : ViewModel() { } suspend fun reloadMediaList() = withContext(Dispatchers.IO) { + val start = System.currentTimeMillis() val dirs = sourceDB.getAllDirList(pickerType) val dir = selectDirLive.value - val allDir = MXDirItem( - allResStr, - "", - dirs.sumOf { it.childSize }, - sourceDB.queryLastItem("", pickerType) - ) + val allDir = MXDirItem(allResStr, "", dirs.sumOf { it.childSize }) val allDirs = listOf(allDir) + dirs val selectDir = allDirs.firstOrNull { it.path == (dir?.path ?: "") } @@ -121,15 +120,19 @@ internal class MXPickerVM : ViewModel() { if (!MXUtils.compareList(dirListLive.value, allDirs)) { dirListLive.postValue(allDirs) + MXUtils.log("刷新->目录列表:${dirListLive.value?.size}->${allDirs.size}") } - if (dir != selectDir) { + if (dir?.path != selectDir.path) { selectDirLive.postValue(selectDir) + MXUtils.log("刷新->选中目录:${dir?.path}->${selectDir.path}") } val mediaList = sourceDB.getAllSource(pickerType, selectDir.path) if (!MXUtils.compareList(mediaListLive.value, mediaList)) { mediaListLive.postValue(mediaList) + MXUtils.log("刷新->图片列表") } + MXUtils.log("加载时长:${(System.currentTimeMillis() - start) / 1000f} 秒") } fun release() { diff --git a/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/fragment/MXPickerFragment.kt b/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/fragment/MXPickerFragment.kt index 637aba7b2e0cc9ecb580f9cf0eaa78b6872d6aaa..da785c236c7d4049b864b1969ecf0170e389b83e 100644 --- a/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/fragment/MXPickerFragment.kt +++ b/ImagePickerLib/src/main/java/com/mx/imgpicker/app/picker/fragment/MXPickerFragment.kt @@ -2,7 +2,6 @@ package com.mx.imgpicker.app.picker.fragment import android.Manifest import android.content.Intent -import android.graphics.Rect import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -14,7 +13,10 @@ import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope -import androidx.recyclerview.widget.* +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.SimpleItemAnimator import com.mx.imgpicker.R import com.mx.imgpicker.adapts.FolderAdapt import com.mx.imgpicker.adapts.ImgGridAdapt @@ -30,7 +32,7 @@ import kotlinx.coroutines.launch internal class MXPickerFragment : Fragment() { private val vm by lazy { ViewModelProvider(requireActivity()).get(MXPickerVM::class.java) } private val imgAdapt by lazy { ImgGridAdapt(vm) } - private val folderAdapt by lazy { FolderAdapt(vm) } + private val folderAdapt by lazy { FolderAdapt(vm, lifecycleScope) } private var selectItemIndex: Array? = null private var returnBtn: ImageView? = null diff --git a/ImagePickerLib/src/main/java/com/mx/imgpicker/db/MXDBSource.kt b/ImagePickerLib/src/main/java/com/mx/imgpicker/db/MXDBSource.kt index db49b8e97d3bbf8843a334577ee6fcbf920f345d..46a38a17c42f705c35d94a651e147b2e31a50ad9 100644 --- a/ImagePickerLib/src/main/java/com/mx/imgpicker/db/MXDBSource.kt +++ b/ImagePickerLib/src/main/java/com/mx/imgpicker/db/MXDBSource.kt @@ -11,6 +11,7 @@ import com.mx.imgpicker.utils.source_loader.MXVideoSource import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io.File +import kotlin.math.abs internal class MXDBSource(val context: Context) { companion object { @@ -194,9 +195,6 @@ internal class MXDBSource(val context: Context) { database.close() } } - for (dir in dirs) { - dir.lastItem = queryLastItem(dir.path, type) - } return@withContext dirs } @@ -235,7 +233,12 @@ internal class MXDBSource(val context: Context) { orderBy ) if (cursor != null && cursor.moveToFirst()) { - return@withContext cursorToItem(database, cursor) + do { + val item = cursorToItem(database, cursor) + if (item != null) { + return@withContext item + } + } while (cursor.moveToNext()) } } catch (e: Exception) { e.printStackTrace() @@ -277,6 +280,13 @@ internal class MXDBSource(val context: Context) { arrayOf(path) ) } + if (isPrivate && abs(System.currentTimeMillis() - time) > 60 * 1000) {// 删除超时的自拍数据 + database.delete( + MXSQLite.DB_NAME, + "${MXSQLite.DB_PATH} = ?", + arrayOf(path) + ) + } return null } diff --git a/build.gradle b/build.gradle index aed9ce86b462aba88e5f1c71786335f9e6e00f7c..31d2550c10e53745bbde4fbc3489a616b36c888e 100644 --- a/build.gradle +++ b/build.gradle @@ -37,5 +37,5 @@ ext { minSdkVersion = 19 versionCode = 1 - versionName = "1.5.3" + versionName = "1.5.4" } \ No newline at end of file