Android Kotlin Retrofit MVP网络请求封装(四)

发布时间 2023-06-21 19:40:52作者: 蟾宝

依赖

   implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.google.code.gson:gson:2.8.8'

    implementation 'com.squareup.okhttp3:okhttp:4.9.1'
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
    implementation 'com.google.code.gson:gson:2.8.6'

    implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
AndroidManifest.xml
  <uses-permission android:name="android.permission.INTERNET" />

上下文

package com.example.app

import android.app.Application
import android.content.Context


/**
 *@author: jst
 *@date:   2023/6/19 0000 18:01
 *@desc:   上下文
 */
class App : Application() {
    companion object {
        private var context: Context? = null
        fun getContext(): Context? {
            return context
        }
    }

    override fun onCreate() {
        super.onCreate()
        context = applicationContext
    }


}

 

application中加
 android:name=".App"

新建http,entity软件包

http网络连接请求封装

entity 实体

在http中封装Result 回调类(接口返回类)

package com.example.app.http

/**
 *@author: jst
 *@date:   2023/6/19 0000 18:01
 *@desc:  回调数据
 */
class Result<T> {
    /*
    var errorMsg: String? = null
    var errorCode: String? = null
    var data: T? = null
     */
    var res: Int? = 0
    var msg: String? = null

}

在entity实体中封装UserBean

package com.example.app.entity

class UserBean {
}

在http中封装接口请求基本回调抽象类

package com.example.app.http

import android.util.Log
import android.widget.Toast
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.internal.EverythingIsNonNull
import java.net.UnknownHostException
import  com.example.app.App

/**
 *@author: jst
 *@date:   2023/6/19 0000 18:01
 *@desc:  接口请求基本回调
 */
abstract class SingleCallback<T : Result<*>?> :
    Callback<T> {
    override fun onResponse(
        call: Call<T>,
        response: Response<T>
    ) {
        val result = response.body()
        if (result == null) {
            onFailure("-99", "接口请求失败", null)
        } else {
            if (apiFailure(result)) {
                onFailure(result.msg, result.msg ?: "", result)
            } else {
                onSuccess(result)
            }
        }
    }

    @EverythingIsNonNull
    override fun onFailure(call: Call<T>, t: Throwable) {
        Log.e("SingleCallback", "onFailure: " + t.message, t)
        if (t is UnknownHostException) {
            onFailure("-99", "接口请求失败", null)
        } else if (!"socket closed".equals(t.localizedMessage, ignoreCase = true)
            && !"canceled".equals(t.localizedMessage, ignoreCase = true)
        ) {
            onFailure("-999", "接口请求失败", null)
        }
    }

    fun successCode(): Int {
        return 1
    }

    fun apiFailure(result: T?): Boolean {
        return result == null || successCode() != result.res
    }

    /**
     * 失败回调。默认已经将失败信息提示出来
     */
    fun onFailure(code: String?, message: String, response: T?) {
        Toast.makeText(App.getContext(), message, Toast.LENGTH_SHORT).show()

    }


    abstract fun onSuccess(response: T)

}

 

在http中封装请求工具类HttpHelper

package com.example.app.http

import com.google.gson.GsonBuilder
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.util.concurrent.TimeUnit


/**
 *@author: jst
 *@date:   2023/6/19 0000 18:01
 *@desc:  接口请求工具类
 */
class HttpHelper {
    companion object {
        private val BASE_URL = "https:www.baidu.com" //接口域名
        private var sHttpClient: OkHttpClient? = null
        private var sApi: Api? = null

        fun getHttpClient(): OkHttpClient? {
            if (sHttpClient == null) {
                synchronized(HttpHelper::class.java) {
                    if (sHttpClient == null) {
                        val builder = OkHttpClient.Builder()
                        /**
                         * 打印日志
                         */
                        var interceptor = HttpLoggingInterceptor()
                        interceptor.level = HttpLoggingInterceptor.Level.BODY
                        builder.addInterceptor(interceptor)
                        sHttpClient = builder
                            .callTimeout(40, TimeUnit.SECONDS)
                            .connectTimeout(40, TimeUnit.SECONDS)
                            .readTimeout(40, TimeUnit.SECONDS)
                            .writeTimeout(40, TimeUnit.SECONDS)
                            .build()
                    }
                }
            }
            return sHttpClient
        }

        fun getApi(): Api? {
            if (sApi == null) {
                synchronized(HttpHelper::class.java) {
                    if (sApi == null) {
                        val retrofit = createRetrofit(BASE_URL)
                        sApi = retrofit.create(Api::class.java)
                    }
                }
            }
            return sApi
        }

        private fun createRetrofit(baseUrl: String): Retrofit {
            val gsonBuilder = GsonBuilder()
            return Retrofit.Builder()
                .client(getHttpClient())
                .baseUrl(baseUrl)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(gsonBuilder.create()))
                .build()
        }
    }
}

 

在http中新建Api接口

package com.example.app.http

import com.example.app.entity.UserBean
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.http.*
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;

/**
 *@author: jst
 *@date:   2023/6/19 0000 18:01
 *@desc:  接口
 */
interface  Api {
    /**
     * 登录
     */
    @POST("/api/PDA/Checkuseradmin")
    @FormUrlEncoded
    fun login(@Field("username") account: String, @Field("password") password: String): Call<Result<UserBean>>


    /**
     * 登录
     */
    @GET("/api/PDA/Checkuseradmin")
    fun loginS(@Query("username") username:String,@Query("password") password: String):Call<Result<UserBean>>



    /**
     * 退出
     */
    @GET("/user/logout/json")
    fun logout(): Call<kotlin.Result<String>>

}

在model 登录实现类中调接口实现登录

 

 HttpHelper.getApi()?.loginS(userName, password)
            ?.enqueue(object : SingleCallback<Result<UserBean>>() {
                override fun onSuccess(response: Result<UserBean>) {
                    if (1 == response.res) {
                        onLoginListener.onSuccess()
                    } else {
                        onLoginListener.onError()
                    }
                }
            })

 

 效果