Android – 使用泛型有一个RxJava翻新调用使用相同的接口返回各种类型

我正在玩泛型,第一次清理一些重复的代码,我有改进的电话。

我能够制作一个通用的改装适配器,所以我的供应商不必每个都有一个独特的创造者,这真是太棒了,令人兴奋。

private fun <T> create(service: Class<T>, baseUrl: String): T { val retrofit = Retrofit.Builder() .client(client) .addConverterFactory(MoshiConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .baseUrl(baseUrl) .build() return retrofit.create(service) } 

现在我试图做一个通用的网络调用,但我无法弄清楚,并想知道如果这是甚至可能的改造如何工作?

我现在有5个服务,如下所有,不同的API。 每个人都有不同的终结点,但都接受1个参数,并返回他们的对象,每个API调用略有不同。

 interface ServiceA { @GET("v2/ticker") fun getCurrentTradingInfo(@Query("book") orderBook: String): Observable<CurrentTradingInfo> } 

所有的响应对象都实现了一个接口来规范响应数据,以便以后可以显示


 data class CurrentTradingInfo(val mid: String, val bid: String, val ask: String, val last_price: String, val low: String, val high: String, val volume: String, val timestamp: String) : normalizedData { override fun lastPrice(): String { return last_price } override fun timeStamp(): String { return timestamp } } 

目前,我有一个像下面的每个服务的网络调用

  val disposable = service.getCurrentTradingInfo(ticker.ticker) .observeOn(AndroidSchedulers.mainThread()) .repeatWhen { result -> result.delay(10, TimeUnit.SECONDS) } .retryWhen { error -> error.delay(10, TimeUnit.SECONDS) } .subscribeOn(Schedulers.io()) .subscribe({ result -> val tradingInfo = TradingInfo(result.lastPrice(), result.timeStamp()) networkDataUpdate.updateData(ticker, tradingInfo) callback.updateUi(ticker) }, { error -> error.printStackTrace() }) 

从我对泛型的一点知识,似乎我应该能够通过一个通用服务,并使用这个RxJava调用来处理许多不同的API端点。 我不知道如何访问每个服务的getCurrentTradingInfo方法,但是从我读的内容来看,我怀疑是否可以使用改进接口?

如果可能的话,我不一定会找到一个完整的答案(虽然解释会很好),但是我想知道在这个特定的情况下是否可以做到这一点? 如果不可能,我不想浪费时间。

从我的理解,似乎你正在寻找一个通用的接口与查询和结果的两个类型参数:

 interface GenService<Q, out D: normalizedData> { fun getCurrentTradingInfo(query: Q): Observable<D> } interface ServiceA: GenService<String, CurrentTradingInfo> { @GET("v2/ticker") override fun getCurrentTradingInfo(@Query("book") orderBook: String): Observable<CurrentTradingInfo> } 

创建observable你可能需要特定的数据,而事后你只是等待规范化的结果。

所以我能拿出下面这个比以前好多了。 我仍然无法弄清楚接口的方法,因此每个xxxRepository类中的每个API都有一点重复,但是少了很多。

 interface QuadrigaService { @GET("v2/ticker") fun getCurrentTradingInfo(@Query("book") query: String): Observable<CurrentTradingInfo> } 

 class QuadrigaRepository(private val service: QuadrigaService) : BaseExchangeRepository() { override fun feedType(): String { return CryptoPairs.QUADRIGA_BTC_CAD.exchange } override fun startFeed(tickers: List<CryptoPairs>, presenterCallback: NetworkCompletionCallback, networkDataUpdate: NetworkDataUpdate) { clearDisposables() tickers.forEach { ticker -> startFeed(service.getCurrentTradingInfo(ticker.ticker), ticker, presenterCallback, networkDataUpdate) } } } 

而基类使用泛型


 abstract class BaseExchangeRepository : Exchange { var disposables: CompositeDisposable = CompositeDisposable() fun clearDisposables() { if (disposables.size() != 0) { disposables.clear() } } fun <T> startFeed(observable: Observable<T>, ticker: CryptoPairs, presenterCallback: NetworkCompletionCallback, networkDataUpdate: NetworkDataUpdate) { val disposable = observable.observeOn(AndroidSchedulers.mainThread()) .repeatWhen { result -> result.delay(10, TimeUnit.SECONDS) } .subscribeOn(Schedulers.io()) .subscribe({ result -> result as NormalizedTickerData Log.d("Result", ticker.toString() + "last price is ${result.lastPrice()}") val tradingInfo = TradingInfo(result.lastPrice(), result.timeStamp()) networkDataUpdate.updateData(ticker, tradingInfo) presenterCallback.updateUi(ticker) }, { error -> error.printStackTrace() }) disposables.add(disposable) } override fun stopFeed() { disposables.clear() } }