Skip to content

Commit

Permalink
1.添加一个可以委托创建服务的接口
Browse files Browse the repository at this point in the history
  • Loading branch information
tiamosu committed Sep 25, 2019
1 parent 27b8f33 commit 737aa05
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 116 deletions.
4 changes: 2 additions & 2 deletions app/src/main/res/layout/fragment_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@
android:id="@+id/main_login_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"/>
android:text="Hello World!"/>

<androidx.appcompat.widget.AppCompatButton
android:id="@+id/main_open_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开通托管账户"/>
android:text="Hello World!"/>

<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ abstract class BaseRequest<R : BaseRequest<R>>(@JvmField protected val mUrl: Str
return this as R
}

protected abstract fun generateRequest(): Observable<ResponseBody>
protected abstract fun generateRequest(): Observable<ResponseBody>?

fun build(): RequestCall {
return RequestCall(generateRequest())
Expand Down
14 changes: 7 additions & 7 deletions fly-http/src/main/java/com/xia/fly/http/request/DeleteRequest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,25 @@ import okhttp3.ResponseBody
*/
class DeleteRequest(url: String) : BaseBodyRequest<DeleteRequest>(url) {

override fun generateRequest(): Observable<ResponseBody> {
override fun generateRequest(): Observable<ResponseBody>? {
if (mRequestBody != null) {
return mRestService.deleteBody(mUrl, mRequestBody!!, mHeaders)
return mRestService?.deleteBody(mUrl, mRequestBody!!, mHeaders)
}
if (mJson != null) {
val body = RequestBody.create(mMediaType, mJson!!)
return mRestService.deleteJson(mUrl, body, mHeaders)
return mRestService?.deleteJson(mUrl, body, mHeaders)
}
if (mObject != null) {
return mRestService.deleteBody(mUrl, mObject!!, mHeaders)
return mRestService?.deleteBody(mUrl, mObject!!, mHeaders)
}
if (mBytes != null) {
val body = RequestBody.create(mMediaType, mBytes!!)
return mRestService.deleteBody(mUrl, body, mHeaders)
return mRestService?.deleteBody(mUrl, body, mHeaders)
}
if (mString != null) {
val body = RequestBody.create(mMediaType, mString!!)
return mRestService.deleteBody(mUrl, body, mHeaders)
return mRestService?.deleteBody(mUrl, body, mHeaders)
}
return mRestService.delete(mUrl, mParams, mHeaders)
return mRestService?.delete(mUrl, mParams, mHeaders)
}
}
6 changes: 3 additions & 3 deletions fly-http/src/main/java/com/xia/fly/http/request/GetRequest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class GetRequest(url: String) : BaseRequest<GetRequest>(url) {
return this
}

override fun generateRequest(): Observable<ResponseBody> {
override fun generateRequest(): Observable<ResponseBody>? {
return if (mIsDownload) {
mRestService.downloadFile(mUrl, mHeaders)
} else mRestService[mUrl, mParams, mHeaders]
mRestService?.downloadFile(mUrl, mHeaders)
} else mRestService?.get(mUrl, mParams, mHeaders)
}
}
16 changes: 8 additions & 8 deletions fly-http/src/main/java/com/xia/fly/http/request/PostRequest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,32 @@ class PostRequest(url: String) : BaseBodyRequest<PostRequest>(url) {
return this
}

override fun generateRequest(): Observable<ResponseBody> {
override fun generateRequest(): Observable<ResponseBody>? {
if (mRequestBody != null) {
return mRestService.postBody(mUrl, mRequestBody!!, mHeaders)
return mRestService?.postBody(mUrl, mRequestBody!!, mHeaders)
}
if (mJson != null) {
val body = RequestBody.create(mMediaType, mJson!!)
return mRestService.postJson(mUrl, body, mHeaders)
return mRestService?.postJson(mUrl, body, mHeaders)
}
if (mObject != null) {
return mRestService.postBody(mUrl, mObject!!, mHeaders)
return mRestService?.postBody(mUrl, mObject!!, mHeaders)
}
if (mBytes != null) {
val body = RequestBody.create(mMediaType, mBytes!!)
return mRestService.postBody(mUrl, body, mHeaders)
return mRestService?.postBody(mUrl, body, mHeaders)
}
if (mString != null) {
val body = RequestBody.create(mMediaType, mString!!)
return mRestService.postBody(mUrl, body, mHeaders)
return mRestService?.postBody(mUrl, body, mHeaders)
}

return if (mFileParams.isEmpty()) {
mRestService.post(mUrl, mParams, mHeaders)
mRestService?.post(mUrl, mParams, mHeaders)
} else {
val builder = MultipartBody.Builder().setType(MultipartBody.FORM)
val body = addParams(builder)
mRestService.uploadFiles(mUrl, body, mHeaders)
mRestService?.uploadFiles(mUrl, body, mHeaders)
}
}

Expand Down
14 changes: 7 additions & 7 deletions fly-http/src/main/java/com/xia/fly/http/request/PutRequest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,25 @@ import okhttp3.ResponseBody
*/
class PutRequest(url: String) : BaseBodyRequest<PutRequest>(url) {

override fun generateRequest(): Observable<ResponseBody> {
override fun generateRequest(): Observable<ResponseBody>? {
if (mRequestBody != null) {
return mRestService.putBody(mUrl, mRequestBody!!, mHeaders)
return mRestService?.putBody(mUrl, mRequestBody!!, mHeaders)
}
if (mJson != null) {
val body = RequestBody.create(mMediaType, mJson!!)
return mRestService.putJson(mUrl, body, mHeaders)
return mRestService?.putJson(mUrl, body, mHeaders)
}
if (mObject != null) {
return mRestService.putBody(mUrl, mObject!!, mHeaders)
return mRestService?.putBody(mUrl, mObject!!, mHeaders)
}
if (mBytes != null) {
val body = RequestBody.create(mMediaType, mBytes!!)
return mRestService.putBody(mUrl, body, mHeaders)
return mRestService?.putBody(mUrl, body, mHeaders)
}
if (mString != null) {
val body = RequestBody.create(mMediaType, mString!!)
return mRestService.putBody(mUrl, body, mHeaders)
return mRestService?.putBody(mUrl, body, mHeaders)
}
return mRestService.put(mUrl, mParams, mHeaders)
return mRestService?.put(mUrl, mParams, mHeaders)
}
}
2 changes: 1 addition & 1 deletion fly/src/main/java/com/xia/fly/di/module/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ abstract class AppModule {
@JvmStatic
@Singleton
@Provides
fun provideExtras(cacheFactory: Cache.Factory<String, Any>): Cache<String, Any> {
fun provideExtras(cacheFactory: Cache.Factory<String, Any?>): Cache<String, Any?> {
return cacheFactory.build(CacheType.EXTRAS)
}

Expand Down
12 changes: 6 additions & 6 deletions fly/src/main/java/com/xia/fly/di/module/GlobalConfigModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class GlobalConfigModule private constructor(builder: Builder) {
private val mOkHttpConfiguration: ClientModule.OkHttpConfiguration?
private val mRxCacheConfiguration: ClientModule.RxCacheConfiguration?
private val mGsonConfiguration: AppModule.GsonConfiguration?
private val mCacheFactory: Cache.Factory<String, Any>?
private val mCacheFactory: Cache.Factory<String, Any?>?
private val mExecutorService: ExecutorService?

init {
Expand Down Expand Up @@ -139,9 +139,9 @@ class GlobalConfigModule private constructor(builder: Builder) {

@Singleton
@Provides
internal fun provideCacheFactory(application: Application): Cache.Factory<String, Any> {
return mCacheFactory ?: object : Cache.Factory<String, Any> {
override fun build(type: CacheType): Cache<String, Any> {
internal fun provideCacheFactory(application: Application): Cache.Factory<String, Any?> {
return mCacheFactory ?: object : Cache.Factory<String, Any?> {
override fun build(type: CacheType): Cache<String, Any?> {
//若想自定义 LruCache 的 size, 或者不想使用 LruCache, 想使用自己自定义的策略
//使用 GlobalConfigModule.Builder#cacheFactory() 即可扩展
return when (type.getCacheTypeId()) {
Expand Down Expand Up @@ -182,7 +182,7 @@ class GlobalConfigModule private constructor(builder: Builder) {
var mOkHttpConfiguration: ClientModule.OkHttpConfiguration? = null
var mRxCacheConfiguration: ClientModule.RxCacheConfiguration? = null
var mGsonConfiguration: AppModule.GsonConfiguration? = null
var mCacheFactory: Cache.Factory<String, Any>? = null
var mCacheFactory: Cache.Factory<String, Any?>? = null
var mExecutorService: ExecutorService? = null

fun baseurl(baseUrl: String): Builder {//基础url
Expand Down Expand Up @@ -246,7 +246,7 @@ class GlobalConfigModule private constructor(builder: Builder) {
return this
}

fun cacheFactory(cacheFactory: Cache.Factory<String, Any>): Builder {
fun cacheFactory(cacheFactory: Cache.Factory<String, Any?>): Builder {
this.mCacheFactory = cacheFactory
return this
}
Expand Down
18 changes: 16 additions & 2 deletions fly/src/main/java/com/xia/fly/integration/IRepositoryManager.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.xia.fly.integration

import android.content.Context
import androidx.annotation.Nullable
import retrofit2.Retrofit

/**
* 用来管理网络请求层,以及数据缓存层,以后可能添加数据库请求层
Expand All @@ -21,11 +23,11 @@ interface IRepositoryManager {
/**
* 根据传入的 Class 获取对应的 Retrofit service
*
* @param service Retrofit service class
* @param serviceClass Retrofit service class
* @param <T> Retrofit service 类型
* @return Retrofit service
</T> */
fun <T> obtainRetrofitService(service: Class<T>): T
fun <T> obtainRetrofitService(serviceClass: Class<T>): T?

/**
* 根据传入的 Class 获取对应的 RxCache service
Expand All @@ -40,4 +42,16 @@ interface IRepositoryManager {
* 清理所有缓存
*/
fun clearAllCache()

/**
* 设置一个可以委托创建服务的接口
*
* @param delegate 委托接口,可为空
*/
fun setObtainServiceDelegate(@Nullable delegate: ObtainServiceDelegate?)

interface ObtainServiceDelegate {
@Nullable
fun <T> createRetrofitService(retrofit: Retrofit?, serviceClass: Class<T>?): T?
}
}
108 changes: 29 additions & 79 deletions fly/src/main/java/com/xia/fly/integration/RepositoryManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@ import com.xia.fly.integration.cache.Cache
import com.xia.fly.integration.cache.CacheType
import com.xia.fly.utils.Preconditions
import dagger.Lazy
import io.reactivex.Observable
import io.reactivex.Single
import io.rx_cache2.internal.RxCache
import retrofit2.Retrofit
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy
import javax.inject.Inject
import javax.inject.Singleton
Expand Down Expand Up @@ -39,110 +35,60 @@ constructor() : IRepositoryManager {
internal var mApplication: Application? = null
@JvmField
@Inject
internal var mCacheFactory: Cache.Factory<String, Any>? = null
internal var mCacheFactory: Cache.Factory<String, Any?>? = null

private var mRetrofitServiceCache: Cache<String, Any>? = null
private var mCacheServiceCache: Cache<String, Any>? = null
private var mRetrofitServiceCache: Cache<String, Any?>? = null
private var mCacheServiceCache: Cache<String, Any?>? = null
private var mDelegate: IRepositoryManager.ObtainServiceDelegate? = null

/**
* 根据传入的 Class 获取对应的 Retrofit service
*
* @param service ApiService class
* @param <T> ApiService class
* @return ApiService
</T> */
@Synchronized
override fun <T> obtainRetrofitService(service: Class<T>): T {
return createWrapperService(service)
}

/**
* 根据 https://zhuanlan.zhihu.com/p/40097338 对 Retrofit 进行的优化
*
* @param serviceClass ApiService class
* @param <T> ApiService class
* @return ApiService
</T> */
@Suppress("UNUSED_ANONYMOUS_PARAMETER")
private fun <T> createWrapperService(serviceClass: Class<T>): T {
Preconditions.checkNotNull<Any>(serviceClass, "serviceClass == null")

// 二次代理
return Proxy.newProxyInstance(serviceClass.classLoader,
arrayOf<Class<*>>(serviceClass), InvocationHandler { proxy, method, args ->
// 此处在调用 serviceClass 中的方法时触发
if (method.returnType == Observable::class.java) {
// 如果方法返回值是 Observable 的话,则包一层再返回。
// 只包一层 defer 由外部去控制耗时方法以及网络请求所处线程,
// 如此对原项目的影响为 0,且更可控。
return@InvocationHandler Observable.defer {
val service = getRetrofitService(serviceClass)
// 执行真正的 Retrofit 动态代理的方法
getRetrofitMethod(service, method)
.invoke(service, *args) as Observable<*>
}
} else if (method.returnType == Single::class.java) {
// 如果方法返回值是 Single 的话,则包一层再返回。
return@InvocationHandler Single.defer {
val service = getRetrofitService(serviceClass)
// 执行真正的 Retrofit 动态代理的方法
getRetrofitMethod(service, method)
.invoke(service, *args) as Single<*>
}
}

// 返回值不是 Observable 或 Single 的话不处理。
val service = getRetrofitService(serviceClass)
getRetrofitMethod(service, method).invoke(service, *args)
}) as T
}

/**
* 根据传入的 Class 获取对应的 Retrofit service
*
* @param serviceClass ApiService class
* @param <T> ApiService class
* @return ApiService
</T> */
private fun <T> getRetrofitService(serviceClass: Class<T>): T? {
*/
@Synchronized
override fun <T> obtainRetrofitService(serviceClass: Class<T>): T? {
if (mRetrofitServiceCache == null) {
mRetrofitServiceCache = mCacheFactory!!.build(CacheType.RETROFIT_SERVICE_CACHE)
mRetrofitServiceCache = mCacheFactory?.build(CacheType.RETROFIT_SERVICE_CACHE)
}
Preconditions.checkNotNull<Any>(mRetrofitServiceCache,
"Cannot return null from a Cache.Factory#build(int) method")
var retrofitService = mRetrofitServiceCache!![serviceClass.canonicalName!!] as T?
if (retrofitService == null && mRetrofit != null) {
retrofitService = mRetrofit!!.get().create(serviceClass)
mRetrofitServiceCache!!.put(serviceClass.canonicalName!!, retrofitService!!)
val canonicalName = serviceClass.canonicalName ?: ""
var retrofitService = mRetrofitServiceCache?.get(canonicalName) as T?
if (retrofitService == null) {
retrofitService = mDelegate?.createRetrofitService(mRetrofit?.get(), serviceClass)
if (retrofitService == null) {
retrofitService = Proxy.newProxyInstance(
serviceClass.classLoader, arrayOf<Class<*>>(serviceClass),
RetrofitServiceProxyHandler(mRetrofit?.get(), serviceClass)) as? T
}
mRetrofitServiceCache?.put(canonicalName, retrofitService)
}
return retrofitService
}

@Throws(NoSuchMethodException::class)
private fun <T> getRetrofitMethod(service: T, method: Method): Method {
return (service as Any).javaClass.getMethod(method.name, *method.parameterTypes)
}

/**
* 根据传入的 Class 获取对应的 RxCache service
*
* @param cache Cache class
* @param <T> Cache class
* @return Cache
</T> */
*/
@Synchronized
override fun <T> obtainCacheService(cache: Class<T>): T? {
Preconditions.checkNotNull<Any>(cache, "cacheClass == null")

if (mCacheServiceCache == null) {
mCacheServiceCache = mCacheFactory!!.build(CacheType.CACHE_SERVICE_CACHE)
mCacheServiceCache = mCacheFactory?.build(CacheType.CACHE_SERVICE_CACHE)
}
Preconditions.checkNotNull<Any>(mCacheServiceCache,
"Cannot return null from a Cache.Factory#build(int) method")
var cacheService = mCacheServiceCache!![cache.canonicalName!!] as T?
if (cacheService == null && mRxCache != null) {
cacheService = mRxCache!!.get().using(cache)
mCacheServiceCache!!.put(cache.canonicalName!!, cacheService!!)
val canonicalName = cache.canonicalName ?: ""
var cacheService = mCacheServiceCache?.get(canonicalName) as T?
if (cacheService == null) {
cacheService = mRxCache?.get()?.using(cache)
mCacheServiceCache?.put(canonicalName, cacheService)
}
return cacheService
}
Expand All @@ -157,4 +103,8 @@ constructor() : IRepositoryManager {
override fun getContext(): Context {
return mApplication!!
}

override fun setObtainServiceDelegate(delegate: IRepositoryManager.ObtainServiceDelegate?) {
mDelegate = delegate
}
}
Loading

0 comments on commit 737aa05

Please sign in to comment.