直接开始,首先我们看看怎么使用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(){
}
以上。
本站内容来源于作者发布和网络转载,如有版权相关问题请及时与我们取得联系,我们将立即删除。