在项目中使用Hilt Retrofit使用总结


直接开始,首先我们看看怎么使用Hilt编写Retrofit接口请求类

用@Provides注解定义可注入的实例的提供者函数,如:provideHttpClient()用于提供OkHttpClient的实例,provideRetrofit()用于提供Retrofit实例

provideUserService()用于提供UserService的实例,这样我们就可以在其他的类里用@Inject获取注入该实例了。

完整代码:

@Module
@InstallIn(SingletonComponent::class)
/** 单例 */
object RetrofitModule {

    /** 服务地址 */
    private const val BASE_URL = Constant.SERVER_ADDRESS

    /** 提供OkHttpClient */
    @Singleton
    @Provides
    fun provideHttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
                .addInterceptor(LoggingInterceptor())
                .addInterceptor(HeaderInterceptor())
                .addInterceptor(BasicParamsInterceptor())
                .build()
    }

    /** 提供Retrofit */
    @Singleton
    @Provides
    fun provideRetrofit(httpClient: OkHttpClient): Retrofit {
        val builder = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(httpClient)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(GsonBuilder().registerTypeAdapterFactory(
                        GsonTypeAdapterFactory()
                ).create()))

        return builder.build()
    }

    /** 用hilt就不用这种创建对象的方式了 */
    fun <T> create(serviceClass: Class<T>): T = provideRetrofit(provideHttpClient()).create(serviceClass)

    /** 提供服务 */
    @Singleton
    @Provides
    fun provideUserService(retrofit: Retrofit): UserService = retrofit.create(UserService::class.java)


    /** 日志拦截器 */
    class LoggingInterceptor : Interceptor {

        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            val request = chain.request()
            val t1 = System.nanoTime()

            //logV(TAG, "发送请求: ${request.method()} ${request.url()} ${request.headers()}")

            logV(
                    TAG, String.format("发送请求 %s on %s%n%s",
                    request.url(), request.method(), request.headers()));

            val response = chain.proceed(request)

            val t2 = System.nanoTime()
            //logV(TAG, "Received response for  ${response.request().url()} in ${(t2 - t1) / 1e6} ms\n${response.headers()}")
            val responseBody: ResponseBody = response.peekBody((1024 * 1024).toLong())
            logV(
                    TAG,
                    String.format(
                            "接收响应: [%s] %n返回json:【%s】 %.1fms%n%s",
                            response.request().url(),
                            responseBody.string(),
                            (t2 - t1) / 1e6,
                            response.headers()
                    )
            )

            return response
        }

        companion object {
            const val TAG = "LoggingInterceptor"
        }
    }

    /** 增加Header */
    class HeaderInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val original = chain.request()
            val request = original.newBuilder().apply {
                header("model", "Android")
                header("If-Modified-Since", "${Date()}")
                header("User-Agent", System.getProperty("http.agent") ?: "unknown")
                MyApplication.instance().token?.apply {
                    header("token", MyApplication.instance().token!!)
                }

            }.build()
            return chain.proceed(request)
        }
    }

    /** 公共参数 */
    class BasicParamsInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val originalRequest = chain.request()
            val originalHttpUrl = originalRequest.url()
            val url = originalHttpUrl.newBuilder().apply {
                addQueryParameter("version", "${Build.VERSION.SDK_INT}")
            }.build()
            val request = originalRequest.newBuilder().url(url).method(originalRequest.method(), originalRequest.body()).build()
            return chain.proceed(request)
        }
    }
}

定义UserService接口

interface UserService {

    /**
     * 获取用户信息
     */
    @GET("/user/info")
    suspend fun userInfo(@Query("userId") userId:String): ServiceResult<User>

}

接着我们定义Repository的提供类,提供UserRepository类的实例

@Module
@InstallIn(ActivityComponent::class)
object RepositoryModule {

    @ActivityScoped
    @Provides
    fun provideUserRepository(userService: UserService):UserRepository {
        return UserRepository(userService)
    }

}

到目前为止我们定义了UserRepository  UserService的实例提供

下面就是怎么在Activity和ViewModel中使用UserRepository  UserService的实例

通过@HiltViewModel   @Inject 在构造函数中注入userRepository

@HiltViewModel
class LoginViewModel @Inject constructor(private val userRepository: UserRepository): ViewModel() {
    .............
}

在Activity中定义ViewModel,在Activity上增加@AndroidEntryPoint 

@AndroidEntryPoint
class LoginActivity : BaseActivity() {  private val loginViewModel: LoginViewModel by viewModels()
}

在Application中增加@HiltAndroidApp注解

@HiltAndroidApp
class MyApplication : Application(){
}

以上。





内容来源与作者发布和网络,如有版权相关问题请及时与我们取得联系,我们将立即删除。

关于作者

还如一梦中 点击这里给我发消息

相关推荐

这些你应该也会喜欢

在项目中使用Hilt Retrofit使用总结

直接开始,首先我们看看怎么使用Hilt编写Retrofit接口请求类用@Provides注解定义可注入的实例的提供者函数,如:provideHttpClient()用于提供OkHttpClient的实...

2021-12-24 09:53:05 还如一梦中
升级gradle7.0.2错误a repository over an insecure HTTP connection

Specifies whether it is acceptable to communicate with a repository over an insecure HTTP connection...

2021-12-21 09:25:24 还如一梦中
@HiltAndroidApp to have a value. Did you forget to apply the Gradle Plugin?

在Android应用中集成Hilt环境遇到这样一个错误,@HiltAndroidApp to have a value. Did you forget to apply the Gradle Plug...

2021-12-20 09:49:42 还如一梦中
Retrofit+Gson解析工具类封装

定义Retrofit Service类import android.os.Build import cn.wtyc.weiwogroup.global.Constant import cn.wtyc....

2021-12-16 10:38:34 还如一梦中
Android Jetpack Paging 3 下拉刷新和加载更多代码示例

使用Paging3实现列表的下拉刷新和加载更多首先定义列表布局文件androidx.swiperefreshlayout.widget.SwipeRefreshLayout a...

2021-12-16 09:43:09 还如一梦中
解决Flutter输入法遮挡页面问题

这个问题看网上有很多解决方法,发现几乎都是错误的,并且麻烦,这里有个简单的方法,借助bottom:MediaQuery.of(context).padding.bottom;这个bottom的值是系统...

2021-08-20 11:29:22 还如一梦中
Flutter给页面增加滚动SingleChildScrollView

使用SingleChildScrollView可以给页面增加滚动:late ScrollController _controller = ScrollController();SingleChildS...

2021-08-20 09:10:34 还如一梦中
2021Flutter发布package到Pub终极解决方案

整整折腾了1天半终于成功吧package上传到了pub上。先花了15在淘宝找人代注册了个google账户。先取消配置的环境变量FLUTTER_STORAGE_BASE_URL https://stor...

2021-05-27 11:49:52 还如一梦中
SpringBoot一梦支付系统搭建完全教程

懂Java Spring Boot的朋友可以选择性的参考被教程,小白就完全按步骤来吧!首先Linux系统安装宝塔,这个省略然后安装Java环境,有2种方式:第一种下载java8 sdk 然后设置Lin...

2021-07-13 19:18:28 还如一梦中
Oracle之分区数据删除

---查看分区的名字SELECT a.table_name,a.partition_name FROM user_tab_partitions  a WHERE a.table_name = 'TES...

2021-07-14 16:34:52 落花飞雪
在线客服