首页 文章

使用Kotlin的RxJava和Retrofit

提问于
浏览
1

如何在 Kotlin 中使用 RxJava and Retrofit 为api调用创建泛型类?

我的JAVA实现如下::

首先添加Gradle Dependency :(如果可用,更新到最新版本)

//用于改造

实现'com.squareup.retrofit2:retrofit:2.3.0'implementation'com.squareup.retrofit2:converter-gson:2.3.0'

// for interceptor implementation'com.squareup.okhttp3:logging-interceptor:3.9.0'

//对于BuildType :(如果你想要各种环境)

buildTypes {debug {buildConfigField“String”,“SERVER_URL”,'“DEV_URL”'debuggable true} release {buildConfigField“String”,“SERVER_URL”,'“LIVE_URL”'minifyEnabled false}}

//如果设置了环境使用set environment定义BASE_URL:

String BASE_URL = BuildConfig.SERVER_URL“url”;

================================================== =====
创建一个名为RestClient For Retrofit Builder的类:

public class RestClient {

private static RestClient instance;
private ApiConstant apiInterface;
private OkHttpClient.Builder okHttpClientBuilder;

public RestClient() {
    instance = this;
    okHttpClientBuilder = new OkHttpClient.Builder();
    okHttpClientBuilder.connectTimeout(60, TimeUnit.SECONDS);
    okHttpClientBuilder.writeTimeout(60, TimeUnit.SECONDS);
    okHttpClientBuilder.readTimeout(60, TimeUnit.SECONDS);


//for logs of api response in debug mode

    if (BuildConfig.DEBUG) {
        final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        okHttpClientBuilder.addInterceptor(interceptor);
    }
}

public static RestClient getInstance() {
    return instance;
}

public ApiConstant getApiInterface() {

    final Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
    retrofitBuilder.baseUrl(ApiConstant.BASE_URL);
    retrofitBuilder.client(okHttpClientBuilder.build());
    retrofitBuilder.addConverterFactory(GsonConverterFactory.create());

    Retrofit retrofit = retrofitBuilder.build();
    apiInterface = retrofit.create(ApiConstant.class);

    return apiInterface;
}

}

================================================== =====
ApiInterface :( api调用的接口)

public interface ApiInterface {

@POST("Urls Params")
Call<ModelClass> postValidateToken(@Body JSONObject body);

}

================================================== =====
创建名为RetrofitCallback的通用类,它处理Api响应并引发基本错误并向用户显示Toast消息:

public abstract class RetrofitCallback<T> implements Callback<T> {

private ProgressDialog progressDialog;
private Context context;
private boolean validateResponse = true;

public RetrofitCallback(Context c) {
    context = c;
}

public RetrofitCallback(Context c, ProgressDialog dialog) {
    progressDialog = dialog;
    context = c;
}

