그동안은 Retrofit을 사용할 일이 전혀 없었는데, 사용할 일이 있어서 관련 자료를 찾아서 테스트하고 적어둔다.
예제를 이해하는데 참 어려웠다. 그래서 유투브 동영상도 보고 이해하고 따라해보고 동작되는 걸 확인한 후에야 로직이 이해가 되었다.
구글에서 추천하는 Volley 라이브러리보다 속도가 빠르다고 검색결과가 나온다.
Retrofit 은 안전한 타입 방식의 HTTP 클라이언트로서 Android 와 Java 애플리케이션을 위한 라이브러리이다.
Json converter : JSON 타입의 응답결과를 객체로 매핑(변환)해주는 Converter
https://square.github.io/retrofit/ 를 참조한다. 그런데 설명만으로는 이해하기 어렵더라.
이해를 돕기 위해서 그림으로 설명한다.
Interface 생성
이 부분에는 GET/POST/PUT/DELETE 등 필요한 모든 함수를 선언하는 부분이다.
Call <> 사이에는 서버의 Json 형태에 따라 클래스 파일을 만들어서 넣어주면 된다.
/**
* GET 방식, URL/getphoto.php/{code} 호출.
* Data Type의 여러 개의 JSON을 통신을 통해 받음.
* 주소값이 "http://www.abc.com/getphoto.php?code=1" 이 됨.
* @param code 요청에 필요한 code
* @return 다수의 Data 객체를 JSON 형태로 반환.
*/
@GET("/getphoto.php")
Call<Data> getData(@Query("code") String code);
앱 build.gradle 설정
compileOptions { // 이거 안해주면 에러가 나오더라. sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } dependencies { implementation 'com.google.android.material:material:1.0.0' implementation 'com.squareup.retrofit2:retrofit:2.7.0' implementation 'com.squareup.retrofit2:converter-gson:2.7.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.4.0' } |
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
android:usesCleartextTraffic="true"
activity_login.xml
구글에서 Meterial Design 예제를 검색하면 나온다. 그걸 참조해서 하면 된다.
Resource 관련 파일을 첨부한다.
LoginActivity.java
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class LoginActivity extends AppCompatActivity implements View.OnClickListener { Context context; EditText etId; EditText etPw; String userID; String userPW; String uID; // 스마트 기기의 대체 고유값 LoginAPI mloginService; PermissionListener permissionlistener = new PermissionListener() { @Override public void onPermissionGranted() { initView(); } @Override public void onPermissionDenied(ArrayList<String> deniedPermissions) { Toast.makeText(LoginActivity.this, "권한 허용을 하지 않으면 서비스를 이용할 수 없습니다.", Toast.LENGTH_SHORT).show(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); context = LoginActivity.this; checkPermissions(); } private void checkPermissions() { if (Build.VERSION.SDK_INT >= 23) { // 마시멜로(안드로이드 6.0) 이상 권한 체크 TedPermission.with(context) .setPermissionListener(permissionlistener) .setRationaleMessage("앱을 이용하기 위해서는 접근 권한이 필요합니다") .setDeniedMessage("앱에서 요구하는 권한설정이 필요합니다...\n [설정] > [권한] 에서 사용으로 활성화해주세요.") .setPermissions(new String[]{ android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.READ_CALL_LOG, // 안드로이드 9.0 에서는 이것도 추가하라고 되어 있음. android.Manifest.permission.CALL_PHONE, // 전화걸기 및 관리 android.Manifest.permission.ACCESS_FINE_LOCATION }) .check(); } else { initView(); } } private void initView() { etId = findViewById(R.id.et_id); etPw = findViewById(R.id.et_pw); Button btn_login = findViewById(R.id.btn_login); Retrofit retrofit = new Retrofit.Builder() .baseUrl(Value.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(createOkHttpClient()) .build(); mloginService = retrofit.create(LoginAPI.class); } @Override public void onClick(View v) { userID = etId.getText().toString().trim(); userPW = etPw.getText().toString().trim(); uID = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID); mloginService.Login(userID, userPW, uID) .enqueue(new Callback<LoginResult>() { @Override public void onResponse(Call<LoginResult> call, Response<LoginResult> response) { // 네트워크 통신 성공 LoginResult result = response.body(); if(result.getResult().contains("success")){ Intent intent = new Intent(LoginActivity.this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY); startActivity(intent); finish(); } else { showAlert(result.getResult(),result.getMessage()); } } @Override public void onFailure(Call<LoginResult> call, Throwable t) { // 네트워크 통신 실패 } }); } private OkHttpClient createOkHttpClient() { // 네트워크 통신 로그(서버로 보내는 파라미터 및 받는 파라미터) 보기 OkHttpClient.Builder builder = new OkHttpClient.Builder(); HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); builder.addInterceptor(interceptor); return builder.build(); } public void showAlert(String title, String message) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(title); builder.setMessage(message) .setCancelable(false) .setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); } }); AlertDialog alert = builder.create(); alert.show(); } } |
public interface LoginAPI { // 서버에 호출할 메소드를 선언하는 인터페이스 // POST 방식으로 데이터를 주고 받을 때 넘기는 변수는 Field 라고 해야 한다. @FormUrlEncoded @POST(Value.URL_LOGIN) Call<LoginResult> Login( @Field("userId") String userId, @Field("userPw") String userPw, @Field("uuid") String uuid ); } |
public class LoginResult { // 결과를 받을 모델 private String result; private String message; public String getResult() { return result; } public String getMessage() { return message; } } |
public class Value extends AppCompatActivity { public static final String BASE_URL = "http://www.abc.com/mobile/"; public static final String URL_LOGIN = "login.php"; } |
예제는 결과를 받아서 RecyclerView 에 보여준다거나 후속 action 에 대한 건 기술하지 않았다.
이 예제는 그냥 복사해서 붙여넣기를 어떻게 하는지에 대한 설명이라고 보면 된다.
PHP 파일에 대한 사항은 기술하지 않는다. 이미 본 블로그 다른 예제를 보면 충분히 이해할 수 있으리라.
참고하면 도움되는 글
https://thdev.tech/androiddev/2016/11/13/Android-Retrofit-Intro/
https://link2me.tistory.com/1850 ArrayList 처리 예제
Update : 2020.8.3일
ㅇ Retrofit2 라이브러리를 여러번 호출하는 걸 만들어야 한다면 함수화를 하는 게 좋다.
import okhttp3.OkHttpClient; import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class RetrofitAPI { private static Retrofit retrofit = null; public static Retrofit getClient() { retrofit = new Retrofit.Builder() .baseUrl(Value.IPADDRESS) .addConverterFactory(GsonConverterFactory.create()) .client(createOkHttpClient()) .build(); return retrofit; } private static OkHttpClient createOkHttpClient() { // 네트워크 통신 로그(서버로 보내는 파라미터 및 받는 파라미터) 보기 OkHttpClient.Builder builder = new OkHttpClient.Builder(); HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); builder.addInterceptor(interceptor); return builder.build(); } } |
사용 예제
public interface RemoteService {// 서버에 호출할 메소드를 선언하는 인터페이스 // POST 방식으로 데이터를 주고 받을 때 넘기는 변수는 Field 라고 해야 한다. @FormUrlEncoded @POST(RetrofitUrl.URL_Verson) Call<VersionResult> lastVersion( @Field("os") String os ); @FormUrlEncoded @POST(RetrofitUrl.URL_GroupList) Call<GroupResult> getGroupList( @Field("keyword") String keyword ); } |
class RetrofitUrl { companion object { const val URL_Verson = "lastVersion.php" const val URL_GroupList = "groupList.php" } } |
private void UpgradeChk() { mloginService = RetrofitAPI.getClient().create(RemoteService.class); mloginService.lastVersion("0").enqueue(new Callback<VersionResult>() { @Override public void onResponse(Call<VersionResult> call, Response<VersionResult> response) { VersionResult result = response.body(); version = Value.VERSION; // 앱 버전 version = version.replaceAll("[^0-9]", ""); // 버전에서 숫자만 추출 Log.d("WEB", "Response: " + response); String Response = result.getVersion().replaceAll("[^0-9]", ""); // 버전에서 숫자만 추출 System.out.println("Server Version : " + Response); if (Integer.parseInt(version) < Integer.parseInt(Response)) { // 서버 버전이 더 높으면 UpgradeProcess(); if(Build.VERSION.SDK_INT >= 26) { NonSecretApp_Setting(); // 출처를 알 수 없는 앱 설정 화면 띄우기 } else { startActivity(new Intent(android.provider.Settings.ACTION_SECURITY_SETTINGS)); } } else { AutoLoginProgress(); } } @Override public void onFailure(Call<VersionResult> call, Throwable t) { } }); } |
더 세부적인 것은 Github 에 올려진 소스코드를 참조하면 도움될 것이다.
https://github.com/jsk005/JavaProjects/tree/master/retrofitsample
'안드로이드 > Android Data 통신' 카테고리의 다른 글
Volley 라이브러리 + Gson 라이브러리 변경 실습 (0) | 2020.07.12 |
---|---|
Volley 라이브러를 이용한 서버 데이터 가져오기 실습 (0) | 2020.07.12 |
Volley 라이브러리 사용 예제 (0) | 2018.09.30 |
AsyncTask return 결과 처리하는 방법 (0) | 2018.08.29 |
[Android Studio] HttpURLConnection PHP 세션 헤더 정보 추출 (0) | 2018.07.20 |