【问题标题】:How to get the request url in retrofit 2.0 with rxjava?如何使用 rxjava 在改造 2.0 中获取请求 url?
【发布时间】:2016-12-25 06:13:36
【问题描述】:

我正在尝试升级到 Retrofit 2.0 并在我的 android 项目中添加 RxJava。我正在进行 api 调用,并希望检索 url 并将其与 sqlite 中的响应数据作为缓存

Observable<MyResponseObject> apiCall(@Body body);

在 RxJava 调用中:

myRetrofitObject.apiCall(body).subscribe(new Subscriber<MyResponseObject>() {
    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onNext(MyResponseObject myResponseObject) {

    }
});

在 Retrofit 1.9 中,我们可以在成功回调中获取 url:

        @Override
        public void success(MyResponseObject object, Response response) {
            String url=response.getUrl();
            //save object data and url to sqlite
        }

你如何使用 RxJava 在 Retrofit 2.0 中做到这一点?

【问题讨论】:

  • 这方面有没有成功?我也在找这个

标签: android rx-java retrofit2


【解决方案1】:

更新:

再次阅读问题后:

如果您想访问原始响应,您需要将 API 接口定义为:

Observable<Response<MyResponseObject>> apiCall(@Body body);

代替:

Observable<MyResponseObject> apiCall(@Body body);

您可以使用以下方法获取 URL:

response.raw().request().url()

这里:
response 是来自 Retrofit 的响应
raw 是来自 OkHttp 的响应
request 是来自 OkHttp 的请求,其中包含 Url 作为 HttpUrl

【讨论】:

【解决方案2】:

使用rxjava 获取来自API 的响应,使用以下代码

创建类名API

public class Api {

private static final String BASE_URL="https://your_url";

private static Api instance;
private final IApiCall iApiCallInterface;

private Api() {
    Gson gson = new GsonBuilder().setLenient().create();
    final OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .build();
    Retrofit retrofit = new Retrofit.Builder().client(okHttpClient).baseUrl(BASE_URL)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(gson)).build();

    iApiCallInterface = retrofit.create(IApiCall.class);
}

public static Api start() {
    return instance = instance == null ? new Api() : instance;
}

public Observable<Example> getSendMoneyCountries() {
    return iApiCallInterface.getCategoryList();
}
}

Crete 接口名称IApiCall 在这里您可以提出所有其他API 请求

public interface IApiCall {
  //response in in json array
  @Headers("Content-Type: application/json")
  @GET("/json")
   Observable<Example> getCategoryList();
}

