Cursor blinking

OkHttp+Retrofit 使用示例

Android 基础|RetrofitRxJava|字数 111|阅读时长≈ 1 分钟
OkHttp+Retrofit 使用示例

添加依赖

项目或 module 下的  build.gradle 文件添加如下依赖

Code
dependencies {	... 	// rxandroid    api 'io.reactivex.rxjava2:rxandroid:2.1.1'    api 'io.reactivex.rxjava2:rxjava:2.2.19'    // okhttp    api 'com.squareup.okhttp3:okhttp:4.11.0'    api 'com.squareup.okio:okio:3.2.0'    api 'com.squareup.okhttp3:logging-interceptor:4.12.0'    // retrofit    api 'com.squareup.retrofit2:retrofit:2.9.0'    api 'com.squareup.retrofit2:converter-moshi:2.9.0'    api 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'    api 'com.squareup.retrofit2:converter-gson:2.9.0'}

配置 OkHttp、Retrofit

OkHttp 的管理类

Code
/** * @Des OkHttp 配置 * @Author lipengfei * @Date 2023/11/27 18:06 */public class OkHttpFamily {    private static final String TAG = OkHttpFamily.class.getSimpleName();    private static volatile OkHttpClient API;     private OkHttpFamily() {    }     public static OkHttpClient API() {        if (null == API) {            synchronized (TAG) {                if (null == API) {                    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();                    logging.setLevel(HttpLoggingInterceptor.Level.BODY);                    OkHttpClient.Builder builder = new OkHttpClient.Builder();                    builder.connectTimeout(15L, TimeUnit.SECONDS)                            .writeTimeout(15L, TimeUnit.SECONDS)                            .readTimeout(15L, TimeUnit.SECONDS);                    builder.addInterceptor(logging);                    for (Interceptor interceptor : HttpConfig.INSTANCE.getConfig().getInterceptors()) {                        builder.addInterceptor(interceptor);                        Log.i(TAG, "addInterceptor" + interceptor.getClass().getSimpleName());                    }                    API = builder.build();                }            }        }        return API;    }}

Retrofit 的管理类

Code
/** * @Des Retrofit 配置 [单例] * @Author lipengfei * @Date 2023/11/27 18:06 */public class RetrofitFamily {     private static Retrofit retrofit;    // 使用 map 缓存已存在的    private static final Map<Class<?>, Object> SERVICE_MAP = new ConcurrentHashMap<>();     private RetrofitFamily() {    }     public static synchronized Retrofit getInstance() {        if (null == retrofit) {            retrofit = new Retrofit.Builder()                    .client(OkHttpFamily.API())                    .baseUrl(HttpConfig.INSTANCE.getConfig().getBaseUrl())                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())                    .addConverterFactory(GsonConverterFactory.create())                    .build();        }        return retrofit;    }     /**     * 创建 Retrofit service。     */    public static <T> T createService(@NonNull Class<T> service) {        T serviceImpl = (T) SERVICE_MAP.get(service);        if (null == serviceImpl) {            serviceImpl = createService(getInstance(), service);            SERVICE_MAP.put(service, serviceImpl);        }        return serviceImpl;    }     private static <T> T createService(Retrofit retrofit, Class<T> service) {        return retrofit.create(service);    }     /**     * 切换环境后重置     */    static synchronized void reset() {        retrofit = null;        SERVICE_MAP.clear();    }}  

网络请求相关的配置放入一个统一的文件

Code
/** * @Des 请求配置统一管理 * @Author lipengfei * @Date 2023/11/27 18:06 */object HttpConfig {     var config: Config? = null     fun initConfig(config: Config) {        this.config = config    }     class Config private constructor(val baseUrl: String, val interceptors: ArrayList<Interceptor>) {        companion object {            inline fun build(block: Builder.() -> Unit) = Builder().apply(block).build()        }         class Builder {            var baseUrl: String = ""            private val interceptors: ArrayList<Interceptor> = ArrayList()            fun addInterceptor(interceptor: Interceptor) {                interceptors.add(interceptor)            }             fun build() = Config(baseUrl, interceptors)        }    }}

发起第一个接口请求

在 app 启动时对 http 请求进行初始化配置

Code
class MyApplication : Application() {    override fun onCreate() {        super.onCreate()        initHttpConfig()    }     private fun initHttpConfig() {        val config = HttpConfig.Config.build {			// 设置 baseUrl            this.baseUrl = ConfigC.PEXELS_BASE_URL			// 设置 拦截器            this.addInterceptor(CommonInterceptor())        }		// 需要在第一个接口请求发起之前配置,也可以做延迟处理        HttpConfig.initConfig(config)    }}

发起网络请求

Code
class RPhotosViewModel : BaseViewModel() {    val photosLiveData = MutableLiveData<Result<List<Photo>>>()    fun searchPhotos() {        if (photosLiveData.value is Result.Loading) {            return        }        photosLiveData.value = Result.Loading        compositeDisposable.add(            RetrofitFamily.createService(PexelsApi::class.java)                .searchPhotos("art", 1, ConstC.PAGE_COUNT_TEN).subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe({                    debug("success: photos.size=${it.photos.size}")                    photosLiveData.value = Result.Success(it.photos)                }) { onError: Throwable? ->                    error("fail:", onError)                    photosLiveData.value = Result.Error(null, onError?.message)                })    }}

Activity/Fragment 中做对应的 UI 展示

Code
 viewModel.photosLiveData.observe(this) {            when (it) {                is Result.Loading -> {                    showLoading()                }                is Result.Success -> {                    hideLoading()                    photoAdapter.setDatas(it.value)                }                is Result.Error, Result.NetworkError -> {                    hideLoading()                    toast("error")                }            }        }

这样一个完整的接口请求就完成了

代码链接