一、实现原理
使用Retrofit实现网络请求,在通过Rxjava2实现线程调度,通过Gson得到当前的需要的模型类
二、实现过程
1、添加依赖
implementation 'com.squareup.okhttp3:okhttp:3.12.3' // OkHttp3
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0' // 日志
implementation 'com.squareup.retrofit2:retrofit:2.6.0' // Retrofit2
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.0' // Retrofit2 -> RxJava 的适配
implementation 'com.squareup.retrofit2:converter-gson:2.5.0' // Gson转换器
implementation 'com.squareup.retrofit2:converter-scalars:2.4.0' // 响应转为基本类型所需依赖
// LeakCanary 内存泄漏检测工具
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.3'
// RxJava
implementation 'io.reactivex.rxjava2:rxjava:2.2.6'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
// 处理网络请求可能导致的内存泄漏
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
2、添加对应的权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3、创建对应的基础类目录
三、实现
1、因为使用了RxJava2所以需要使用Rxlifecycle防止内存泄露
2、实现Activity和Fragment的基类,并根据自己的需要做简单的封装
abstract class BasicActivity : RxFragmentActivity() {
protected abstract val mLayoutResId: Int
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (this.mLayoutResId > 0) {
setContentView(mLayoutResId)
} else {
throw RuntimeException("this activity is miss cotentview")
}
onContentViewReady(savedInstanceState)
}
abstract fun onContentViewReady(savedInstanceState: Bundle?)
fun <A> startActivity(clazz: Class<A>, data: Bundle?) {
var intent = Intent(this, clazz)
data?.let { intent.putExtras(data) }
this.startActivity(intent)
}
fun <A> startActivity(clazz: Class<A>) {
var intent = Intent(this, clazz)
this.startActivity(intent)
}
}
abstract class BasicFragment : Fragment(), LifecycleProvider<FragmentEvent> {
private val lifecycleSubject = BehaviorSubject.create<FragmentEvent>()
protected abstract val mLayoutResId: Int
protected var mRootView: View? = null
override fun lifecycle(): Observable<FragmentEvent> {
return this.lifecycleSubject.hide()
}
/**
* 指定生命周期断开
*/
override fun <T : Any?> bindUntilEvent(event: FragmentEvent): LifecycleTransformer<T> {
return RxLifecycle.bindUntilEvent(this.lifecycleSubject, event)
}
/**
* 绑定生命周期到lifecycle
*/
override fun <T : Any?> bindToLifecycle(): LifecycleTransformer<T> {
return RxLifecycleAndroid.bindFragment(this.lifecycleSubject)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
this.lifecycleSubject.onNext(FragmentEvent.CREATE)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
if (null != this.mRootView) {
var parent = this.mRootView!!.parent
if (null != parent) {
(parent as ViewGroup).removeView(this.mRootView)
}
} else {
this.mRootView = inflater.inflate(this.mLayoutResId, container, false)
}
return this.mRootView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
this.lifecycleSubject.onNext(FragmentEvent.CREATE_VIEW)
}
private var mIsCalled = false
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (!this.mIsCalled) {
this.mIsCalled = true
onContentReady(savedInstanceState)
}
}
private var mContext: Context? = null
override fun onAttach(context: Context) {
super.onAttach(context)
this.mContext = context
this.lifecycleSubject.onNext(FragmentEvent.ATTACH)
}
override fun onStart() {
super.onStart()
this.lifecycleSubject.onNext(FragmentEvent.START)
}
override fun onResume() {
super.onResume()
this.lifecycleSubject.onNext(FragmentEvent.RESUME)
}
override fun onPause() {
super.onPause()
this.lifecycleSubject.onNext(FragmentEvent.PAUSE)
}
override fun onStop() {
super.onStop()
this.lifecycleSubject.onNext(FragmentEvent.STOP)
}
override fun onDestroy() {
super.onDestroy()
this.lifecycleSubject.onNext(FragmentEvent.DESTROY)
}
override fun onDestroyView() {
super.onDestroyView()
this.lifecycleSubject.onNext(FragmentEvent.DESTROY_VIEW)
}
override fun onDetach() {
super.onDetach()
this.lifecycleSubject.onNext(FragmentEvent.DETACH)
}
override fun getContext(): Context? {
var context = super.getContext()
if (null == context) context = this.mContext
return context
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
}
/**
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* 自己的方法
*/
abstract fun onContentReady(savedInstanceState: Bundle?)
fun <A> startActivity(clazz: Class<A>, data: Bundle?) {
this.mContext?.let {
var intent = Intent(it, clazz)
data?.let { intent.putExtras(data) }
this.startActivity(intent)
}
}
fun <A> startActivity(clazz: Class<A>) {
this.mContext?.let {
var intent = Intent(it, clazz)
this.startActivity(intent)
}
}
}
3、因为Retrofit的网络请求是OkHttp实现的,所以网络请求还是相当于封装OkHttp
class HttpRequest<ApiService> {
//请求超时时间5S
private val connectionTimeoutTime = 60L
private val httpLoggingInterceptor = HttpLoggingInterceptor().setLevel(
HttpLoggingInterceptor.Level.BODY
// else HttpLoggingInterceptor.Level.NONE
)
//构造OkhttpBuilder
private val okhttBuilder: OkHttpClient.Builder =
OkHttpClient.Builder()
.addNetworkInterceptor(httpLoggingInterceptor)
.addInterceptor(LogInterceptor())
//链接超时设置
.connectTimeout(connectionTimeoutTime, TimeUnit.SECONDS)
//读取超时时间设置
.readTimeout(connectionTimeoutTime, TimeUnit.SECONDS)
.writeTimeout(connectionTimeoutTime, TimeUnit.SECONDS)
//默认重试一次,若需要重试N次,则要实现拦截器。
.retryOnConnectionFailure(true)
class LogInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
Log.i(
"wxf",
" Requeste " + "\nmethod:" + request.method() + "\nurl:" + request.url() + "\nbody:" + request.body().toString()
)
var response = chain.proceed(request)
Log.i(
"wxf",
" Response " + "\nsuccessful:" + response.isSuccessful + "\nbody:" + response.peekBody(
1024
)?.string()
)
return response
}
}
/**
* 发起网络请求
*/
private fun buildOkHttpClient(): OkHttpClient {
return this.okhttBuilder.build()
}
/**
* 构建ApiService
*/
fun buildApiService(apiService: Class<ApiService>, baseurl: String): ApiService {
return Retrofit
.Builder()
.client(buildOkHttpClient())
.baseUrl(baseurl)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build().create(apiService)
}
}
/**
* 负责与服务器接口通信
*/
open class ApiRequest(private val progress: HttpObserver.Progress?) {
/**
* 服务器api响应实体类
*/
protected fun <Entity> request(
observable: Observable<Entity>,
lifecycleTransformer: LifecycleTransformer<Entity>,
callback: ResponseCallback<Entity>
) {
observable.compose(lifecycleTransformer)
.subscribeOn(Schedulers.io())//线程调度,发射事件的线程
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())//订阅者接收事件的线程
.subscribe(createHttpObserver(callback))//订阅
}
protected open fun <Entity> createHttpObserver(callback: ResponseCallback<Entity>): HttpObserver<Entity> {
return DefaultHttpObserver(callback, progress)
}
}
4、解析得到数据
class DefaultListResponseParse<Entity>(
private val callback: ResponseCallback<List<Entity>>,
private val entityClass: Class<Entity>
) : ResponseCallback<String> {
private val gson: Gson = Gson()
override fun onSuccess(response: String?) {
val basicEntity = parseResponse(response)
if (null != basicEntity) {
if (basicEntity.code == BasicResponse.CODE_SUCCESS) {
this.callback.onSuccess(parseEntitys(basicEntity))
}
} else {
onServerException()
}
}
override fun onFailed(ex: RequestException) {
}
private fun parseEntitys(response: BasicStringResponse?): List<Entity> {
val entitys = arrayListOf<Entity>()
if (!TextUtils.isEmpty(response?.ret)) {
var jsonArray: JSONArray? = null
try {
jsonArray = JSONArray(response?.ret)
} catch (e: Exception) {
}
if (null != jsonArray) {
Log.i("wxf", "array->" + jsonArray)
for (index in 0..(jsonArray.length() - 1)) {
var entity: Entity? = null
try {
entity = this.gson.fromJson(jsonArray.optString(index), entityClass)
} catch (e: Exception) {
}
if (null != entity) {
entitys.add(entity)
}
}
}
}
return entitys
}
private fun parseResponse(response: String?): BasicStringResponse? {
var basicEntity: BasicStringResponse? = null
var jsonObject: JSONObject? = null
if (!TextUtils.isEmpty(response)) {
try {
jsonObject = JSONObject(response)
} catch (e: Exception) {
}
if (null != jsonObject) {
basicEntity = BasicStringResponse()
basicEntity.code = jsonObject.optInt("code")
basicEntity.msg = jsonObject.optString("msg")
basicEntity.ret = jsonObject.optString("ret")
}
}
return basicEntity
}
private fun onServerException() {
onFailed(ServerException())
}
}
/**
* 将得到的String转换成Entity
*/
class DefaultResponseParse<Entity>(
private val callback: ResponseCallback<Entity>,
private val entityClass: Class<Entity>
) : ResponseCallback<String> {
private val gson: Gson = Gson()
override fun onSuccess(response: String?) {
Log.i("wxf","onSuccess"+response)
var basicEntity = parseResponse(response)
if (null != basicEntity) {
if (basicEntity.code == BasicResponse.CODE_SUCCESS) {
val entity = parseEntity(basicEntity.ret)
Log.i("wxf", "entity:" + entity)
this.callback.onSuccess(entity)
} else {
onFailed(RequestException(basicEntity.msg, basicEntity.errorCode.toInt()))
}
} else {
onServerException()
}
}
override fun onFailed(ex: RequestException) {
this.callback.onFailed(ex)
}
private fun parseResponse(response: String?): BasicStringResponse? {
var basicEntity: BasicStringResponse? = null
var jsonObject: JSONObject?
try {
jsonObject = JSONObject(response)
} catch (e: Exception) {
jsonObject = null
}
if (jsonObject != null) {
basicEntity = BasicStringResponse()
basicEntity.code = jsonObject.optInt("code")
basicEntity.msg = jsonObject.optString("msg")
basicEntity.ret = jsonObject.optString("ret")
}
return basicEntity
}
private fun onServerException() = this.onFailed(ServerException())
private fun parseEntity(data: String?): Entity? {
var entity: Entity? = null
try {
if (!TextUtils.isEmpty(data)) {
entity = this.gson.fromJson(data, this.entityClass)
}
} catch (e: Exception) {
}
return entity
}
}
5、使用
@POST("others/carousel")
fun getBanner(): Observable<BasicResponse<List<HomeBanner>>>
class HomeApi(context: Context?) : ApiRequest(context.let { DefaultHttpProgress(context) }) {
private val homeApiService =
HttpRequest<HomeApiService>()
.buildApiService(HomeApiService::class.java, Constool.BASE_URL)
fun getBanner(
lifecycleTransformer: LifecycleTransformer<BasicResponse<List<HomeBanner>>>,
callback: ResponseCallback<BasicResponse<List<HomeBanner>>>
) {
request(
this.homeApiService.getBanner(),
lifecycleTransformer, callback
)
}
}
HomeApi(this).let {
it.getBanner(
this.bindToLifecycle(),
object : ResponseCallback<BasicResponse<List<HomeBanner>>> {
override fun onSuccess(response: BasicResponse<List<HomeBanner>>?) {
response?.let {
Log.i("wxf", "getBanner->" + it.ret?.size)
}
}
override fun onFailed(ex: RequestException) {
}
})
}
代码在我的下载资源中有,名字为KT_Retrofit_Rxjava2