http://square.github.io/retrofit/
기본적인 Retrofit 사용법( RxAndroid2 사용 )
rxjava를 사용하기 위해서는 CallAdapterFactory 에 RxJava2CallAdapter를 설정해야 rxjava 타입을 사용할 수 있다.
인터페이스를 정의
interface SampleRestfulService{
@Annotation
fun apiFuntion1 () : Observable<Model>
@Annotation
fun apiFuntion2 () : Single<Model>
@Annotation
fun apiFuntion3 () : Flowable<Modle>
}
Flowable은 RxJava2(RxAndroid2) 에서 대기열 버퍼에 대해 흐름제어 기능이 추가된 객체이다.
리액티브 프로그래밍에서 push로 무한정 밀어넣을 수 없는 상황이 발생하는데, 이경우 backpressure가 발생한다고 한다. 이 backpressure를 핸들링 하기 위해 필요한게 Flowable 이라고 생각하면 된다.
일반적인 rest api 정도에서야 Observable이면 충분한데, 대량의 api 호출과 각 처리간에 일정 시간이 필요한 경우 Flowable을 사용을 고려한다.
Retrofit은 GET,POST 를 위한 어노테이션들을 제공한다.
GET
REQUEST, URL 변환 처리
ex) users/user/repos?sort=sorting
주소치환 : 입력받을 변수앞에 @Path("파라미터명") 를 사용하면 해당 파라미터를 변수값으로 치환하게된다.
@GET("users/{user}/repos")
fun getTestFunction( @Path("user") user:String ) : Observable<ResponseModel>
쿼리문 치환 : @Query("name") 을 사용 :
@GET("users/{user}/repos")
fun getTestFunction( @Path("user") user:String, @Query("sort") sort:String ) : Observable<ResponseModel>
여러개의 퀴리의 경우 @QueryMap options:Map<String, String> 을 사용해 한번에 지정가능하다.
url을 입력받는 경우
@GET
fun getTestFunction( @Url user:String ) : Observable<ResponseModel>
POST
REQUEST BODY
@POST("users/new")
fun createUser( @Body user : UserModel )
FORM ENCODED
@FormUrlEncoded
@Post("user/edit")
fun updateUser( @Field("filed_name") first:String ) : Observable<ResponseModel>
@FieldMap
헤더
@Headers({
"Accept: application",
"User-Agent: "
})
build.gradle 설정
retrofit
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2::converter-gson:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.4.0'
ok http
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
rx android
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.1.14'
api 인터페이스
interface SampleApi{
@FormUrlEncoded
@POST("/post_url")
fun postTestFunction( @Field("field_name") filed : String ) : Observable<MyModel>
}
모델 정의
json 형태에 맞게 모델구성
ex) { "result": 0 , "value": 200, "desc":"GOOD", "data" : { "value1": true, "value2": 0 } }
json 키값과 변수명을 맞춰준다.
class MyModel{
val result:Integer = 0
val value:Integer = 200
desc:String = ""
val data:MyModelItem = MyModelItem()
}
아래처럼 변수명을 별도로 지정하려면 @SerializedName 사용
class MyModelItem( @SerializedName("value1") val myValue1 : Boolean,
@SerializedName("value2") val myValue2 : Integer)
배열의 경우 List 로 정의한다.
ex) { "result": 0 , "value": 200, "desc":"GOOD", "data" : [ { "value1": true, "value2": 0 }, { "value1": true, "value2": 0 }] }
class MyModel( val result:Integer, val value:Integer, desc:String, val data:List<MyModelItem>)
Retrofit adapter
// http클라이언트는 ok http를 사용하므로 해당 객체 생성
fun createOkHttpClient : OkHttpClient {
val interceptor = HttpLoggingInteceptor()
if( BuildConfig.DEBUG ) {
interceptor.level = HttpLoggingInterceptor.Level.Body
} else {
interceptor.level = HttpLoggingInterceptor.Level.NONE
}
// ok http client 생성
return OkHttpClient.Builder()
.addNetworkInterceptor(interceptor)
.sslSocketFactory( createSslSocketFactory(
.build()
}
fun createRetrofitApi : SampleApi
{
// retrofit 객체 생성
// rxjava2를 위한 call adapter factory와 json 변환을 위한 converter factory를 설정
Retrofit retrofit =
Retrofit.Builder()
.baseUrl( "http://api.sample.com/")
.client( createOkHttpClient() )
.addConverterFactory( GsonConverterFactory.create())
.addCallAdapterFactory( RxJava2CallAdapterFactory.create() )
.build()
// api 서비스 생성
SampleApi api = retrofit.create(SampleApi::class.java)
return api
}
MainActivity
lateinit var disposable: CompositeDisposable
lateinit var retrofitAdapter : RetrofitAdapter
override fun onCreate( savedInstanceState: Bundle?) {
super.onCreate( savedInstanceState )
setContentView( R.layout.activity_main )
// CompositeDisposable 객체에 Observable 객체들을 넣게 된다.
// 취소시 각각의 Observable을 처리하는게 아니라 CompositeDisposable을 정리하면 모든 처리가 취소된다.
disposable = CompositeDisposable()
retrofitAdapter = RetrofitAdapter()
SampleApi api = retrofitAdapter.createRetrofitApi()
disposable.add(
api.postTestFunction("test")
// result 를 판단해 필요한 데이터만 전달
// verify 관련 처리가 필요없는 경우 그냥 subscribe 에서 처리해도 됨.
.flatMap {
if( it.result == 0 ) {
Observable.just( it.data )
} else {
Observable.error( IllegalStateException("error") )
}
}
.observeOn( AndroidSchedulers.mainThread())
.subscribeOn( Schedulers.newThread())
.subscribe(
{ response: MyModelItem ->
// 응답처리
}, { error: Throwable ->
// exception
}
))
}
override fun onDestroy() {
// 제거
disposable.clear()
super.onDestroy()
}
'프로그래밍 > Android' 카테고리의 다른 글
[Android] gson , 복합적인 요소의 파싱 (0) | 2019.09.23 |
---|---|
[Android] gradle android 빌드 구성 (0) | 2019.09.17 |
[Android] ConstraintSet (0) | 2019.08.22 |
Gradle Kotlin, AndroidX 설정 (0) | 2019.08.17 |
[Android] androidX Camera (0) | 2019.07.15 |
[Android] Data Binding Library (0) | 2019.03.31 |
String 리소스에 html 태그 넣기 (0) | 2014.04.29 |
파일 변경 이벤트 (0) | 2014.04.01 |
[안드로이드TV] 개발 전 확인사항 (0) | 2014.02.17 |
GoogleTV 개발환경 설정 (0) | 2014.02.06 |