Skip to content

Instantly share code, notes, and snippets.

@webserveis
Created November 27, 2019 16:59
Show Gist options
  • Save webserveis/123b0db42f9e77235043e8b0faa6118e to your computer and use it in GitHub Desktop.
Save webserveis/123b0db42f9e77235043e8b0faa6118e to your computer and use it in GitHub Desktop.
Test Retrofit
**Dependencias**
```gradle
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
//Kotlin Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2'
//gson
implementation 'com.google.code.gson:gson:2.8.6'
//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.6.1'
implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
```
## Modelos
TodoModel = modelo normal
TodoResponse = modelo usando para leer los datos json en retrofit
```kotlin
data class TodoModel(
val id: Int = 0,
val title: String = "",
val completed: Boolean = false
)
data class TodoResponse(
@SerializedName("userId") val userId: Int,
@SerializedName("id") val id: Int,
@SerializedName("title") val title: String,
@SerializedName("completed") val completed: Boolean
)
```
## Otros
```kotlin
class AppException(val exceptin: Throwable?): Exception()
```
class MainActivity : AppCompatActivity() {
companion object {
val TAG: String = MainActivity::class.java.simpleName
}
private val mViewModel: MyViewModel by lazy {
ViewModelProviders.of(this).get(MyViewModel::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
/* mViewModel.getFirstTodo().observe(this, Observer<TodoModel> {
tv_display.text = it.toString()
})*/
/*mViewModel.getFirstTodo().observe(this, Observer<Resource<TodoModel>> { value ->
value?.let {
when (value.status) {
Resource.Status.LOADING -> {
Log.d(TAG, "Loading...." + value.data)
tv_display.setText(R.string.app_name)
}
Resource.Status.SUCCESS -> {
Log.d(TAG, "Success....")
Log.d(TAG, value.data.toString())
tv_display.text = value.data.toString()
}
Resource.Status.ERROR -> {
Log.d(TAG, "Error....")
}
}
}
})
*/
mViewModel.getAllTodos2().observe(this, Observer<Resource<List<TodoModel>>> { value ->
value?.let {
when (value.status) {
Resource.Status.LOADING -> {
Log.d(TAG, "Loading...." + value.data)
tv_display.setText(R.string.app_name)
}
Resource.Status.SUCCESS -> {
Log.d(TAG, "Success....")
Log.d(TAG, value.data.toString())
tv_display.text = value.data?.size.toString()
}
Resource.Status.ERROR -> {
Log.d(TAG, "Error....")
}
}
}
})
fab.setOnClickListener { view ->
toast("Hello world!")
//mViewModel.sayHelloWorld()
}
}
fun Context.toast(message: CharSequence) =
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
class MyViewModel : ViewModel() {
private val viewModelJob = SupervisorJob()
private val uiScope = CoroutineScope(Dispatchers.Default + viewModelJob)
val respuesta: MutableLiveData<Resource<TodoModel>> = MutableLiveData()
val respuesta2: MutableLiveData<Resource<List<TodoModel>>> = MutableLiveData()
val repository: TodoRepository = TodoRepository(TodoApiServiceFactory.todobApi)
//private val productDataMapper: Mapper<TodoResponse, TodoModel>
fun getFirstTodo(): LiveData<Resource<TodoModel>> {
return repository.getTodo(2)
}
fun getFirstTodo2(): LiveData<Resource<TodoModel>> {
uiScope.launch(Dispatchers.IO) {
val datos = repository.getTodo2(4)
//respuesta.postValue(Resource.success(TodoModel(1,"prueba",true)))
respuesta.postValue(datos)
}
return respuesta
}
fun getAllTodos(): LiveData<Resource<List<TodoModel>>> {
return repository.getTodosList(2)
}
fun getAllTodos2(): LiveData<Resource<List<TodoModel>>> {
uiScope.launch(Dispatchers.IO) {
val datos = repository.getTodoList2()
//respuesta.postValue(Resource.success(TodoModel(1,"prueba",true)))
respuesta2.postValue(datos)
}
return respuesta2
}
override fun onCleared() {
super.onCleared()
uiScope.coroutineContext.cancelChildren()
}
}
class Resource<T> private constructor(
val status: Status,
val data: T?,
val exception: AppException?
) {
enum class Status {
SUCCESS, ERROR, LOADING
}
companion object {
fun <T> success(data: T?): Resource<T> {
return Resource(
Status.SUCCESS,
data,
null
)
}
fun <T> error(exception: AppException?): Resource<T> {
return Resource(
Status.ERROR,
null,
exception
)
}
fun <T> loading(data: T?): Resource<T> {
return Resource(
Status.LOADING,
data,
null
)
}
}
}
interface TodoAPIService {
@GET("/todos/{id}")
fun getTodo(@Path("id") id: Int): Call<TodoResponse>
@GET("/todos/{id}")
suspend fun getTodo2(@Path("id") id: Int): TodoResponse
@GET("/todos")
fun getTodos(): Call<List<TodoResponse>>
@GET("/todos")
suspend fun getTodos2(): List<TodoResponse>
}
/*
https://android.jlelse.eu/android-networking-in-2019-retrofit-with-kotlins-coroutines-aefe82c4d777
*/
object TodoApiServiceFactory {
fun retrofit(): Retrofit = Retrofit.Builder()
.baseUrl("https://jsonplaceholder.typicode.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val todobApi = retrofit()
.create(TodoAPIService::class.java)
}
/*
https://proandroiddev.com/suspend-what-youre-doing-retrofit-has-now-coroutines-support-c65bd09ba067
https://proandroiddev.com/the-real-repository-pattern-in-android-efba8662b754
https://proandroiddev.com/demystifying-retrofit-network-call-with-kotlin-livedata-27437439137a
https://github.com/rifqimfahmi/android-mvvm-coroutine/blob/master/app/src/main/java/com/rifqimfahmi/foorballapps/data/source/SportRepository.kt
*/
class TodoRepository(private var todoApiService: TodoAPIService) {
fun getTodo(id: Int): LiveData<Resource<TodoModel>> {
val liveData = MutableLiveData<Resource<TodoModel>>()
// Dispatchers.IO
/* perform blocking network IO here */
todoApiService.getTodo(id).enqueue(object : Callback<TodoResponse> {
override fun onResponse(
call: Call<TodoResponse>,
response: Response<TodoResponse>
) {
if (response.isSuccessful) {
liveData.value = Resource.success(
TodoModel(
response.body()!!.id,
response.body()!!.title,
response.body()!!.completed
)
)
// When data is available, populate LiveData
//liveData.value = response?.body()
}
}
override fun onFailure(call: Call<TodoResponse>, t: Throwable) {
t.printStackTrace()
liveData.value = Resource.error(AppException(t.cause))
}
})
// Synchronously return LiveData
// Its value will be available onResponse
return liveData
}
suspend fun getTodo2(id: Int): Resource<TodoModel> {
// Dispatchers.IO
/* perform blocking network IO here */
return try {
val datos = todoApiService.getTodo2(id)
Resource.success(TodoModel(datos.id, datos.title, datos.completed))
} catch (e: Exception) {
println("Caught ArithmeticException")
Resource.success(null)
}
}
fun getTodosList(id: Int): LiveData<Resource<List<TodoModel>>> {
val liveData = MutableLiveData<Resource<List<TodoModel>>>()
// Dispatchers.IO
/* perform blocking network IO here */
todoApiService.getTodos().enqueue(object : Callback<List<TodoResponse>> {
override fun onResponse(
call: Call<List<TodoResponse>>,
response: Response<List<TodoResponse>>
) {
if (response.isSuccessful) {
Log.d(
"aaa", "size response" + response.body()?.size
)
val nameMap: List<TodoModel>? = response.body()?.map { TodoModel(it.id,it.title,it.completed) };
liveData.postValue(Resource.success(nameMap))
}
}
override fun onFailure(call: Call<List<TodoResponse>>, t: Throwable) {
t.printStackTrace()
liveData.value = Resource.error(AppException(t.cause))
}
})
// Synchronously return LiveData
// Its value will be available onResponse
return liveData
}
//val value = NetworkCall<TodoResponse>().makeCall(todoApiService.getTodo(id)).value?.data
suspend fun getTodoList2(): Resource<List<TodoModel>> {
// Dispatchers.IO
/* perform blocking network IO here */
return try {
val datos = todoApiService.getTodos2()
val nameMap: List<TodoModel>? = datos.map { TodoModel(it.id,it.title,it.completed) };
Resource.success(nameMap)
} catch (e: Exception) {
println("Caught ArithmeticException")
Resource.success(null)
}
}
/*private lateinit var localDataSource: LocalDataSource
private lateinit var remoteDataSource: RemoteDataSource
operator fun invoke(context: Context): MyRepository {
//...
localDataSource = LocalDataSourceImpl.getInstance(context)
remoteDataSource = RemoteDataSourceImpl.getInstance(context)
return this
}*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment