Return 没有返回值
Return is not returning the value
所以我的视图模型的 return 函数没有给出 return 预期给出 return 位图的地方所以它可以在 UI 中使用设置图像。
视图模型代码:
val bitmap : MutableLiveData<Bitmap> by lazy { MutableLiveData<Bitmap>() }
fun retrive(doc_name : String,uid: String){
viewModelScope.launch(Dispatchers.IO){
bitmap.postValue(repository.retrive(doc_name,uid))
}
}
存储库代码:
var localfile = createTempFile("tempImage", null)
var bitmap :Bitmap? = null
override suspend fun retrive(doc_name:String,uid: String) : Bitmap?{
val storageRef = FirebaseStorage.getInstance().reference?.child("/image/8WEFQnomCEMtlaSkCIkrBgT7XeO2/download")
storageRef.getFile(localfile).addOnSuccessListener {
bitmap = BitmapFactory.decodeFile(localfile.absolutePath)
}
return bitmap
}
View Created 部分的 Fragment 中的代码:
val obsover = Observer<Bitmap>{
image.setImageBitmap(it)
}
admin_viewmodel.bitmap.observe(viewLifecycleOwner,obsover)
因为我在我的 Repository 函数中保留了位图可以为 null 的信息,所以它在图像视图中打开了没有图像的片段
但是如果我保持 Bitmap 不为 null(!!) 应用程序崩溃并在下面的行中给出 Null Pointer Exception 错误:
在我上面分享的存储库代码中:
return bitmap!!
2.Inside我上面分享的View Model代码:
bitmap.postValue(repository.retrive(doc_name,uid))
我认为它无法 return 因为事情在不同的线程上工作。
请帮我解决这个问题,谢谢。
Broot 回复代码更改后编辑:
override suspend fun retrive(doc_name:String,uid: String) : Bitmap {
return suspendCoroutine { cont ->
val storageRef =
FirebaseStorage.getInstance().reference?.child("/image/0XhL4jD4XCemk38rcRkIEjJMgjh2/Aadhar")
val localfile = createTempFile("tempImage", null)
storageRef.getFile(localfile).addOnSuccessListener {
val x = cont.resume(bitmap!!)
Log.d("checck", "$x")
}
}
}
您的原始代码不正确,因为它触发了 API 的异步函数,然后立即 returns,在异步工作完成并触发其回调以更新 bitmap
属性.
你的第二个代码是错误的,因为它试图用 属性 bitmap
的值恢复继续,你还没有用回调中返回的值更新它。此外,由于您只需要来自云文件的位图,因此没有理由将其下载到临时文件中。您可以直接使用字节。而且没有理由使用我可以看到的 属性 。 bitmap
可以是局部变量。
此外,由于在失败的情况下您不执行任何操作,因此如果从 Firebase 检索数据时出现问题,您的函数将挂起。下面,我只是抛出错误,但如果你愿意,你可以做一些不同的事情,比如返回 null。
我不知道你用这两个参数做什么,但我把它们留下了。我让你来决定你的字节限制应该是多少(我只使用了 500 万字节)。我不记得保证的最小可用内存量是针对 Android 应用程序的,而且您可能知道您正在检索的文件无论如何都低于该值。
override suspend fun retrive(doc_name: String, uid: String): Bitmap = suspendCoroutine { cont ->
val storageRef =
FirebaseStorage.getInstance().reference.child("/image/0XhL4jD4XCemk38rcRkIEjJMgjh2/Aadhar")
storageRef.getBytes(5_000_000L).addOnSuccessListener { byteArray ->
val bitmap = BitmapFactory.decodeByteArray(byteArray)
cont.resume(bitmap)
}.addOnFailureListener {
cont.resumeWithException(it)
}
}
但是: Firebase 已经带有 await()
扩展暂停功能,因此您不必使用 suspendCoroutine
.
override suspend fun retrive(doc_name: String, uid: String): Bitmap {
val storageRef =
FirebaseStorage.getInstance().reference.child("/image/0XhL4jD4XCemk38rcRkIEjJMgjh2/Aadhar")
val byteArray = storageRef.getBytes(5_000_000L).await()
return BitmapFactory.decodeByteArray(byteArray)
}
由于解码位图是一项繁重的操作,我会在 Dispatchers.Default
:
中执行此操作
override suspend fun retrive(doc_name: String, uid: String): Bitmap = withContext(Dispatchers.Default) {
val storageRef =
FirebaseStorage.getInstance().reference.child("/image/0XhL4jD4XCemk38rcRkIEjJMgjh2/Aadhar")
val byteArray = storageRef.getBytes(5_000_000L).await()
return BitmapFactory.decodeByteArray(byteArray)
}
所以我的视图模型的 return 函数没有给出 return 预期给出 return 位图的地方所以它可以在 UI 中使用设置图像。
视图模型代码:
val bitmap : MutableLiveData<Bitmap> by lazy { MutableLiveData<Bitmap>() }
fun retrive(doc_name : String,uid: String){
viewModelScope.launch(Dispatchers.IO){
bitmap.postValue(repository.retrive(doc_name,uid))
}
}
存储库代码:
var localfile = createTempFile("tempImage", null)
var bitmap :Bitmap? = null
override suspend fun retrive(doc_name:String,uid: String) : Bitmap?{
val storageRef = FirebaseStorage.getInstance().reference?.child("/image/8WEFQnomCEMtlaSkCIkrBgT7XeO2/download")
storageRef.getFile(localfile).addOnSuccessListener {
bitmap = BitmapFactory.decodeFile(localfile.absolutePath)
}
return bitmap
}
View Created 部分的 Fragment 中的代码:
val obsover = Observer<Bitmap>{
image.setImageBitmap(it)
}
admin_viewmodel.bitmap.observe(viewLifecycleOwner,obsover)
因为我在我的 Repository 函数中保留了位图可以为 null 的信息,所以它在图像视图中打开了没有图像的片段 但是如果我保持 Bitmap 不为 null(!!) 应用程序崩溃并在下面的行中给出 Null Pointer Exception 错误:
在我上面分享的存储库代码中:
return bitmap!!
2.Inside我上面分享的View Model代码:
bitmap.postValue(repository.retrive(doc_name,uid))
我认为它无法 return 因为事情在不同的线程上工作。 请帮我解决这个问题,谢谢。
Broot 回复代码更改后编辑:
override suspend fun retrive(doc_name:String,uid: String) : Bitmap {
return suspendCoroutine { cont ->
val storageRef =
FirebaseStorage.getInstance().reference?.child("/image/0XhL4jD4XCemk38rcRkIEjJMgjh2/Aadhar")
val localfile = createTempFile("tempImage", null)
storageRef.getFile(localfile).addOnSuccessListener {
val x = cont.resume(bitmap!!)
Log.d("checck", "$x")
}
}
}
您的原始代码不正确,因为它触发了 API 的异步函数,然后立即 returns,在异步工作完成并触发其回调以更新 bitmap
属性.
你的第二个代码是错误的,因为它试图用 属性 bitmap
的值恢复继续,你还没有用回调中返回的值更新它。此外,由于您只需要来自云文件的位图,因此没有理由将其下载到临时文件中。您可以直接使用字节。而且没有理由使用我可以看到的 属性 。 bitmap
可以是局部变量。
此外,由于在失败的情况下您不执行任何操作,因此如果从 Firebase 检索数据时出现问题,您的函数将挂起。下面,我只是抛出错误,但如果你愿意,你可以做一些不同的事情,比如返回 null。
我不知道你用这两个参数做什么,但我把它们留下了。我让你来决定你的字节限制应该是多少(我只使用了 500 万字节)。我不记得保证的最小可用内存量是针对 Android 应用程序的,而且您可能知道您正在检索的文件无论如何都低于该值。
override suspend fun retrive(doc_name: String, uid: String): Bitmap = suspendCoroutine { cont ->
val storageRef =
FirebaseStorage.getInstance().reference.child("/image/0XhL4jD4XCemk38rcRkIEjJMgjh2/Aadhar")
storageRef.getBytes(5_000_000L).addOnSuccessListener { byteArray ->
val bitmap = BitmapFactory.decodeByteArray(byteArray)
cont.resume(bitmap)
}.addOnFailureListener {
cont.resumeWithException(it)
}
}
但是: Firebase 已经带有 await()
扩展暂停功能,因此您不必使用 suspendCoroutine
.
override suspend fun retrive(doc_name: String, uid: String): Bitmap {
val storageRef =
FirebaseStorage.getInstance().reference.child("/image/0XhL4jD4XCemk38rcRkIEjJMgjh2/Aadhar")
val byteArray = storageRef.getBytes(5_000_000L).await()
return BitmapFactory.decodeByteArray(byteArray)
}
由于解码位图是一项繁重的操作,我会在 Dispatchers.Default
:
override suspend fun retrive(doc_name: String, uid: String): Bitmap = withContext(Dispatchers.Default) {
val storageRef =
FirebaseStorage.getInstance().reference.child("/image/0XhL4jD4XCemk38rcRkIEjJMgjh2/Aadhar")
val byteArray = storageRef.getBytes(5_000_000L).await()
return BitmapFactory.decodeByteArray(byteArray)
}