- 간단한 버튼들로 Retrofit을 이용해 node.js 서버와 각각 ( post / get / put / delete )의 통신 방법으로 데이터를 주고받는 기능을 구현해보자
- 프로젝트 생성
Create New Project
Empty Activity / Next
Name : Example_Retrofit / Finish
- 버튼 만들기
- activity_main.xml
: Layout은 본인 편한대로! 저는 ConstraintLayout 공부중이라 이걸로... ( 쓰다보면 편할거같음 => 좋음 )
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_get"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="GET"
app:layout_constraintBottom_toTopOf="@+id/btn_post"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<Button
android:id="@+id/btn_post"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="POST"
app:layout_constraintBottom_toTopOf="@id/btn_update"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_get" />
<Button
android:id="@+id/btn_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="UPDATE"
app:layout_constraintBottom_toTopOf="@id/btn_delete"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_post" />
<Button
android:id="@+id/btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DELETE"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_update" />
</androidx.constraintlayout.widget.ConstraintLayout>
- gradle에 retrofit 추가
- build.gradle ( Module: Example_Retrofit.app )
: dependencies 블럭 안에 추가하고 우측 상단에 Sync Now 클릭!
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'
- AndroidManifest 에 권한 추가
- AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
: <manifest ... > 태그 다음에 넣기
android:usesCleartextTraffic="true"
: <application 태그 안에 넣기
- 통신하면서 동작할 인터페이스 생성
- ApiService.java
package com.example.example_retrofit;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.DELETE;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Path;
import retrofit2.http.Query;
public interface ApiService {
@GET("/retrofit/get")
Call<ResponseBody> getFunc(@Query("data") String data);
@FormUrlEncoded
@POST("/retrofit/post")
Call<ResponseBody> postFunc(@Field("data") String data);
@FormUrlEncoded
@PUT("/retrofit/put/{id}")
Call<ResponseBody> putFunc(@Path("id") String id, @Field("data") String data);
@DELETE("/retrofit/delete/{id}")
Call<ResponseBody> deleteFunc(@Path("id") String id);
}
: GET - Query 형태로 보냄
: POST - Field 형태로 보내기 때문에 @FormUrlEncoded 어노테이션 붙여줘야함
: PUT - 마찬가지로 Field 형태가 있어서 어노테이션 추가, 경로를 통해 id를 보냄
: DELETE - 경로를 통해 id를 보냄
=> 통신방법에 따라 보내는 형태가 다름 주의!
- MainActivity 작성
- MainActivity.java
: onCreate() 메소드 안에 소스코드가 길면 개인적으로 가독성이 좋지 않은것 같아서 메소드를 따로 만들어서 작성하는 편이다. 그리고 버튼이 비슷한 동작을 할 때에는 아래 코드처럼 클릭리스너를 implements해서 작성한다. 상황에 따라 본인이 알맞게 쓰시길... 코드스타일 굳히기가 너무 어렵다 ㅠ
package com.example.example_retrofit;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private final String TAG = "MainActivityLog";
private final String URL = "http://192.168.0.174:3000";
private Retrofit retrofit;
private ApiService service;
private Button btn_get, btn_post, btn_delete, btn_update;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
firstInit();
btn_get.setOnClickListener(this);
btn_post.setOnClickListener(this);
btn_delete.setOnClickListener(this);
btn_update.setOnClickListener(this);
}
/**
* Init
*/
public void firstInit() {
btn_get = (Button) findViewById(R.id.btn_get);
btn_post = (Button) findViewById(R.id.btn_post);
btn_delete = (Button) findViewById(R.id.btn_delete);
btn_update = (Button) findViewById(R.id.btn_update);
retrofit = new Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
service = retrofit.create(ApiService.class);
}
/**
* View.OnLongClickListener override method
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_get:
Call<ResponseBody> call_get = service.getFunc("get data");
call_get.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String result = response.body().string();
Log.v(TAG, "result = " + result);
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.v(TAG, "error = " + String.valueOf(response.code()));
Toast.makeText(getApplicationContext(), "error = " + String.valueOf(response.code()), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.v(TAG, "Fail");
Toast.makeText(getApplicationContext(), "Response Fail", Toast.LENGTH_SHORT).show();
}
});
break;
case R.id.btn_post:
Call<ResponseBody> call_post = service.postFunc("post data");
call_post.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String result = response.body().string();
Log.v(TAG, "result = " + result);
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.v(TAG, "error = " + String.valueOf(response.code()));
Toast.makeText(getApplicationContext(), "error = " + String.valueOf(response.code()), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.v(TAG, "Fail");
Toast.makeText(getApplicationContext(), "Response Fail", Toast.LENGTH_SHORT).show();
}
});
break;
case R.id.btn_update:
Call<ResponseBody> call_put = service.putFunc("board", "put data");
call_put.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String result = response.body().string();
Log.v(TAG, "result = " + result);
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.v(TAG, "error = " + String.valueOf(response.code()));
Toast.makeText(getApplicationContext(), "error = " + String.valueOf(response.code()), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.v(TAG, "Fail");
Toast.makeText(getApplicationContext(), "Response Fail", Toast.LENGTH_SHORT).show();
}
});
break;
case R.id.btn_delete:
Call<ResponseBody> call_delete = service.deleteFunc("board");
call_delete.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String result = response.body().string();
Log.v(TAG, "result = " + result);
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.v(TAG, "error = " + String.valueOf(response.code()));
Toast.makeText(getApplicationContext(), "error = " + String.valueOf(response.code()), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.v(TAG, "Fail");
Toast.makeText(getApplicationContext(), "Response Fail", Toast.LENGTH_SHORT).show();
}
});
break;
default:
break;
}
}
}
여기까지 앱에서 동작하는 부분은 완료! 다음 포스팅에서 각각의 버튼에 따라 동작하는 node.js 서버를 만들어보자.
'앱 개발 > 안드로이드(Java)' 카테고리의 다른 글
RecyclerView ScrollBar 설정 (0) | 2021.07.10 |
---|---|
RecyclerView 아이템 클릭 리스너 구현하기 (0) | 2021.06.17 |
RecyclerView를 커스텀해서 가로,세로 구현하기 (0) | 2021.06.12 |
ListView를 커스텀해서 구현하기 (0) | 2021.06.11 |
Retrofit2를 사용하여 서버(node.js)와 Post/Get/Put/Delete 통신하기 (2/2) (0) | 2021.06.10 |