here is my api sevice
interface GetDataServices {
@GET("categories.php")
suspend fun getCategoryList(): Category
here is my Repositor
class Repository(
var getDataService : GetDataServices ?=null,
var dao: RecipeDao?=null,
var application: Application
){
//-1-get Main category from api
suspend fun getMainCategory(): Category? {
var res_rep= getDataService?.getCategoryList()
return res_rep
Log.v("res_rep_get",res_rep.toString())
}
}
here is my ViewModel
class CategoryViewModel: ViewModel(){
var repository:Repository?=null
var mainCategoryList:MutableLiveData<ArrayList<CategoryItems>?>?=MutableLiveData()
suspend fun getMainCategory(){
viewModelScope.launch(Dispatchers.IO) {
val result= withContext(Dispatchers.Main){
repository?.getMainCategory()
}
mainCategoryList!!.value = result!!.categoriesitems as ArrayList<CategoryItems>?
}
}
}
here is my activity
@OptIn(DelicateCoroutinesApi::class)
class SplashActivity : BaseActivity(), EasyPermissions.RationaleCallbacks,
EasyPermissions.PermissionCallbacks {
private var READ_STORAGE_PERM = 123
lateinit var categoryViewModel: CategoryViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
GlobalScope.launch {
// readStorageTask()
withContext(Dispatchers.Main){
getCategories()
}
}
}
suspend fun getCategories() {
categoryViewModel = ViewModelProvider(this).get(CategoryViewModel::class.java)
categoryViewModel!!.getMainCategory()
categoryViewModel.mainCategoryList?.observe(this) { value ->
value?.let {
Log.d("cor_get", value.toString())
}
}
}
here isُError
com.example.foodrecipeapp.viewmodel.CategoryViewModel$getMainCategory$2.invokeSuspend(CategoryViewModel.kt:26) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
here isُ another Error
at com.example.foodrecipeapp.viewmodel.CategoryViewModel$getMainCategory$2.invokeSuspend(CategoryViewModel.kt:26)
here is my dependincies
def lifecycle_version = "2.5.0-alpha01" def arch_version = "2.1.0" implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version") // ViewModel utilities for Compose implementation("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version") // LiveData implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")
kapt("androidx.lifecycle:lifecycle-compiler:2.5.0")
CodePudding user response:
You're doing your api request from the main thread
val result = withContext(Dispatchers.Main) { repository?.getMainCategory() }
Just leave it as
val result = repository?.getMainCategory()
I would guess that you're receiving an error from Retrofit about sending requests from the main thread.
- You have too many wrappers withContext(), you don't need them.
- You shouldn't use GlobalScope.launch for such cases as in your SplashActivity. Just operate viewModelScope and that would be enough.
- Add a brief error handling.
result!!.categoriesitems
will always fail if your server returns any http error or there is no internet connection
Please also take a look here. It has a great explanation about using scopes and creating coroutines.
CodePudding user response:
var repository
is declared but not instantiated.
class CategoryViewModel: ViewModel(){
/*
*Declared but not instantiated
*/
var repository:Repository?=null
var mainCategoryList:MutableLiveData<ArrayList<CategoryItems>?>?=MutableLiveData()
suspend fun getMainCategory(){
viewModelScope.launch(Dispatchers.IO) {
val result= withContext(Dispatchers.Main){
repository?.getMainCategory()
}
mainCategoryList!!.value = result!!.categoriesitems as ArrayList<CategoryItems>?
}
}
}