우선 HTTP 통신을 위한 많은 라이브러리들이 있지만 Retrofit을 사용하는 이유와 장점에 대해 간략히 설명하고
사용 방법에 대해 알아보도록 합시다.
Retrofit란?
앱을 만들다보면 통신(HTTP) 이 필요한 기능이 대다수 필요하며 통신 기능을 쉽고 간결하게 구현가능하게 해주는 라이브러리입니다.
1. 장점
- 간결한 코드로 통신 기능 지원
- okhttp를 기반으로 사용하여 빠른 속도 지원
- 어노테이션으로 메서드를 정의함으로써 직관적인 코드 구현과 유지보수에 용이
- 통신 시 스레드 구현 필요 X (asyncTask 등..)
2. 단점
- asyncTask, volley 보다 자유도가 낮음
Retrofit 사용방법
1. 라이브러리 사용을 위한 종속성 추가
build.gradle (Module)
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
2. 인터넷 사용을 위한 권한 설정
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
3. http 접속 허용을 위한 권한 설정
AndroidManafest.xml (application) 태그 안
<application
android:icon="@mipmap/ic_launcher"
android:allowBackup="true"
android:usesCleartextTraffic="true" <-- 이것
..
4. 데이터를 담기 위한 model class 생성
- 서버에서 JSON 형태로 받는 데이터가 아래와 같으므로 해당 내용으로 model 생성
"data": [
{
"서비스ID": "string",
"지원유형": "string",
"서비스명": "string",
"서비스목적": "string",
"지원대상": "string",
"선정기준": "string",
"지원내용": "string",
"신청방법": "string",
"신청기한": "string",
"상세조회URL": "string",
"소관기관코드": "string",
"소관기관명": "string",
"부서명": "string",
"조회수": 0
}
]
ServiceModel.java (코드가 길어 접이식 글로 대체)
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ServiceModel {
@SerializedName("서비스ID")
@Expose
private String serviceId;
@SerializedName("지원유형")
@Expose
private String supportType;
@SerializedName("서비스명")
@Expose
private String serviceName;
@SerializedName("서비스목적")
@Expose
private String servicePurpose;
@SerializedName("지원대상")
@Expose
private String supportTarget;
@SerializedName("선정기준")
@Expose
private String selectionCriteria;
@SerializedName("지원내용")
@Expose
private String supportContents;
@SerializedName("신청방법")
@Expose
private String applyHow;
@SerializedName("신청기한")
@Expose
private String applyDeadline;
@SerializedName("상세조회URL")
@Expose
private String detailedUrl;
@SerializedName("소관기관코드")
@Expose
private String agencyCode;
@SerializedName("소관기관명")
@Expose
private String agencyName;
@SerializedName("부서명")
@Expose
private String departmentName;
@SerializedName("조회수")
@Expose
private int views;
public String getServiceId() {
return serviceId;
}
public void setServiceId(String serviceId) {
this.serviceId = serviceId;
}
public String getSupportType() {
return supportType;
}
public void setSupportType(String supportType) {
this.supportType = supportType;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getServicePurpose() {
return servicePurpose;
}
public void setServicePurpose(String servicePurpose) {
this.servicePurpose = servicePurpose;
}
public String getSupportTarget() {
return supportTarget;
}
public void setSupportTarget(String supportTarget) {
this.supportTarget = supportTarget;
}
public String getSelectionCriteria() {
return selectionCriteria;
}
public void setSelectionCriteria(String selectionCriteria) {
this.selectionCriteria = selectionCriteria;
}
public String getSupportContents() {
return supportContents;
}
public void setSupportContents(String supportContents) {
this.supportContents = supportContents;
}
public String getApplyHow() {
return applyHow;
}
public void setApplyHow(String applyHow) {
this.applyHow = applyHow;
}
public String getApplyDeadline() {
return applyDeadline;
}
public void setApplyDeadline(String applyDeadline) {
this.applyDeadline = applyDeadline;
}
public String getDetailedUrl() {
return detailedUrl;
}
public void setDetailedUrl(String detailedUrl) {
this.detailedUrl = detailedUrl;
}
public String getAgencyCode() {
return agencyCode;
}
public void setAgencyCode(String agencyCode) {
this.agencyCode = agencyCode;
}
public String getAgencyName() {
return agencyName;
}
public void setAgencyName(String agencyName) {
this.agencyName = agencyName;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public int getViews() {
return views;
}
public void setViews(int views) {
this.views = views;
}
@Override
public String toString() {
return "ServiceModel{" +
"serviceId='" + serviceId + '\'' +
", supportType='" + supportType + '\'' +
", serviceName='" + serviceName + '\'' +
", servicePurpose='" + servicePurpose + '\'' +
", supportTarget='" + supportTarget + '\'' +
", selectionCriteria='" + selectionCriteria + '\'' +
", supportContents='" + supportContents + '\'' +
", applyHow='" + applyHow + '\'' +
", applyDeadline='" + applyDeadline + '\'' +
", detailedUrl='" + detailedUrl + '\'' +
", agencyCode='" + agencyCode + '\'' +
", agencyName='" + agencyName + '\'' +
", departmentName='" + departmentName + '\'' +
", views=" + views +
'}';
}
}
위 작성한 ServiceModel의 상위 Model class 생성
- 객체 값에 위에 작성한 serviceModel 이 포함됨을 알 수 있습니다.
코드가 길어 접이식 글로 대체.
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
public class ServiceApiModel {
@SerializedName("page")
@Expose
private int page;
@SerializedName("perPage")
@Expose
private int perPage;
@SerializedName("totalCount")
@Expose
private int totalCount;
@SerializedName("currentCount")
@Expose
private int currentCount;
@SerializedName("matchCount")
@Expose
private int matchCount;
@SerializedName("data")
@Expose
private ArrayList<ServiceModel> data;
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getPerPage() {
return perPage;
}
public void setPerPage(int perPage) {
this.perPage = perPage;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getCurrentCount() {
return currentCount;
}
public void setCurrentCount(int currentCount) {
this.currentCount = currentCount;
}
public int getMatchCount() {
return matchCount;
}
public void setMatchCount(int matchCount) {
this.matchCount = matchCount;
}
public ArrayList<ServiceModel> getData() {
return data;
}
public void setData(ArrayList<ServiceModel> data) {
this.data = data;
}
@Override
public String toString() {
return "ServiceApiModel{" +
"page=" + page +
", perPage=" + perPage +
", totalCount=" + totalCount +
", currentCount=" + currentCount +
", matchCount=" + matchCount +
", data=" + data +
'}';
}
}
5. Retrofit Interface 생성
RetrofitInterface.java
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;
public interface RetrofitInterface {
@GET("{path}")
Call<ServiceModel> getServiceList(
@Path ("path") String path,
@Query("page") String page,
@Query("perPage") String perPage,
@Query("serviceKey") String serviceKey
);
@GET("{path}")
Call<ServiceModel> getTest(
@Path ("path") String path,
@Query("serviceKey") String serviceKey
);
}
Call<ServiceModel> | 앞서 작성한 model class 이름 |
@GET | HTTP 통신 시 GET 방식을 사용할 것이고, http://BASE_URL/{path} 의 뒤에 end point url 을 명시해주기 위해 작성. (end point url 은 아래 MainActivity 에서 추가 설명 |
@Path | 위 GET 에 들어가 String 문자 |
@Query | http://BASE_URL/aaa?page=1 과 같이 URL 뒤 파라미터명 및 string 값 MainActivity에서 값 세팅해서 넘겨줌. |
6. 통신 호출 (MainActivity에서 테스트)
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String BASE_URL = "사용할 BASE_URL";
private static final String SERVICE_KEY = "발급 받은 키값";
public static String TAG = "retrofit_test";
private static String buf = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.text1);
retrofit2.Retrofit retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL) // baseUrl 등록
.addConverterFactory(GsonConverterFactory.create()) // Gson 변환기 등록
.build();
RetrofitInterface service = retrofit.create(RetrofitInterface.class); // 레트로핏 인터페이스 객체 구현
Call<ServiceApiModel> call = service.getServiceList("API end point url", "1", "10", SERVICE_KEY);
call.enqueue(new Callback<ServiceApiModel>() {
@Override
public void onResponse(Call<ServiceApiModel> call, Response<ServiceApiModel> response) {
if(response.isSuccessful()){
Log.d(TAG, "연결 주소 확인 : " + response.raw().request().url().url());
Log.d(TAG, "통신여부 코드 : " + response.code());
ServiceApiModel sm = response.body();
ArrayList<ServiceModel> arr = sm.getData();
Log.d(TAG, "데이터 정보: " + sm.toString());
for(ServiceModel serviceModel : arr){
buf = buf + serviceModel.getServiceName() + "\n";
}
tv.setText(buf);
}
else{
// 실패
Log.e(TAG, "실패 코드 확인 : " + response.code());
Log.e(TAG, "연결 주소 확인 : " + response.raw().request().url().url());
}
}
@Override
public void onFailure(Call<ServiceApiModel> call, Throwable t) {
// 통신 실패
Log.e(TAG, "onFailure: " + t.getMessage());
}
});
}
}
MainActivity의 내용은 주석 및 로그 내용을 확인해 보면 통신에 대한 내용들을 파악할 수 있습니다.
Retrofit을 통한 공공데이터 정보
이로써 중요 코드 작업은 끝났고 해당 앱을 실행시키면 아래와 같이 공공데이터의 정보를 가져올 수 있습니다.
다음 과정으로는 해당 정보를 가지고 Recyclerview를 통해 리스트로 출력하는 방법은 아래 내용을 참고하세요.
2022.09.29 - [IT/Android] - Android Retrofit2 데이터 RecyclerView 적용하기
'IT > Android' 카테고리의 다른 글
Android RecyclerView Click Event 적용하기 (클릭 이벤트) (1) | 2022.09.29 |
---|---|
Android Retrofit2 데이터 RecyclerView 적용하기 (0) | 2022.09.29 |
Android 좌우 드래그(drag)해서 화면 전환 기능 만들기 (0) | 2022.09.08 |
Android Fragment 전환 애니메이션 효과 적용하기 (0) | 2022.09.04 |
Android 투명 Activity (Layout) 배경 만드는 방법. (0) | 2022.08.31 |
댓글