这是又一个例子,关于怎样在Kotlin中使用Java使用过的相同库。
Retrofit是一个库,它极大地简化了请求API,在这个例子中我计划教你怎样将其与一些LastFM API请求集成。你能够读到运行在Bandhook Kotlin创库全部代码。
Kotlin中的Retrofit 2
Kotlin代码是非常类似我们在Java中用的。我们将看到更多的细节有哪些不同,而且,你会发现这一切都是很简单和直观的。
你还会看到我们也将创建一些非常实用的扩展函数。
构建build.gradle
我在这里不会解释太多,而你需要将下面指令加入到build.gradle中:
1 compile "com.squareup.okhttp3:okhttp:$okhttpVersion" 2 compile "com.squareup.okhttp3:logging-interceptor:$okhttpVersion" 3 4 compile ("com.squareup.retrofit2:retrofit:$retrofitVersion"){ 5 // exclude Retrofit’s OkHttp peer-dependency module and define your own module import 6 exclude module: 'okhttp' 7 }
第一个依赖关系包括OkHttp最后的版本和日志记录拦截器,它能够用于调试。
接着加Retrofit(不包括OkHttp,这样我们控制我们实用的版本),Gson转换器转换请求给类。
创建通讯接口
这是Retrofit的中枢神经部分。这是你指定的请求结构,将需要匹配的API
1 interface LastFmService { 2 3 @GET("/2.0/?method=artist.search") 4 fun searchArtist(@Query("artist") artist: String): Call 5 6 @GET("/2.0/?method=artist.getinfo") 7 fun requestArtistInfo(@Query("mbid") id: String, @Query("lang") language: String): Call 8 9 @GET("/2.0/?method=artist.gettopalbums") 10 fun requestAlbums(@Query("mbid") id: String, @Query("artist") artist: String): Call; 11 12 @GET("/2.0/?method=artist.getsimilar") 13 fun requestSimilar(@Query("mbid") id: String): Call 14 15 @GET("/2.0/?method=album.getInfo") 16 fun requestAlbum(@Query("mbid") id: String): Call 17 }
它十分简单。它用符号标识请求的类型,然后请求的参数作为参数的函数。
在Retrofit 2中,我们需要返回调用对象类型。
通讯服务的初始化
首先,你能够按如下初始化OkHttp client端:
1 val client = OkHttpClient().newBuilder() 2 .cache(cache) 3 .addInterceptor(LastFmRequestInterceptor(apiKey, cacheDuration)) 4 .addInterceptor(HttpLoggingInterceptor().apply { 5 level = if (BuildConfig.DEBUG) Level.BODY else Level.NONE 6 }) 7 .build() 8 }
这里我们看到了apple函数的使用,它将帮助我们以构建者风格初始化拦截器,不需要为类实现构建者的任何类型。
LastFmRequestInterceptor
没有什么了不起,但是你能够到GitHub上找到。服务器端的创建于Java有些不同:
val retrofit = Retrofit.Builder() .baseUrl("http://ws.audioscrobbler.com") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() val lastFmService = retrofit.create(LastFmService::class.java)
建立你的第一个请求
由于需要调用Retrofit 2,它成为一点冗余代码:
1 val call = lastFmService.requestAlbums(mbid, name) 2 val result = call.execute().body() 3 val albums = AlbumMapper().transform(result.topAlbums.albums)
然而,幸亏有扩展函数,我们能够在Call创建一个函数,提取值,就如同这样:
1 val albums = lastFmService.requestAlbums(mbid, name).unwrapCall { 2 AlbumMapper().transform(topAlbums.albums) 3 }
非常简单,对面?
unwrapCall的格式是什么?
1 inline fun <T, U> Call.unwrapCall(f: T.() -> U): U = execute().body().f()
它是扩展Call
类的函数。它将执行请求,提取body
,使其(它将是U类型)执行函数f()。
在上面例子中,T
是LastFmResponse
,U
是List
。
热门评论
你写的什么乱七八糟的