我实现了 LiveData 和 ViewModel 来模仿 AsyncTaskLoader。
我从 DCIM 中的相机目录加载文件名,然后附加一个 fileObserver 来观察删除文件(图片)时的情况,然后回调告诉 LiveData 在发生删除事件时重新获取文件名
问题:
下面的代码应该在 LiveData 的帮助下从 DCIM/Pictures 异步获取文件名,然后将 FileObserver 附加到目录 (DCIM/Pictures),以监视文件何时被删除,并使用 LiveData 子实现回调类来重新加载文件,如代码中所示。
好的,它第一次工作,即文件第一次加载,调用setValue()
并传递文件名触发 onChange 在观察 Activity/Fragment 中调用。但是当文件被删除时,回调函数会调用loadFiles()函数重新加载文件,但这次调用setValue并传入FileNames并不会触发观察Activity/Fragment中的OnChange。
根据LiveData官方文档 https://developer.android.com/topic/libraries/architecture/livedata
您必须调用 setValue(T) 方法来更新 LiveData 对象
从主线程。
我很好奇为什么 LiveData 在第一次调用后没有更新其值。
The Code
我的实时数据
class MyLiveData() : MutableLiveData<MutableList<String>>(), PictureDelete {
override fun onPicDelete() {
loadFileNames()
}
val TAG = "MyLiveData"
val fileNamesList: MutableList<String> = ArrayList()
val fileWatcher : MyFileWatcher
init {
loadFileNames()
val pathToWatch = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM + "/Camera").getAbsolutePath()
fileWatcher = MyFileWatcher(pathToWatch, this)
fileWatcher.startWatching()
}
private fun loadFileNames() {
val fileDir: File
try {
fileDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM + "/Camera")
} catch (e: Exception) {
Log.e(TAG, e.message)
return
}
Log.d(TAG, "Actively Loading Files in Status LiveData")
val arrayOfFiles = fileDir.listFiles()
if (arrayOfFiles == null || arrayOfFiles.size < 1) return
Log.d(TAG, "Actively Loading Files. Size: ${arrayOfFiles.size}")
setValue(fileNamesList)
}
}
我的视图模型
class MyViewModel() : ViewModel() {
val myLiveData: MyLiveData
val TAG = "WhatsAppFragment-VModel"
init {
myLiveData = MyLiveData()
}
}
我的片段
class MyFragment : Fragment() {
private val TAG = "MyFragment"
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_layout, container, false)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
viewModel.myLiveData.observe(this, androidx.lifecycle.Observer { fileNames ->
Log.d(TAG, "New Live Data Dispatch")
for ((index, name) in fileNames.withIndex()) {
Log.d(TAG, "the element at $index is $name")
}
})
}
}
我的文件观察者
class MyFileWatcher(pathToWatch: String, val picDelete: PictureDelete) : FileObserver(pathToWatch, DELETE) {
val TAG = "MyFileWatcher"
init {
Log.d(TAG, "Initialization")
}
override fun onEvent(event: Int, path: String?) {
if (event = FileObserver.DELETE) { // EventCode 512 == Delete
Log.d(TAG, "OnEvent. Event: $event Path: $path")
picDelete.onPicDelete()
}
}
}
图片删除接口
interface PictureDelete {
fun onPicDelete()
}
我的实施有什么问题?