[译] 2024 年的 Android 网络 —— Retrofit 与 Kotlin 协程,android数据结构算法面试题

123 阅读5分钟
  • Picasso / Glide —— 下载网络图片并将其设置给 ImageView。

显然这些只是一些热门的库,也有其他类似的库。此外这些库都是由 Square 公司 的牛人开发的。点击 Square 团队的开源项目 查看更多。

开始吧

Movie Database(TMDb)API 包含所有热门的、即将上映的、正在上映的电影和电视节目列表。这也是最流行的 API 之一。

TMDB API 需要 API 密钥才能请求。为此:

在版本控制系统中隐藏 API 密钥(可选但推荐)

获取 API 密钥后,按照下述步骤将其在 VCS 中隐藏。

  • 将你的密钥添加到根目录下的 local.properties 文件中。
  • build.gradle 中用代码来访问密钥。
  • 之后在程序中通过 BuildConfig 就可以使用密钥了。

//In local.properties tmdb_api_key = "xxxxxxxxxxxxxxxxxxxxxxxxxx"

//In build.gradle (Module: app) buildTypes.each { Properties properties = new Properties() properties.load(project.rootProject.file("local.properties").newDataInputStream()) def tmdbApiKey = properties.getProperty("tmdb_api_key", "")

it.buildConfigField 'String', "TMDB_API_KEY", tmdbApiKey

it.resValue 'string', "api_key", tmdbApiKey

}

//In your Constants File var tmdbApiKey = BuildConfig.TMDB_API_KEY

设置项目

为了设置项目,我们首先会将所有必需的依赖项添加到 build.gradle (Module: app) 文件中:

// build.gradle(Module: app) dependencies {

def moshiVersion="1.8.0" def retrofit2_version = "2.5.0" def okhttp3_version = "3.12.0" def kotlinCoroutineVersion = "1.0.1" def picassoVersion = "2.71828"

//Moshi implementation "com.squareup.moshi:moshi-kotlin:moshiVersion"kapt"com.squareup.moshi:moshikotlincodegen:moshiVersion" kapt "com.squareup.moshi:moshi-kotlin-codegen:moshiVersion"

//Retrofit2 implementation "com.squareup.retrofit2:retrofit:retrofit2version"implementation"com.squareup.retrofit2:convertermoshi:retrofit2_version" implementation "com.squareup.retrofit2:converter-moshi:retrofit2_version" implementation "com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2"

//Okhttp3 implementation "com.squareup.okhttp3:okhttp:$okhttp3_version" implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'

//Picasso for Image Loading implementation ("com.squareup.picasso:picasso:$picassoVersion"){ exclude group: "com.android.support" }

//Kotlin Coroutines implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:kotlinCoroutineVersion"implementation"org.jetbrains.kotlinx:kotlinxcoroutinescore:kotlinCoroutineVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:kotlinCoroutineVersion"

}

现在创建我们的 TmdbAPI 服务

//ApiFactory to create TMDB Api object Apifactory{

//Creating Auth Interceptor to add api_key query in front of all the requests. private val authInterceptor = Interceptor {chain-> val newUrl = chain.request().url() .newBuilder() .addQueryParameter("api_key", AppConstants.tmdbApiKey) .build()

val newRequest = chain.request() .newBuilder() .url(newUrl) .build()

chain.proceed(newRequest) }

//OkhttpClient for building http request url private val tmdbClient = OkHttpClient().newBuilder() .addInterceptor(authInterceptor) .build()

fun retrofit() : Retrofit = Retrofit.Builder() .client(tmdbClient) .baseUrl("api.themoviedb.org/3/") .addConverterFactory(MoshiConverterFactory.create()) .addCallAdapterFactory(CoroutineCallAdapterFactory()) .build()

val tmdbApi : TmdbApi = retrofit().create(TmdbApi::class.java)

}

