您的位置:首页 > 理论基础 > 计算机网络

Android 网络访问框架retrofit2,okhttp3之简单封装,kotlin源码

2017-08-28 15:40 716 查看
本文章需要用到的引用

//okhttp
compile 'com.squareup.okhttp3:okhttp:3.8.0'
//retrofit
compile 'com.squareup.retrofit2:retrofit:2.3.0'
//rxjava
compile 'io.reactivex.rxjava2:rxjava:2.0.7'
//rxjava适配器,方便rxjava与retrofit的结合
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
//Log拦截器,方便DEBUG模式输出log信息
compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
//json转换器,方便将返回的数据转换为json格式
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
//rxandroid
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.github.bumptech.glide:glide:3.7.0'


定义:

1.基于retrofit2和okhttp3的网络访问简单封装。

基本封装类

RetrofitClient.kt

import android.content.Context
import android.util.Log
import java.io.File
import okhttp3.Cache
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.Retrofit
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.OkHttpClient
import java.util.concurrent.TimeUnit

/**
* @author Created by qlang on 2017/7/14.
*/
class RetrofitClient private constructor(context: Context, baseUrl: String) {
var httpCacheDirectory: File? = null
val mContext: Context = context
var cache: Cache? = null
var okHttpClient: OkHttpClient? = null
var retrofit: Retrofit? = null
val DEFAULT_TIMEOUT: Long = 20
val url = baseUrl

init {
//缓存地址
if (httpCacheDirectory == null) {
httpCacheDirectory = File(mContext.cacheDir, "app_cache")
}
try {
if (cache == null) {
cache = Cache(httpCacheDirectory, 10 * 1024 * 1024)
}
} catch (e: Exception) {
Log.e("OKHttp", "Could not create http cache", e)
}
//okhttp创建了
okHttpClient = OkHttpClient.Builder()
.addNetworkInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.cache(cache)
.addInterceptor(CacheInterceptor(context))
.addNetworkInterceptor(CacheInterceptor(context))
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.build()
//retrofit创建了
retrofit = Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(url)
.build()
}

companion object {
@Volatile
var instance: RetrofitClient? = null
var context: Context? = null

fun init(context: Context) {
if (context == null) {
throw NullPointerException("context can not be null.")
return
}
this.context = context
}

fun getInstance(baseUrl: String): RetrofitClient {
if (instance == null) {
synchronized(RetrofitClient::class) {
if (context == null) throw NullPointerException("context is null.Use init(content) in your Application")
if (instance == null) {
instance = RetrofitClient(context!!, baseUrl)
}
}
}
return instance!!
}
}

fun <T> create(service: Class<T>?): T? {
if (service == null) {
throw RuntimeException("Api service is null!")
}
return retrofit?.create(service)
}
}


缓存辅助类:

CacheInterceptor.kt


import android.content.Context
import android.util.Log
import com.ql.ufun.utils.NetworkUtils
import okhttp3.Interceptor
import okhttp3.Response
import okhttp3.CacheControl

/**
* @author Created by qlang on 2017/7/14.
*/
class CacheInterceptor(context: Context) : Interceptor {
val context = context
override fun intercept(chain: Interceptor.Chain?): Response? {
var request = chain?.request()
if (NetworkUtils.isNetConneted(context)) {
val response = chain?.proceed(request)
// read from cache for 60 s
val maxAge = 60
val cacheControl = request?.cacheControl().toString()
Log.e("CacheInterceptor", "6s load cahe" + cacheControl)
return response?.newBuilder()?.removeHeader("Pragma")?.removeHeader("Cache-Control")?.header("Cache-Control", "public, max-age=" + maxAge)?.build()
} else {
Log.e("CacheInterceptor", " no network load cahe")
request = request?.newBuilder()?.cacheControl(CacheControl.FORCE_CACHE)?.build()
val response = chain?.proceed(request)
//set cahe times is 3 days
val maxStale = 60 * 60 * 24 * 3
return response?.newBuilder()?.removeHeader("Pragma")?.removeHeader("Cache-Control")?.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)?.build()
}
}

}

使用:

1.定义接口

ApiServer.kt

interface ApiServer {
companion object {
val BASE_URL: String get() = "http://route.xxx.com/"
}

@GET("xxxxxx")
fun getHomeTxtData(@Query("xxx") apiid: String, @Query("xxx") sign: String, @Query("currPage") page: String, @Query("maxResult") num: String): Observable<Xxxxx>

2.定义Base Model

BaseModel.kt

import com.ql.xxx.net.ApiServer
import com.ql.xxx.net.RetrofitClient
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers

/**
* @author Created by qlang on 2017/7/18.
*/
open class BaseModel {
fun buildServer(): RetrofitClient {
return RetrofitClient.getInstance(ApiServer.BASE_URL)
}

fun <T> Observable<T>.applySchedulers(): Observable<T> {
return subscribeOn(Schedulers.io()).
unsubscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread())
}
}


3.具体的Model

MainModel.kt

/**
* @author Created by qlang on 2017/7/18.
*/
class MainModel : BaseModel() {

fun loadTextData(index: Int): Observable<Xxxxx>? {
val server = buildServer().create(ApiServer::class.java)
return server?.getHomeTxtData(ApiServer.API_ID, ApiServer.API_SIGN, "$index", "20")?.applySchedulers()
}
}


4.发起请求
val model: MainModel by lazy {
MainModel()
}
val observable: Observable<Xxxxx>? = model.loadTextData(index)
observable?.subscribe({ bean: Xxxxx -> listener?.onSuccRespone(bean) },
{ err: Throwable -> listener?.onErrRespone(err) })

附:

基于Glide的图片加载简单封装

ImageLoader.kt

import android.content.Context
import android.graphics.Bitmap
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.ql.ufun.R

/**
* @author Created by qlang on 2017/7/19.
*/
class ImageLoader {

interface BitmapListener {
fun onCall(bitmap: Bitmap?)
}

companion object {
fun <T : ImageView> loadImg(context: Context, url: String, imageView: T?) {
loadImg(context, url, imageView, R.mipmap.ic_default_img, R.mipmap.ic_default_img)
}

fun <T : ImageView> loadBigImg(context: Context, url: String, imageView: T?) {
if (imageView == null) {
throw IllegalArgumentException("argument error")
}
Glide.with(context).load(url)
.asBitmap()
.format(DecodeFormat.PREFER_ARGB_8888)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.mipmap.ic_default_img)
.error(R.mipmap.ic_default_img)
.into(imageView)
}

fun <T : ImageView> loadImg(context: Context, url: String, imageView: T?, defaultImageResId: Int, errImageResId: Int) {
if (imageView == null) {
throw IllegalArgumentException("argument error")
}
Glide.with(context).load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(defaultImageResId)
.error(errImageResId)
.crossFade().into(imageView)
}

fun loadImg(context: Context, url: String, listener: BitmapListener?) {
Glide.with(context).load(url)
.asBitmap()
.format(DecodeFormat.PREFER_ARGB_8888)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(object : SimpleTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap?, glideAnimation: GlideAnimation<in Bitmap>?) {
listener?.onCall(resource)
}
})
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