如何使用rxjava在retrofit 2.0中获取请求URL?

时间:2016-08-18 10:40:27

标签: android rx-java retrofit2

我尝试升级到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中,我们可以获得成功回调中的网址:

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

如何使用RxJava进行Retrofit 2.0?

4 个答案:

答案 0 :(得分:30)

更新

再次阅读问题后:

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

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

而不是:

Observable<MyResponseObject> apiCall(@Body body);

您可以使用以下网址获取网址:

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

这里:
response是Retrofit的回复 raw是OkHttp的回复 request是来自OkHttp的请求,其中包含Url HttpUrl

答案 1 :(得分:0)

使用以下代码从api获得来自rxjava的响应

创建类名称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

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

主要活动

    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() {
                }
            });

答案 2 :(得分:0)

好吧,我将向您展示如何做,使用翻新和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.class TokenAuthenticator.class (基于您的其余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);

    }

最后,我们可以从“活动/片段”中访问 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);
    }

}

欢迎提出疑问和建议。

答案 3 :(得分:0)

只需调用此方法

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