在你的MainActivity.java中写下代码

    private static Api api;
    api = Api.start();
    api.getSendMoneyCountries()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(new DisposableObserver<Example>() {
                @Override
                public void onNext(Example response) {
                    //Handle logic
                    try {
                        populateCountryList(response);
                    }catch (Exception e)
                    {
                        finish();
                        Toast.makeText(MainActivity.this,"Unable to send money",Toast.LENGTH_SHORT).show();
                        //MainActivity.showTimeoutDialog();
                        e.printStackTrace();
                    }
                }

                @Override
                public void onError(Throwable e) {
                    //Handle error
                    Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onComplete() {
                }
            });

【讨论】:

    【解决方案3】:

    好吧,我会告诉你我是怎么做的,用改造和 rxJava 处理 API。

    首先创建一个ApiClient.class

         public class ApiClient {
    
                private static final String BASE_URL = "https://travellingbook.app/api/v2/";
    
            public static final String IMAGE_BASE_URL = "";
    
            private static File httpCacheDirectory = new File(UpasargaApplication.getAppContext().getCacheDir(), "new_responses");
    
            private static int cacheSize = 10 * 1024 * 1024; // 10 MiB
    
            private static Cache cache = new Cache(httpCacheDirectory, cacheSize);
    
            private static Retrofit retrofit = null;
    
            public static Retrofit getClient() {
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
    
                HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
                if (BuildConfig.DEBUG) {
                    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    
                } else {
                    interceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
                }
    
                builder.interceptors().add(interceptor);
                builder.authenticator(new ApiTokenAuthenticator());
                OkHttpClient httpClient = builder
                        .readTimeout(15, TimeUnit.SECONDS)
                        .connectTimeout(15, TimeUnit.SECONDS)
                        .writeTimeout(15, TimeUnit.SECONDS)
                        .addInterceptor(new ApiInterceptor())
                        .build();
    
    
                Gson gson = new GsonBuilder()
                        .setLenient()
                        .create();
    
                RxJava2CallAdapterFactory rxJava2CallAdapterFactory = RxJava2CallAdapterFactory.createWithScheduler(Schedulers.computation());
    
    
                if (retrofit == null) {
                    retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
                            .addConverterFactory(GsonConverterFactory.create(gson))
                            .addCallAdapterFactory(rxJava2CallAdapterFactory)
                            .client(httpClient)
                            .build();
                }
                return retrofit;
            }
    
    

    现在,添加 Interceptor.classTokenAuthenticator.class(基于您的 REST API 架构。这是一个示例案例。)

    public class ApiInterceptor implements Interceptor {
    
        @NonNull
        @Override
        public Response intercept(@NonNull Chain chain) throws IOException {
            Request originalRequest = chain.request();
            if (Utilities.getLoginResponse() == null || TextUtils.isEmpty(Utilities.getLoginUserToken())) {
                return chain.proceed(originalRequest);
            }
    
    
            Request request = originalRequest.newBuilder()
                    .addHeader("Authorization", Utilities.getLoginUserToken())
                    .addHeader("Accept", "Accept: application/x.school.v1+json")
                    .header("Cache-Control", String.format("max-age=%d", 50000))
                    .build();
            return chain.proceed(request);
        }
    }
    

    现在创建一个 LoginApiService.java 接口。

    public interface LoginApiService {
    
        @POST("login")
        @FormUrlEncoded
        Observable<Login> login(
                @Field("email") String email,
                @Field("password") String password
        );
    
    
        @POST("forgot_password")
        @FormUrlEncoded
        Observable<ServerResponse> forgotPassword(
                @Field("email") String email
        );
    
    
    }
    

    现在实现 LoginPresenter.java 处理逻辑。

    public class LoginPresenter {
    
        private static final String TAG = LoginPresenter.class.getSimpleName();
    
        private WeakReference<View> view;
    
        CompositeDisposable compositeDisposable;
    
        public LoginPresenter(View view) {
            this.view = new WeakReference<>(view);
            this.compositeDisposable = new CompositeDisposable();
    
        }
    
        private View getView() throws NullPointerException {
            if (view != null)
                return view.get();
            else
                throw new NullPointerException("View is unavailable");
        }
    
    
        public void userLogin(String email, String password) {
    
    
            Observable<Login> loginObservable = ApiClient.getClient().create(LoginApiService.class)
                    .login(email, password)
                    .subscribeOn(Schedulers.io())
                    .retry(AppConstants.API_RETRY_COUNT)
                    .observeOn(AndroidSchedulers.mainThread());
    
    
            DisposableObserver<Login> loginDisposableObserver = new DisposableObserver<Login>() {
    
                @Override
                public void onNext(Login login) {
    
                    if (getView() != null && login != null) {
                        getView().onUserLoginSuccess(login);
                    }
    
                }
    
                @Override
                public void onError(Throwable e) {
    
                    try {
    
                        getView().onFailure(UtilitiesFunctions.handleApiError(e));
    
                    } catch (Exception ignored) {
    
                    }
    
                }
    
                @Override
                public void onComplete() {
    
                }
            };
    
            compositeDisposable.add(loginObservable.subscribeWith(loginDisposableObserver));
    
        }
    
    
        public void forgotPassword(String email) {
    
            Observable<ServerResponse> loginObservable = ApiClient.getClient().create(LoginApiService.class)
                    .forgotPassword(email)
                    .subscribeOn(Schedulers.io())
                    .retry(AppConstants.API_RETRY_COUNT)
                    .observeOn(AndroidSchedulers.mainThread());
    
            DisposableObserver<ServerResponse> loginDisposableObserver = new DisposableObserver<ServerResponse>() {
    
                @Override
                public void onNext(ServerResponse serverResponse) {
    
                    Log.e("onNext: ", new GsonBuilder().create().toJson(serverResponse));
    
                    if (getView() != null && serverResponse != null) {
                        getView().onForgotPasswordSuccess(serverResponse);
                    }
    
                }
    
                @Override
                public void onError(Throwable e) {
    
                    ServerResponse serverResponse = new GsonBuilder().create().fromJson(e.getMessage(), ServerResponse.class);
    
                    if (serverResponse != null) {
    
                        getView().onFailure(serverResponse.getMessage());
                    } else {
                        try {
    
                            getView().onFailure(UtilitiesFunctions.handleApiError(e));
    
                        } catch (Exception ignored) {
    
                        }
                    }
    
    
                }
    
                @Override
                public void onComplete() {
    
                }
            };
    
            compositeDisposable.add(loginObservable.subscribeWith(loginDisposableObserver));
    
        }
    
    
        public void onActivityStop() {
    
            if (getView() != null) {
                compositeDisposable.clear();
    
            }
        }
    
    
        public interface View {
    
            void onUserLoginSuccess(Login login);
    
            void onForgotPasswordSuccess(ServerResponse serverResponse);
    
            void onFailure(String message);
    
        }
    

    最后,我们可以从Activity/Fragment访问LoginPresenter.class

    public class LoginActivity extends AppActivity implements LoginPresenter.View {
    
    private Button btnLogin;
        private LoginPresenter loginPresenter;
    
     @Override
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_login);
        enter code here
            loginPresenter = new LoginPresenter(this);
    
        }
     @Override
        public void onUserLoginSuccess(Login login) {
            if (login != null) {
                Utilities.saveLoginResponse(login);
                Utilities.saveLoginResponse(login);
                hideProgressBarWork();
                if (login.getStatus()) {
                    Utilities.setUserLoginCompleted();
                } else {
                    ShowToastWithMessage("Your account has been disabled.");
                }
            }
        }
    
        @Override
        public void onForgotPasswordSuccess(ServerResponse serverResponse) {
    
        }
    
        @Override
        public void onFailure(String message) {
            hideProgressBarWork();
            ShowToastWithMessage(message);
        }
    
    }
    

    欢迎提出疑问和建议。

    【讨论】:

    【解决方案4】:

    只需调用此方法

    @Override
    public void onFailure(Call<List<loginModel>> call, Throwable t) {
            Log.v("rese",call.request().url().toString());
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2020-06-20
      • 1970-01-01
      • 2017-12-17
      • 2023-03-17
      • 1970-01-01
      • 2021-06-04
      • 1970-01-01
      • 2020-01-29
      • 1970-01-01
      相关资源
      最近更新 更多