我使用Single.zip()和Function 5将5个API调用合并为一个:
private fun loadProfileAndBalances() {
registerSubscription(
Single.zip<AvailableFundsResult, IncomingFundsResult, TotalEarnedResult, TotalDonatedResult, ProfileResult, Unit>(
Interactors.api.paymentsApiClient.getAvailableFunds()
.map<AvailableFundsResult> {
Timber.d("Available Result [${it.amount}]") <------ DollarAmount object with null amount
AvailableFundsResult.Amount(it) }
.onErrorReturn { AvailableFundsResult.Error(it) }
.scheduleIOUI(),
Interactors.api.paymentsApiClient.getIncomingFunds()
.map<IncomingFundsResult> { IncomingFundsResult.Amount(it) }
.onErrorReturn { IncomingFundsResult.Error(it) }
.scheduleIOUI(),
Interactors.api.paymentsApiClient.getTotalEarned()
.map<TotalEarnedResult> { TotalEarnedResult.Amount(it) }
.onErrorReturn { TotalEarnedResult.Error(it) }
.scheduleIOUI(),
Interactors.api.paymentsApiClient.getTotalDonated()
.map<TotalDonatedResult> { TotalDonatedResult.Amount(it) }
.onErrorReturn { TotalDonatedResult.Error(it) }
.scheduleIOUI(),
Interactors.profileManager.getNotCachedProfile()
.map<ProfileResult> { ProfileResult.Profile(it) }
.onErrorReturn { ProfileResult.Error(it) }
.scheduleIOUI(),
Function5 { availableFunds: AvailableFundsResult, incomingFunds: IncomingFundsResult, totalEarned: TotalEarnedResult, totalDonated: TotalDonatedResult, profileResult: ProfileResult ->
availableTotal = when (availableFunds) {
is AvailableFundsResult.Amount ->
availableFunds.result.amount
is AvailableFundsResult.Error -> {
Timber.w(availableFunds.throwable, "Error while fetching sponsorships")
"0.00"
}
}
incomingTotal = when (incomingFunds) {
is IncomingFundsResult.Amount -> incomingFunds.result.amount
is IncomingFundsResult.Error -> {
Toast.makeText(activity, getString(R.string.payout_main_error_loading_totals), Toast.LENGTH_SHORT).show()
"0.00"
}
}
earnedTotal = when (totalEarned) {
is TotalEarnedResult.Amount -> totalEarned.result.amount
is TotalEarnedResult.Error -> {
Toast.makeText(activity, getString(R.string.payout_main_error_loading_totals), Toast.LENGTH_SHORT).show()
"0.00"
}
}
donatedTotal = when (totalDonated) {
is TotalDonatedResult.Amount -> totalDonated.result.amount
is TotalDonatedResult.Error -> {
Toast.makeText(activity, getString(R.string.payout_main_error_loading_totals), Toast.LENGTH_SHORT).show()
"0.00"
}
}
onboardingComplete = when (profileResult) {
is ProfileResult.Profile ->
profileResult.result.isOnboardingCompleted
is ProfileResult.Error -> {
Timber.e(profileResult.throwable, "Error fetching profile")
true
}
}
}
).ignoreElement()
.subscribe(::updateViews) {
it.printStackTrace()
availableTotal = ""
incomingTotal = ""
earnedTotal = ""
donatedTotal = ""
onboardingComplete= false
vWalletRefresher.isRefreshing = false
internetConnectionError(it)
})
}这些API调用中的每一个都成功地使用了代码200。使用Interactors.api.paymentsApiClient.getAvailableFunds()进行的调用将返回{"amount":264.69},并将其解析为此类的对象:
internal data class DollarAmount(@SerializedName("amount") val amount: String)重复引用的paymentsApiClient是这样构建的:
private fun createNewPaymentsClient(authRefreshClient: AuthRefreshClient,
preferencesInteractor: PreferencesInteractor): PaymentsApiClient {
val loggingInterceptor = run {
val httpLoggingInterceptor = HttpLoggingInterceptor()
httpLoggingInterceptor.apply {
httpLoggingInterceptor.level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
}
}
val okHttpClient = createHttpClientBuilder()
.addInterceptor(createSessionRequestInterceptor())
.addInterceptor(createUserAgentInterceptor(context))
.addInterceptor(loggingInterceptor)
.authenticator(RefreshUserAuthenticator(authRefreshClient, preferencesInteractor,
UnauthorizedNavigator(SDKInternal.appContext, Interactors.preferences)))
.build()
val gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().setLenient().create()
return Retrofit.Builder()
.client(okHttpClient)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl(Interactors.apiEndpoint)
.build()
.create(PaymentsApiClient::class.java)
}尽管API调用成功,但在Single.zip中打印的用于通过Interactors.api.paymentsApiClient.getAvailableFunds()成功检索DollarAmount的日志语句显示其数量为null,而不是264.69。我的解析出了什么问题,导致它为空?
编辑:正如有人注意到的,我将结果包装在另一组类中:
private sealed class AvailableFundsResult {
data class Error(val throwable: Throwable) : AvailableFundsResult()
data class Amount(val result: DollarAmount) : AvailableFundsResult()
}
private sealed class IncomingFundsResult {
data class Error(val throwable: Throwable) : IncomingFundsResult()
data class Amount(val result: DollarAmount) : IncomingFundsResult()
}
private sealed class TotalEarnedResult {
data class Error(val throwable: Throwable) : TotalEarnedResult()
data class Amount(val result: DollarAmount) : TotalEarnedResult()
}
private sealed class TotalDonatedResult {
data class Error(val throwable: Throwable) : TotalDonatedResult()
data class Amount(val result: DollarAmount) : TotalDonatedResult()
}
private sealed class ProfileResult {
data class Error(val throwable: Throwable) : ProfileResult()
data class Profile(val result: InfluencerProfileDto) : ProfileResult()
}我不认为这是相关的,因为在我还没有吐出这些包装器类的实例之前,数量就返回了null。
编辑2:从第五次API调用返回的类:
@JsonClass(generateAdapter = true)
internal data class InfluencerProfileDto(
@Json(name = "id") val id: String,
@Json(name = "emailAddress") val email: String?,
@Json(name = "phoneNumber") val phoneNumber: PhoneNumberDto?,
@Json(name = "isPhoneNumberVerified") val isPhoneNumberVerified: Boolean,
@Json(name = "isEmailVerified") val isEmailVerified: Boolean,
@Json(name = "notificationTimePreference") val notificationTimePreference: String,
@Json(name = "isInstagramConnected") val isInstagramConnected: Boolean,
@Json(name = "isFacebookConnected") val isFacebookConnected: Boolean,
@Json(name = "isTwitterConnected") val isTwitterConnected: Boolean,
@Json(name = "currencyIsoSymbol") val currencyIsoSymbol: String,
@Json(name = "currencySymbol") val currency: String,
@Json(name = "birthDate") val birthDate: Date?,
@Json(name = "name") val name: String?,
@Json(name = "profilePictureUri") val avatarUrl: String?,
@Json(name = "gender") val gender: Gender?)
{
val isOnboardingCompleted: Boolean
get() = gender!= Gender.UNKNOWN && birthDate!= null && !!notificationTimePreference.isNullOrEmpty() && isPhoneNumberVerified && !email.isNullOrEmpty()
}发布于 2020-10-13 06:24:05
我的方法是java。
首先,我们需要两个你可能不会在你的项目中使用的库。
gson =>,用于从字符串传递对象,反之亦然
字符串http请求的volley =>
请谷歌他们的官方github页面并安装最新版本
然后,我们将创建一个通用的结果对象来承载结果。
class Result {
boolean error; // this field can be used by the api to tell if there was some error while processing the request
String message; // here api can give you some extra message if there was some error
String result; // here you get the result. you can make it a map as well if you want to receive an object and later parse to a unique object class
}这是一个可用于HTTP请求的函数
public static Single<Result> getHttpResult(String api, Map<Stirng, String> params){
return Single.create(emitter -> {
StringRequest stringRequest = new StringRequest(Request.Method.POST, api, response -> {
Log.i("RESPONSE :", response);
try {
Result result = new Gson().fromJson(response, Result.java);
emitter.onSuccess(result);
} catch (JSONException e) {
emitter.onError(e);
}
}, emitter::onError) {
@Override
protected Map<String, String> getParams() {
return params;
}
};
stringRequest.setRetryPolicy(new DefaultRetryPolicy(0, 0, 0));
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.add(stringRequest);
});
}这就是你可以一次获得多个结果的方法,我建议你也检查互联网连接,如果用户有足够的互联网,那么只进行并行请求,否则就不会产生好的用户体验
...
List<Single<Result>> tasks = new ArrayList();
tasks.add(getHttpResult("https://..."), /**here you can add a map with params that your api might require for auth and other purposes**/);
tasks.add(...);
tasks.add(...);
tasks.add(...);
Single.zip(tasks, objects -> {
List<Result> results = new ArrayList();
for(Object object : objects){
results.add((Result)object)
}
return results;
}).subscribe(results -> {
// this result object have all the results of http requests
// for distinguising results from each other you can create a field on the result object
});
...希望我的方法对您有所帮助;)
https://stackoverflow.com/questions/64325078
复制相似问题