2017-11-20 1 views
3

를 사용 RxJava 및 개조?어떻게 <strong>RxJava 및 <strong>코 틀린</strong>에</strong> 환장을 사용하여 호출 API에 대한 제네릭 클래스를 만드는 코 틀린

내 자바 구현 먼저 추가 Gradle을 종속성에서 ::

과 같습니다

// 개조를위한 (사용 가능한 경우 최신 버전으로 업데이트)

구현 'com.squareup.retrofit2 : 갱신 : 2.3.0 '

구현'com.squareup.retrofit2 : 컨버터 GSON : 2.3.0 '

인터셉터 구현을위한 16,

// 'com.squareup.okhttp3 : 로깅 인터셉터 : 3.9.0'

// BuildType 경우 : (다양한 환경에 대해 원하는 경우)

buildTypes { 디버그 { buildConfigField "문자열", "server_url에", ' "DEV_URL"' 디버깅 진정한 } 출시 { buildConfigField "문자열", "server_url에", ' "LIVE_URL"' 거짓 minifyEnabled,536,} }

// 환경 설정 환경에서 사용 BASE_URL 정의 설정되어있는 경우 :

문자열 BASE_URL는 = BuildConfig.SERVER_URL + "URL을";

========================== ===========
이 개조 빌더 위해 RESTClient라는 클래스 만들기 :

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); 

} 

===================================== ========
API 응답을 처리하고 사용자에게 기본 오류 및 쇼 토스트 메시지를 예외 RetrofitCallback라는 일반 클래스 만들기 :

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)

문제가 생겼습니다. 나중에 다시 시도 해주십시오. 인터넷에 연결되어 있지 않습니다. 나중에 다시 시도 해주십시오. 서버가 응답하지 않습니다. 나중에 다시 시도 해주십시오. 연결 시간 제한

서버

에서 응답을 구문 분석 할 수 없습니다 ==================================== ===================
구현 (활동이나 조각에서 호출하는 방법) : 단지의 경우

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 
      } 
     }); 
+0

'제네릭 클래스'란 무엇을 의미하며 지금까지 어떤 시도를 했습니까? – FWeigl

+0

나는 kotlin을 처음 사용하므로 RxJava를 사용하여 API 호출을 단순화하고 싶습니다. 오류를 직접 처리하고 onSuccess를 직접 제공하는 일반 클래스를 작성하면 ... –

답변

0

가 나는 ServiceGenerator 클래스를 사용 나는 필요 하나 이상의 개조 서비스 인터페이스를 사용하십시오.

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 응답으로 되돌릴 수있게 만들었습니다. 내 요청

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 ... 
     } 
    ) {} 

이 방법을 내 HTTP 호출을 할 때

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

그럼, 내가 먼저 내 ServiceRx 클래스

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

를 초기화 그리고 수 있도록, 귀하의 서비스 인터페이스를 제공합니다 당신은 옵서버 (Observer)입니다. 서비스 생성기는 모든 호출에 공통적으로 적용되며 사용자는이를 관찰하고 응답을 처리 할 수 ​​있습니다.

희망이 있습니다.