    public RetrofitCallback(Context context, ProgressDialog progressDialog, boolean validateResponse) {
    this.progressDialog = progressDialog;
    this.context = context;
    this.validateResponse = validateResponse;
}

public RetrofitCallback(Context context, boolean validateResponse) {
    this.context = context;
    this.validateResponse = validateResponse;
}

public abstract void onSuccess(T arg0);

@Override
public void onResponse(Call<T> call, Response<T> response) {

    if (!(((Activity) context).isFinishing()) && progressDialog != null && progressDialog.isShowing()) {
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    if (response.isSuccessful() && response.code() == 200) {
        onSuccess(response.body());
    } else {
        Toast.makeText(context, context.getString(R.string.something_wrong), Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onFailure(Call<T> call, Throwable error) {
    if (!validateResponse)
        return;

    String errorMsg;
    error.printStackTrace();
    if (error instanceof SocketTimeoutException) {
        errorMsg = context.getString(R.string.connection_timeout);
    } else if (error instanceof UnknownHostException) {
        errorMsg = context.getString(R.string.nointernet);
    } else if (error instanceof ConnectException) {
        errorMsg = context.getString(R.string.server_not_responding);
    } else if (error instanceof JSONException || error instanceof JsonSyntaxException) {
        errorMsg = context.getString(R.string.parse_error);
    } else if (error instanceof IOException) {
        errorMsg = error.getMessage();
    } else {
        errorMsg = context.getString(R.string.something_wrong);
    }

    if (progressDialog != null && progressDialog.isShowing()) {
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }
    Toast.makeText(context, errorMsg, Toast.LENGTH_SHORT).show();
}
}

================================================== =====
字符串:(string.xml)

有些不对劲 . 请稍后再试 . 没有互联网连接 . 请稍后再试 . 服务器没有响应 . 请稍后再试 . 连接超时无法解析来自服务器的响应

================================================== =====
实现(如何调用Activity或Fragment):

Call<User> userLoginCall = RestClient.getInstance().getApiInterface().LoginURL(Util.currentLanguage,
                Util.getLoginURL(getActivity(), email, LOGIN_GOOGLE, accID));
        userLoginCall.enqueue(new RetrofitCallback<User>(getActivity(), DialogUtils.showProgressDialog(getActivity())) {
            @Override
            public void onSuccess(User user) {

                //Your Response
            }
        });

1 回答

  • 0

    我使用ServiceGenerator类,以防我需要使用多个Retrofit Service接口 .

    object ServiceGenerator {
    
        const val APP_CODE = "APP_CODE"
    
        private val interceptor = HttpLoggingInterceptor()
            .setLevel(HttpLoggingInterceptor.Level.BODY)
    
        private val certificatePinner = CertificatePinner.Builder()
            .add(BuildConfig.HOSTNAME, BuildConfig.SHA1_HASH1)
            .add(BuildConfig.HOSTNAME, BuildConfig.SHA1_HASH2)
            .add(BuildConfig.HOSTNAME, BuildConfig.SHA1_HASH3)
            .add(BuildConfig.HOSTNAME, BuildConfig.SHA1_HASH4)
            .build()
    
        private val httpClient = OkHttpClient.Builder()
            .readTimeout(1, TimeUnit.MINUTES)
            .connectTimeout(1, TimeUnit.MINUTES)
            .addInterceptor(interceptor)
    
        private val builder = Retrofit.Builder()
            .baseUrl(BuildConfig.URL_ENDPOINT)
            .addCallAdapterFactory(
                        RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io())
            )
            .addConverterFactory(GsonConverterFactory.create())
    
        private var requestInterceptor: AppEventosRequestInterceptor? = null
    
        fun <S> createService(context: Context, serviceClass: Class<S>): S {
            if (BuildConfig.FLAVOR.equals("production")) {
                httpClient.certificatePinner(certificatePinner)
            }
            if (!httpClient.interceptors().contains(requestInterceptor)) {
                requestInterceptor = AppEventosRequestInterceptor(context)
                httpClient.addInterceptor(requestInterceptor!!)
            }
            builder.client(httpClient.build())
            val retrofit = builder.build()
            return retrofit.create(serviceClass)
        }
    }
    

    在我的情况下,我使我的服务能够返回Flowable响应,所以我可以观察它 .

    @GET("schedule")
    fun getSchedules(
            @Header("If-None-Match") etag: String
    ): Flowable<Response<ResponseBody>>
    

    然后,当我想进行我的http调用时,我首先初始化我的ServiceRx类

    private var mService: AppEventosServiceRx = ServiceGenerator.createService<AppEventosServiceRx>(applicationContext, AppEventosServiceRx::class.java)
    

    然后提出我的要求

    mService.getSchedules(mEtagManager.getEtag(EtagManager.ETAG_SCHEDULES))
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            { response ->
                if (response.code() != HttpURLConnection.HTTP_NOT_MODIFIED) {
                    if (response.body() != null) {
                        // Do your useful stuff here...
                    }
                } else {
                    // Check if not modified or any other HTTP Error
                }
            },
            { throwable -> 
                // Log your connectivity problems ...
            }
        ) {}
    

    这样,您的服务接口将为您提供一个Observer,Service生成器将使每个调用都通用,您可以观察它并处理响应 .

    希望能帮助到你!

相关问题