新建项目,添加如下依赖:
/** retrofit框架所需依赖 */
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
/**gson解析依赖*/
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
/**rxjava适配依赖*/
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
/** rxjava框架所需依赖 */
implementation 'io.reactivex.rxjava2:rxjava:2.1.16'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
/**gson依赖*/
implementation 'com.google.code.gson:gson:2.8.5'
/**一个网络请求日志打印的依赖*/
implementation('com.github.ihsanbal:LoggingInterceptor:2.0.5') {
exclude group: 'org.json', module: 'json'
}
1、写网络请求的BaseResponse类和model类,这里调用的是鸿洋大神玩Android的开放API来做测试,网站地址:https://www.wanandroid.com/blog/show/2
网络返回的的结构如下:
数据主要位于data中,编写BaseResponse内容:
package com.zc.demo.model
/**
*网络请求响应解析的基类
*这里T为泛型
*/
class BaseResponse<T>{
var errorCode:Int = 0
var errorMsg:String? = null
var data:T? = null
}
再编写获取首页文章的model类:
package com.zc.demo.model
class HomeArticleModel{
var curPage:Int ?= 0
var datas:List<DatasBean> ?= null
var offset:Int ?= null
var over:Boolean ?= false
var pageCount:Int ?= 0
var size:Int ?= 0
var total:Int ?= 0
class DatasBean{
var apkLink:String ?= null
var author:String ?= null
var chapterId:String ?= null
var chapterName:String ?= null
var collect:String ?= null
var courseId:String ?= null
var desc:String ?= null
var envelopePic:String ?= null
var fresh:String ?= null
var id:String ?= null
var link:String ?= null
var niceDate:String ?= null
var origin:String ?= null
var prefix:String ?= null
var projectLink:String ?= null
var publishTime:String ?= null
var superChapterId:String ?= null
var superChapterName:String ?= null
var title:String ?= null
var type:String ?= null
var visible:String ?= null
var userId:String ?= null
var zan:String ?= null
}
}
2、编写retrofit网络请求服务类:
package com.zc.demo.connect
import com.zc.demo.model.BaseResponse
import com.zc.demo.model.HomeArticleModel
import com.zc.demo.model.HomeBannerModel
import io.reactivex.Observable
import retrofit2.http.GET
import retrofit2.http.Path
interface ConnectService{
/**
* 获取首页Banner
*/
@GET("banner/json")
fun getHomeBanner():Observable<BaseResponse<List<HomeBannerModel>>>
/**
* 获取首页文章内容
* @param page 页数 用于分页查询
*/
@GET("article/list/{page}/json")
fun getHomeArticle(@Path("page") page: String):Observable<BaseResponse<HomeArticleModel>>
}
3、编写自定义网络请求回调的订阅者BaseObserver、自定义请求回调ConnectCallback(用于渲染界面)、网络请求控制类(获取网络数据):
package com.zc.demo.connect
/**
* 网络请求回调
* T 泛型
*/
interface ConnectCallback<T>{
/**
* 请求成功回调
* data 数据
*/
fun success(data:T)
/**
* 请求失败回调
* @param msg 失败信息
*/
fun error(msg:String)
/**
* 无网络回调
*/
fun noNetwork()
}
package com.zc.demo.connect
import com.zc.demo.model.BaseResponse
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
/**
* 自定义网络请求订阅者
* 用于处理网络数据
* T 泛型
*/
class BaseObserver<T>: Observer<BaseResponse<T>> {
var callback: ConnectCallback<T>
/**
* 构造方法初始化
*/
constructor(callback: ConnectCallback<T>) {
this.callback = callback
}
/**
* 网络请求完成
*/
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
}
/**
* 网络请求成功
*/
override fun onNext(t: BaseResponse<T>) {
handleDataByCode(t,callback)
}
/**
* 网络请求失败
*/
override fun onError(e: Throwable) {
callback.error(e.message!!)
}
/**
* 根据code码判断数据返回
* 这里可根据实际的结果码来判断响应 如未登录的结果码 回调未登录的响应方法
* @param baseResponse 数据
* @param callback 回调
*/
private fun handleDataByCode(baseResponse: BaseResponse<T>,callback: ConnectCallback<T>){
when(baseResponse.errorCode){
0 ->{
//结果码为0时成功获取数据
callback.success(baseResponse.data!!)
}
else ->{
//其他结果码回调
callback.error("获取数据失败")
}
}
}
}
package com.zc.demo.connect
import com.ihsanbal.logging.Level
import com.ihsanbal.logging.LoggingInterceptor
import com.zc.demo.BuildConfig
import com.zc.demo.content.ServerUrl
import com.zc.demo.model.HomeArticleModel
import com.zc.demo.model.HomeBannerModel
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.OkHttpClient
import okhttp3.internal.platform.Platform
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
/**
* 网络请求控制类
*/
class ConnectControl{
/**
* 静态方法和常量
*/
companion object {
/**网络请求服务*/
lateinit var service:ConnectService
/**okhttp builder*/
lateinit var builder: OkHttpClient.Builder
/**
* 初始化okhttp retrofit service
*/
private fun init(){
//判断service是否已经初始化
if (::service.isInitialized){
return
}
//初始化网络请求日志打印 只在Debug调试模式下才打印
var httpLoggingInterceptor: LoggingInterceptor? = null
if (BuildConfig.DEBUG) {
//debug模式下 打印网络请求日志
httpLoggingInterceptor = LoggingInterceptor.Builder()
.loggable(BuildConfig.DEBUG)
.setLevel(Level.BASIC)
.log(Platform.INFO)
.request("Request")
.response("Response")
.build()
}
builder = OkHttpClient.Builder()
//设置响应超时时间
builder!!.readTimeout(9, TimeUnit.SECONDS)
//设置连接超时时间
builder!!.connectTimeout(10, TimeUnit.SECONDS)
if (httpLoggingInterceptor != null) {
builder!!.addInterceptor(httpLoggingInterceptor)
}
//初始化retrofit
val retrofit = Retrofit.Builder().baseUrl(ServerUrl.BASE_URL)
.client(builder!!.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
//初始化服务service
service = retrofit.create(ConnectService::class.java)
}
/**
* 获取首页banner
*/
fun getHomeBanner(callback: ConnectCallback<List<HomeBannerModel>>){
init()
service.getHomeBanner().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(BaseObserver(callback))
}
/**
* 获取首页文章
*/
fun getHomeArticle(path:String,callback: ConnectCallback<HomeArticleModel>){
init()
service.getHomeArticle(path).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(BaseObserver(callback))
}
}
}
4、调用网络请求:
package com.zc.demo
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.zc.demo.connect.ConnectCallback
import com.zc.demo.connect.ConnectControl
import com.zc.demo.model.HomeArticleModel
import com.zc.demo.model.HomeBannerModel
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ConnectControl.getHomeBanner(object : ConnectCallback<List<HomeBannerModel>> {
override fun noNetwork() {
}
override fun success(data: List<HomeBannerModel>) {
Log.e("main","title="+data[0].title)
}
override fun error(msg: String) {
Log.e("main","错误:msg="+msg)
}
})
ConnectControl.getHomeArticle("1",object :ConnectCallback<HomeArticleModel>{
override fun noNetwork() {
}
override fun success(data: HomeArticleModel) {
Log.e("main","title="+ data.datas!![0].title)
}
override fun error(msg: String) {
Log.e("main","错误:msg="+msg)
}
})
}
}