问题
I'm trying to learn MVVM architecture on parse Json into a Recyclerview in MVVM using coroutines. But I'm getting error on BlogRepository class.
My Json file looks like this:
[
  {
    "id": 1,
    "name": "potter",
    "img": "https://images.example.com/potter.jpg"
},
{ …}
]
I have created data class as below:
@JsonClass(generateAdapter = true)
class ABCCharacters (
    @Json(name = "id") val char_id: Int,
    @Json(name = "name") val name: String? = null,
    @Json(name = "img") val img: String
)
Then the RestApiService as below:
interface RestApiService {
    @GET("/api")
    fun getPopularBlog(): Deferred<List<ABCCharacters>>
    companion object {
        fun createCorService(): RestApiService {
            val okHttpClient = OkHttpClient.Builder()
                .connectTimeout(1, TimeUnit.MINUTES)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .build()
            return Retrofit.Builder()
                .baseUrl("https://example.com")
                .addConverterFactory(MoshiConverterFactory.create())
                .client(okHttpClient)
                .addCallAdapterFactory(CoroutineCallAdapterFactory())
                .build().create(RestApiService::class.java)
        }
    }
}
BlogReposity.kt
class BlogRepository() {
    private var character = mutableListOf<ABCCharacters>()
    private var mutableLiveData = MutableLiveData<List<ABCCharacters>>()
    val completableJob = Job()
    private val coroutineScope = CoroutineScope(Dispatchers.IO + completableJob)
    private val thisApiCorService by lazy {
        RestApiService.createCorService()
    }
    fun getMutableLiveData():MutableLiveData<List<ABCCharacters>> {
        coroutineScope.launch {
            val request = thisApiCorService.getPopularBlog()
            withContext(Dispatchers.Main) {
                try {
                    val response = request.await()
                    val mBlogWrapper = response;
                    if (mBlogWrapper != null && mBlogWrapper.name != null) {
                        character = mBlogWrapper.name as MutableList<ABCCharacters>
                        mutableLiveData.value=character;
                    }
                } catch (e: HttpException) {
                    // Log exception //
                } catch (e: Throwable) {
                    // Log error //)
                }
            }
        }
        return mutableLiveData;
    }
}
Finally the ViewModel class
class MainViewModel() : ViewModel() {
    val characterRepository= BlogRepository()
    val allBlog: LiveData<List<ABCCharacters>> get() = characterRepository.getMutableLiveData()
    override fun onCleared() {
        super.onCleared()
        characterRepository.completableJob.cancel()
    }
}
I've done this based on https://itnext.io/kotlin-wrapping-your-head-around-livedata-mutablelivedata-coroutine-networking-and-viewmodel-b552c3a74eec Someone can guide me where am I going wrong & how to fix it?
回答1:
Your getPopularBlog() API return List<ABCCharacters> instead of ABCCharacters. So, you can't access ABCCharacters's property from your response directly. That's why name property here shows Unresolved reference.
Try below code:
if (mBlogWrapper != null && mBlogWrapper.isNotEmpty()) {
    character = mBlogWrapper as MutableList<ABCCharacters>
    mutableLiveData.value = character
}
回答2:
Your response return List but you want to check single object value (mBlogWrapper.name != null). You dont need this line on your code. In the example he checked if "response" is not a "null" and if the blog list is not null. Analize example one more time ;)
if you still have a problem with it, let me know
来源:https://stackoverflow.com/questions/58808044/kotlin-json-parsing-mvvm