電影資訊App是一個純練手項目,使用了系統API28,所有是基於Androidx包下的。使用Kotlin語言開發,使用了Android JetPack中的LiveData、ViewModel以及Room。爲了學習Kotlin和鞏固自定義View和ViewGroup,這個項目是儘可能少應用依賴第三方庫。Api來自豆瓣電影,豆瓣電影Api目前是不公開的,小編是在簡書上看到有人公開了訪問豆瓣電影的Api的API_KEY,若是有侵犯,請聯繫刪除!java
截圖1 | 截圖2 | 截圖 3 | 截圖 4 | 截圖5 |
---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
看幾段代碼,訪問網絡的核心代碼,設計到了蠻多的知識點,這是初始化Retrofitgit
class RetrofitClient {
companion object {
val serviceApi: ServiceApi by lazy {
val retrofitClient = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor(HttpLoggingInterceptor.Logger { message ->
Log.i(TAG, message)
}).setLevel(HttpLoggingInterceptor.Level.BODY)
).build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(LiveDataCallAdapterFactory())
.build()
retrofitClient.create(ServiceApi::class.java)
}
}
}
複製代碼
注意這段代碼,經過工廠模式添加一個LiveData數據源適配器github
.addCallAdapterFactory(LiveDataCallAdapterFactory())
複製代碼
經過方法工廠返回LiveDataCallAdapter的實例,而且獲取泛型的參數類型網絡
class LiveDataCallAdapterFactory : Factory() {
override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? {
val responseType: Type
if (Factory.getRawType(returnType) != LiveData::class.java) {
throw IllegalStateException("return type must be parameterized")
}
val observableType = Factory.getParameterUpperBound(0, returnType as ParameterizedType)
val rawObservableType = Factory.getRawType(observableType)
responseType = if (rawObservableType == Response::class.java) {
if (observableType !is ParameterizedType) {
throw IllegalArgumentException("Response must be parameterized")
}
Factory.getParameterUpperBound(0, observableType)
} else {
observableType
}
return LiveDataCallAdapter<Any>(responseType)
}
}
複製代碼
注意adapt()方法中的代碼,經過適配器模式將Call轉爲LiveDataapp
class LiveDataCallAdapter<R>(private val responseType: Type) :
CallAdapter<R, LiveData<R>> {
override fun responseType() = responseType
override fun adapt(call: Call<R>): LiveData<R> {
return object : LiveData<R>() {
private var started = AtomicBoolean(false)
override fun onActive() {
super.onActive()
if (started.compareAndSet(false, true)) {
call.enqueue(object : Callback<R> {
override fun onResponse(call: Call<R>, response: Response<R>) {
postValue(response.body())
}
override fun onFailure(call: Call<R>, throwable: Throwable) {
postValue(null)
}
})
}
}
}
}
}
複製代碼
你們可能看這些代碼會比較懵,我是看了RxJava2中的RxJava2CallAdapterFactory中的代碼,之前只是會寫,可是點擊去看源碼,在分析就不同了。Observable在這至關於LiveData(被觀察者)。經過調用retrofitClient.create(ServiceApi::class.java),最終會調用到adapt()方法中。ide
github傳送門post