看一下我们在 ApiFactory.kt 文件中做了什么。

  • 首先,我们创建了一个用以给所有请求添加 api_key 参数的网络拦截器,名为 authInterceptor
  • 然后我们用 OkHttp 创建了一个网络客户端,并添加了 authInterceptor。
  • 接下来,我们用 Retrofit 将所有内容连接起来构建 Http 请求的构造器和处理器。此处我们加入了之前创建好的网络客户端、基础 URL、一个转换器和一个适配器工厂。 首先是 MoshiConverter,用以辅助 JSON 解析并将响应的 JSON 转化为 Kotlin 数据类,如有需要,可进行选择性解析。 第二个是 CoroutineCallAdaptor,它的类型是 Retorofit2 中的 CallAdapter.Factory,用于处理 Kotlin 协程中的 Deferred
  • 最后,我们只需将 TmdbApi 类(下节中创建) 的一个引用传入之前建好的 retrofit 类中就可以创建我们的 tmdbApi。

探索 Tmdb API

调用 /movie/popular 接口我们得到了如下响应。该响应中返回了 results,这是一个 movie 对象的数组。这正是我们关注的地方。

{ "page": 1, "total_results": 19848, "total_pages": 993, "results": [ { "vote_count": 2109, "id": 297802, "video": false, "vote_average": 6.9, "title": "Aquaman", "popularity": 497.334, "poster_path": "/5Kg76ldv7VxeX9YlcQXiowHgdX6.jpg", "original_language": "en", "original_title": "Aquaman", "genre_ids": [ 28, 14, 878, 12 ], "backdrop_path": "/5A2bMlLfJrAfX9bqAibOL2gCruF.jpg", "adult": false, "overview": "Arthur Curry learns that he is the heir to the underwater kingdom of Atlantis, and must step forward to lead his people and be a hero to the world.", "release_date": "2018-12-07" }, { "vote_count": 625, "id": 424783, "video": false, "vote_average": 6.6, "title": "Bumblebee", "popularity": 316.098, "poster_path": "/fw02ONlDhrYjTSZV8XO6hhU3ds3.jpg", "original_language": "en", "original_title": "Bumblebee", "genre_ids": [ 28, 12, 878 ], "backdrop_path": "/8bZ7guF94ZyCzi7MLHzXz6E5Lv8.jpg", "adult": false, "overview": "On the run in the year 1987, Bumblebee finds refuge in a junkyard in a small Californian beach town. Charlie, on the cusp of turning 18 and trying to find her place in the world, discovers Bumblebee, battle-scarred and broken. When Charlie revives him, she quickly learns this is no ordinary yellow VW bug.", "release_date": "2018-12-15" } ] }

因此现在我们可以根据该 JSON 创建我们的 Movie 数据类和 MovieResponse 类。

// Data Model for TMDB Movie item data class TmdbMovie( val id: Int, val vote_average: Double, val title: String, val overview: String, val adult: Boolean )

// Data Model for the Response returned from the TMDB Api data class TmdbMovieResponse( val results: List )

//A retrofit Network Interface for the Api interface TmdbApi{ @GET("movie/popular") fun getPopularMovie(): Deferred<Response> }

TmdbApi 接口:

创建了数据类后,我们创建 TmdbApi 接口,在前面的小节中我们已经将其引用添加至 retrofit 构建器中。在该接口中,我们添加了所有必需的 API 调用,如有必要,可以给这些调用添加任意参数。例如,为了能够根据 id 获取一部电影,我们在接口中添加了如下方法:

interface TmdbApi{

@GET("movie/popular") fun getPopularMovies() : Deferred<Response>

@GET("movie/{id}")
fun getMovieById(@Path("id") id:Int): Deferred<Response>

}

最后,进行网络调用

接着,我们最终发出一个用以获取所需数据的请求,我们可以在 DataRepository 或者 ViewModel 或者直接在 Activity 中进行此调用。

总结

最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

这里附上我整理的几十套腾讯、字节跳动,京东,小米,头条、阿里、美团等公司19年的Android面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

详细整理在GitHub可以见;

Android架构视频+BAT面试专题PDF+学习笔记

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

技术进阶之路很漫长,一起共勉吧~