美文网首页Android知识Android开发经验谈Android开发
使用Kotlin和Android JetPack开发一款App

使用Kotlin和Android JetPack开发一款App

作者: 皮卡丘520 | 来源:发表于2019-03-08 11:48 被阅读24次

    电影资讯App是一个纯练手项目,使用了系统API28,全部是基于Androidx包下的。使用Kotlin语言开发,使用了Android JetPack中的LiveData、ViewModel以及Room。为了学习Kotlin和巩固自定义View和ViewGroup,这个项目是尽量少应用依赖第三方库。Api来自豆瓣电影,豆瓣电影Api目前是不公开的,小编是在简书上看到有人公开了访问豆瓣电影的Api的API_KEY,如果有侵犯,请联系删除!

    项目截图

    截图1 截图2 截图 3 截图 4 截图5
    5.jpg 3.jpg 1.jpg 4.jpg 6.jpg

    app主要设计到知识点:

    • Material Design UI设计风格;
    • 使用Kotlin开发,大家想学习和巩固Kotlin,可以参考这个App;
    • Retrofit适配LiveData手写一个LiveDataCallAdapter适配器;
    • RecyclerView支持上拉刷新和下拉加载,并且可以添加不同类型头部和底部的View以及动画;
    • 支持视频播放

    看几段代码,访问网络的核心代码,设计到了蛮多的知识点,这是初始化Retrofit

    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数据源适配器

      .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转为LiveData

    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()方法中。

    这是小编的公众号

    公众号后台回复:“源码” 关键字获取项目地址。

    相关文章

      网友评论

        本文标题:使用Kotlin和Android JetPack开发一款App

        本文链接:https://www.haomeiwen.com/subject/sehxpqtx.html