Retrofit2 使用总结

    科技2022-08-10  99

    0.首先导入相关的库

    implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.okhttp3:okhttp:4.8.0' // 导入第一行之后如果未成功导入okhttp库,手动导入,retrofit 是基于okhttp库进行封装的。

    1.定义一个 Service 接口

    interface PlaceService {//发起请求 @GET("v2/place") // 调用此方法时会发起一条GET请求 suspend fun getData(@Query("query") query: String, //自动开启子线程 @Query("token") token: String, @Query("lang") lang: String ):DailyResponse }

    2.定义一个 ServiceCreator 单例类,用于生成 动态代理对象

    object ServiceCreator { val retrofit = Retrofit.Builder() .baseUrl("https://api.caiyunapp.com/") .addConverterFactory(GsonConverterFactory.create()) .build() //创建动态代理对象,inline 内联函数使泛型不会擦除,reified关键字表明泛型要进行实化 inline fun <reified T> create() = retrofit.create(T::class.java) }

    3.定义一个 Network 单例类,用于提供网络请求的接口

    object WeatherNetwork { private val placeService = ServiceCreator.create<PlaceService>() //内部开启一个新的IO线程 suspend fun getPlace(name: String) = placeService.getData(name,WeatherApplication.token, "zh_CN") }

    4.定义一个data class 用于接收数据

    data class DailyResponse(val status: String, val result: Result) {//data类对数据做了一个很好的封装 data class Result(val daily: Daily) data class Daily(val astro: List<Astro>, val temperature: List<Temperature>, val skycon: List<Skycon>) data class Astro(val sunrise: Sunrise, val sunset: Sunset) data class Sunrise(val time: String) data class Sunset(val time: String) data class Temperature(val max: Float, val min: Float) data class Skycon(val date: Date, val value: String) }

    基于官方推荐的架构

    0.View 从ViewModel 中获得数据

    ViewMdel 中定义两个 LiveData ,第一个 LiveData的值改变时触发 switchMap() 函数,生成第二个LiveData 对象。

    class HotViewModel : ViewModel() { private var pageLiveData = MutableLiveData<Int>() fun queryArticle(page: Int) { pageLiveData.value = page } // 当 pageLivedata 改变时触发 switchMap() 函数,返回一个liveData val articleLiveData = Transformations.switchMap(pageLiveData) { page -> HotRepository.getArticle(page) } }

    1.ViewModel 从 Repository 中获取数据

    Repository 可以提供本地数据,或者网络数据。

    object HotRepository { fun getArticle(page: Int) = liveData{ // livedata() 函数拥有协程作用域,同时返回LiveData对象 val res = try { val articleResponse = ArticleNetwork.getArticle(page) if (articleResponse.errorCode == 0) { Result.success(articleResponse) // Result 类可以对结果进行封装,返回更加直观的信息 } else { Result.failure(RuntimeException("errorCode is ${articleResponse.errorCode}")) } } catch (e: Exception) { Result.failure<ArticleResponse>(e) } emit(res) } }
    Processed: 0.019, SQL: 8