티스토리 뷰
5장에서는 네트워킹에 대한 내용이 나오는데, 네트워킹은 인터넷에 연결되어 있는 원격지의 서버 또는 단말과 통신해서 데이터를 주고받는 동작들을 포함한다. 이번 포스팅에서는 이런 네트워킹에 대한 내용을 정리하려고 한다.
뒤에 나올 내용을 다루기에 앞서 네트워크 연결 방식에 대해 짚고 넘어가려고 한다. 먼저 원격지의 서버를 연결하는 가장 단순한 방식은 클라이언트와 서버가 일대일로 연결하는 '2-tier C/S(Client/Server)' 방식이다. 이 연결 방식을 가장 많이 사용하며, 대부분 클라이언트가 서버에 연결 되어 데이터를 요청하고 응답받는 단순한 개념으로 이해할 수 있다.
여기서 서버를 응용 서버와 데이터 서버로 구성하면 3-tier C/S 방식이 되는데, 이 연결 방식을 사용하면 데이터베이스를 분리할 수 있어 중간에 비즈니스 로직을 처리하는 응용 서버가 좀 더 다양한 역할을 할 수 있다는 장점이 생긴다.
단말 간의 통신이 일반화 되면서 클라이언트와 서버의 관계가 P2P(Pear-to-Pear) 모델로도 변형되어 사용되기도 하는데, P2P 모델은 서버를 두지 않고 단말끼리 서버와 클라이언트 역할을 하는 것이다.
이렇게 간단하게 네트워킹이 무엇인지 알아보았으니 이제 가장 기초적인 네트워킹 방법인 소켓에 대해 알아보자.
[Socket 사용하기]
네트워킹을 이해하려면 먼저 TCP/IP 수준의 통신 방식을 제공하는 소켓이 무엇인지 알아야 한다. IP 주소로 목적지 호스트를 찾아내고 포트로 통신 접속접을 찾아내는 소켓 연결은 TCP와 UDP 방식으로 나뉜다. 하지만 일반적인 프로그래밍에서는 대부분 TCP 연결을 사용하고, 인터넷 전화에 많이 사용되는 SIP 프로토콜이나 데이터 스트림을 처리하는 RTP 프로토콜은 기본적으로 UDP를 많이 사용한다.
HTTP 와 소켓(Socket)
HTTP 프로토콜은 소켓으로 웹서버에 연결한 후에 요청을 전송하고 응답을 받은 다음 연결을 끊는데, 이런 특성을 비연결성(Stateless)이라고 한다. 이런 특성 때문에 실시간으로 데이터를 처리하는 앱은 응답 속도를 높이기 위해 연결성이 있는 소켓 연결을 선호했지만, 지금은 인터넷의 속도가 빨라져 HTTP 프로토콜을 사용하는 웹이 일반적이 되었고 결국 속도가 그렇게 느리지 않으면서도 국제 표준을 따를 수 있다는 장점을 가진 웹서버로 많은 서버가 만들어지게 되었다. HTTP는 뒤에서 더 자세하게 다룰 것이다.
소켓은 다른 컴퓨터와 연결을 만드는 과정으로, 그 연결 위에서 데이터가 왔다 갔다 하는 것이다. 이 연결이 실제로는 TCP 레이어에서 패킷을 계속 주고 받으면서 다른 컴퓨터가 인터넷망에서 어느 위치에 있는지를 계속 알아내는 과정이라고 할 수 있다.
소켓에 대한 예제를 알아보기 전에 알아두어야 할 것이 있다. 안드로이드는 소켓 연결 등을 시도하거나 응답을 받아 처리할 때 스레드를 사용해야 한다는 것이다. 이전에는 권장사항이었으나 현재 플랫폼 버전에서는 강제사항이 되었으므로 스레드를 사용하지 않으면 네트워킹 기능 자체가 동작하지 않는다. (이러한 이유로 이전 포스팅에서 스레드와 핸들러에 대해 먼저 정리해 두었다.)
소켓 연경 방식은 다음과 같다. 안드로이드에서는 표준 자바의 소켓을 그대로 사용할 수 있는데, 서버 쪽에는 port를 지정한 ServerSocket 객체를 만들어서 실행하고, 클라이언트 쪽에는 IP와 port를 지정한 Socket을 만들어 해당 IP와 port로 실행중인 ServerSocket과 연결한다. 여기서 데이터를 주고 받기 위해 Stream 객체를 이용한다.
이제 소켓 예제를 보며 서버와 클라이언트의 소켓 연결 방식을 확인해 보자. SocketServer 프로젝트와 SocketClient 프로젝트를 각각 만들어서 서로 통신하게 하는 예제를 볼 것이다.
먼저, SocketServer 프로젝트에서 새로운 스레드를 만들어서 run() 메서드 안에 아래 코드를 넣는다.
try {
int port = 5001;
ServerSocket server = new ServerSocket(port); // 서버소켓 객체 만들기
while (true) {
// 클라이언트로부터 요청이 올 때 까지 대기상태. 요청이 들어오면 Socket 리턴
Socket socket = server.accept();
Log.d("Server Socket", "연결됨.");
ObjectInputStream instream = new ObjectInputStream(socket.getInputStream());
Object input = instream.readObject();
Log.d("Server Socket", "받은 데이터 : " + input);
ObjectOutputStream outstream = new ObjectOutputStream(socket.getOutputStream());
outstream.writeObject(input + " from server.");
outstream.flush();
Log.d("Server Socket", "데이터 보냄.");
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
서버소켓 객체를 만들 때 IO Exception이 발생할 수 있기 때문에 try-catch 문으로 감싸주고, accept()에서 클라이언트로부터 요청이 올 때 까지 대기상태로 기다린다. 여기서 클라이언트로부터 요청을 계속 받아서 처리해 주어야 하기 때문에 while(true)로 무한루프를 돌게 해야 한다. 요청이 들어오면 요청온 Socket 객체가 리턴되는데, 그 객체에서 ObjectInputStream으로 데이터를 읽고 ObjectOutputStream으로 데이터를 넣을 수 있다. 여기서 주의할 점은 데이터를 쓰고 나서는 스트림 버퍼에 데이터가 남아있을 수 있기 때문에 flush()로 버퍼를 비워야 한다. 마지막으로 소켓 연결을 더 이상 유지할 필요가 없다면 한정적인 리소스를 낭비하지 않도록 socket.close()로 소켓 연결을 끊어주어야 한다. 하지만 소켓 연결을 계속 유지해야 한다면 끊어주면 안 된다.
이제, Socket Client 프로젝트에서 새로운 스레드를 만들어서 run() 메서드 안에 아래 코드를 넣는다.
try {
int port = 5001;
Socket socket = new Socket("localhost", port); // 클라이언트 소켓 생성 후 연결
Log.d("Client Socket", "서버와 연결됨.");
ObjectOutputStream outstream = new ObjectOutputStream(socket.getOutputStream());
outstream.writeObject("우와와으ㅏ어아");
outstream.flush();
Log.d("Client Socket", "서버에게 데이터 전송.");
ObjectInputStream instream = new ObjectInputStream(socket.getInputStream());
final Object input = instream.readObject();
handler.post(new Runnable() {
@Override
public void run() {
textView.setText("받은 데이터: " + input);
}
});
socket.close();
} catch (Exception e) {
Log.d("Log", "error message: " + e.getMessage());
}
IP와 port를 넣어 Socket 객체를 생성한다. 여기서 서버가 로컬에서 동작하고 있기 때문에 host로 "localhost"를 넣어주고, port는 서버소켓을 만들 때 지정한 port를 넣어야 한다. 서버에서와 마찬가지로 소켓을 생성할 때 IO Exception이 발생할 수 있기 때문에 try-catch로 감싸주고, 소켓을 통해 데이터를 주고 받을 때에는 ObjectInputStream과 ObjectOutputStream 객체를 사용한다. 또한 writeObject()로 버퍼에 데이터를 쓰고 나서는 flush()로 버퍼를 비워준다. 여기서 서버로부터 받은 데이터를 화면 UI에 표시하고 싶을 때는 핸들러를 통해 Runnable 객체를 넘겨줘서 메인 스레드에서 동작하도록 해야 한다. 마지막으로 리소스 낭비를 방지하기 위해 소켓 연결을 끊어야 하는 곳에서 socket.close()로 연결을 끊어준다.
이렇게 하고 각각의 메인 스레드에서 스레드를 생성해 start() 해 주면 잘 동작한다. 소켓 예제가 잘 실행되는지 보고자 할 때는 항상 서버를 먼저 실행하고 그 다음에 클라이언트를 실행해야 한다는 점을 유의해야 한다.
여기서 서버를 액티비티로 만드는 경우 시스템 리소스가 부족한 경우 강제로 종료될 수 있다. 이런 이유로 서버는 일반적으로 서비스로 만들어서 실행한다. 그 방법은 먼저 서비스를 만들고 그 안에 스레드를 정의하는데 그 안에는 위에서 만들었던 서버 실행하는 run() 코드를 그대로 넣는다. 그리고 나서 onCreate()에서 스레드 객체를 생성하고 start()로 실행하면 된다. 아래 코드는 그 예시이다.
public class ChatService extends Service {
public ChatService() {
}
@Override
public void onCreate() {
super.onCreate();
ServerThread thread = new ServerThread();
thread.start();
}
class ServerThread extends Thread {
@Override
public void run() {
// 여기에 아까 위에 있던 서버를 실행하는 코드를 넣으면 된다.
}
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
}
이렇게 소켓 사용법을 알아보았는데 마지막으로 소켓 사용 시 주의할 점을 정리하고 다음으로 넘어가려고 한다.
※ 주의할 점 ※
-
안드로이드는 소켓 연결 등을 시도하거나 응답을 받아 처리할 때 스레드를 사용해야 한다.
-
일반적으로 서버는 이클립스에서 자바 파일로 만들지만, 약식으로 안드로이드에서 진행한 것이다.
(안드로이드에서도 표준 자바 라이브러리를 사용할 수 있기 때문에 코드는 동일하다.) -
서버는 액티비티로 만드는 경우 시스템 리소스가 부족하면 강제로 종료될 수 있기 때문에 일반적으로는 서비스로 만들어서 실행한다.
-
네트워킹 기능을 사용하기 위해서는 AndroidManifest.xml 파일에 INTERNET 권한을 추가해야 한다.
-
실제 앱에서 네트워킹 관련 코드를 만들 때는 ObjectInputStream과 ObjectOutputStream은 잘 사용하지 않는다.
이 두 클래스는 자바의 객체(Object) 정보를 편리하게 주고 받을 수 있도록 만들어진 것이지만 자바가 아닌 다른 언어로 만들어진 서버와 통신할 경우 데이터 송수신이 정상적으로 이루어지지 않을 수 있기 때문에 일반적으로는 DataInputStream과 DataOutputStream을 많이 사용한다.
[웹으로 요청하기]
HTTP 이해하기
웹은 HTTP라는 프로토콜이라는 국제 표준 규약을 가지고 데이터가 왔다 갔다 하는 것이다. HTTP도 소켓을 쓰도록 되어 있는데, 밑바닥에는 소켓 서버를 만들고 소켓으로 접속하는 구조가 동일하다. 이 때 소켓 위에서 HTTP라는 형식대로 데이터를 주고 받는 것이다. 이를 HTTP Request / HTTP Response 라고 한다.
HTTP는 기본적으로 헤더(Header)와 바디(Body)로 구분되는데, 헤더는 데이터의 설명 부분이고 바디는 데이터 부분이다.
그 중 HTTP 요청 포맷(HTTP Request Format)은 다음와 같다.
첫 번째 줄이 기본적인 요청 정보를 포함하고 있는데 GET이나 POST와 같은 요청 방식(Method), 요청 패스 그리고 HTTP 버전 등이 들어가 있다. 헤더에 들어가 있는 각각의 줄은 하나의 속성을 나타내고 속성이름 + 콜론(:) + 속성값으로 구성된다. 헤더와 바디는 한 줄 더 띄워져 있는 것으로 구분하며, 바디에는 전송하고자 하는 데이터를 넣을 수 있다.
HTTP 응답 포맷(HTTP Response Format)은 요청 포맷과 크게 다르지 않다. 헤더와 바디로 구분되고 헤더에는 한 줄씩 속성이 들어가며, 응답의 첫 줄은 상태를 나타내고 HTTP 버전과 응답 코드, 응답 메시지 등으로 구성된다.
웹으로 요청하기
앱에서 웹서버에 요청하는 방식은 표준 자바를 이용할 때와 크게 다르지 않다. 다만 스레드를 사용해야 한다는 점을 꼭 기억해야 한다. 자바에서 HTTP 클라이언트를 만드는 가장 간단한 방법은 URL 객체를 만들고 이 객체의 openConnection() 메서드를 호출하여 HttpURLConnection 객체를 만드는 것이다. openConnection() 메서드의 반환형이 URLConnection이기 때문에 HttpURLConnection으로 형변환하여 사용해야 한다.
public void setRequestMethod(String method)
public void setRequestProperty(String field, String newValue)
HttpURLConnection 객체로 연결할 경우에는 setRequestMethod()로 GET이나 POST 문자열을 파라미터로 전달하여 요청 방식을 설정할 수 있고 setRequestProperty()로 요청할 때 헤더에 들어가는 필드 값을 지정할 수 있다.
다음 코드는 HttpURLConnection 객체를 사용하여 웹에 연결하여 정보를 문자열로 받아온 뒤 뷰에 보여주는 코드이다. 아래의 코드는 별도의 스레드 안에서 실행해야 한다.
final StringBuilder output = new StringBuilder();
try {
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 객체 생성
if (connection != null) {
connection.setConnectTimeout(10000); // 10초 동안 연결 대기
connection.setRequestMethod("GET"); // GET방식으로 요청
connection.setDoInput(true); // 객체에 입력이 가능
connection.getResponseCode(); // 웹서버에 연결하는 메소드. 응답으로 resCode 리턴
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while (true) {
line = reader.readLine(); // 결과 한 줄씩 읽기
if (line == null) break;
output.append(line + "\n");
}
reader.close();
connection.disconnect();
}
} catch (Exception e) {
Log.d("Log", "error message: " + e.getMessage());
}
handler.post(new Runnable() {
@Override
public void run() {
textView.append(output.toString() + "\n"); // 뷰에 업데이트
}
});
HttpURLConnection을 쓰기 위해서는 INTERNET 권한이 있어야 하므로 AndroidManifest.xml에 아래의 코드를 추가해야 한다.
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true" />
<!--안드로이드 파이 버전부터 WebView에 일반 텍스트 URL 접근이 막힘. 이 속성은 텍스트 URL을 무조건 허용한다는 의미.-->
HttpURLConnection는 웹 요청을 하는 가장 간단한 방법이지만 요청을 할 때마다 스레드, 핸들러 등을 직접 만들어야 하기 때문에 코드 양이 많아지는 불편함이 있다. 그렇기 때문에 이를 편하게 지원해주는 OkHttp, Volley 등 라이브러리가 있다.
[Volley]
웹 요청과 응답을 단순화시키기 위해 만들어진 라이브러리들 중의 하나인 Volley 라이브러리에 대해 알아보려고 한다. Volley 라이브러리는 외부 라이브러리이기 때문에 build.gradle(Module: app) 파일의 dependencies 안에 아래의 코드를 추가해야 사용이 가능하다.
implementation 'com.android.volley:volley:1.1.0'
Volley 사용 방법은 간단하다. 요청(Request) 객체를 만들고 이 요청 객체를 요청 큐(RequestQueue)에 넣어주면 된다. 그러면 요청 큐가 내부에서 스레드를 만들고 웹서버에 요청하고 응답을 받고 나면 메인 스레드에서 결과를 처리할 수 있도록 만든 후 자신이 설정한 리스너의 메소드를 호출해주기 때문에 화면에 결과를 표시할 때 핸들러를 사용하지 않아도 된다.
Volley 라이브러리의 가장 큰 장점은 스레드를 신경쓰지 않아도 된다는 점이다. 또한 네트워크 요청(Request) 우선 순위를 자동으로 관리하고, 동시에 여러 네트워크 요청을 할 수 있다. 그리고 요청을 할 때 Cache 적용 여부를 의식하지 않아도 내부적으로 처리가 되기 때문에 개발자는 이런 것들을 신경쓰지 않아도 된다.
그러면 이제 RequestQueue를 만드는 법을 알아보자.
RequestQueue는 앱 별로 하나만 만들어서 사용하는 것이기 때문에 애플리케이션 객체로 만드는 것이 좋다. 또 다른 방법은 새로운 클래스를 만들어서 클래스 멤버 변수(static 변수)로 선언해 두고 쓰는 것이다. RequestQueue는 new로 직접 만드는 것이 아니라 Volley 클래스 내부의 newRequestQueue() 메서드를 사용해서 만든다.
1. 새로운 클래스를 만드는 방법
public class AppHelper {
public static RequestQueue requestQueue;
public static void createRequestQueue(Context context) {
if (requestQueue == null) {
requestQueue = Volley.newRequestQueue(context);
}
}
}
2. 애플리케이션 객체로 만드는 방법
public class MyApplication extends Application {
public static RequestQueue requestQueue;
public static void createRequestQueue(Context context) {
if (requestQueue == null) {
requestQueue = Volley.newRequestQueue(context);
}
}
}
위와 같이 애플리케이션 클래스를 상속해서 사용할 경우, Manifest 파일에 android:name 속성을 추가해 주어야 한다.
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
...
</application>
※ 애플리케이션 객체란?
앱 프로세스는 유일한 Application 객체가 있고 그 아래 컴포넌트인 서비스, 브로드캐스트 수신자, 액티비티, 내용 제공자로 구성된다.
Application 클래스가 모든 컴포넌트보다 우선적으로 생성되고 싱글톤으로 하나의 객체만 생성되므로 앱 전역에서 필요한 기능을 두기에 좋은 곳이다. 또한 Application 객체의 멤버는 프로세스의 어디에서나 참조할 수 있다.
액티비티나 서비스에서는 다음 메소드로 Application 객체를 가져올 수 있다.
final Application getApplication();
이제 RequestQueue에 넣을 Request 만드는 법을 알아보자.
-
Request는 아래와 같이 타입에 따라 클래스가 존재한다. 문자열을 주고 받는 Request는 StringRequest 클래스를 사용한다.
-
생성자의 인자로 4개를 받는데 각각의 인자는 다음과 같다.
-
첫 번째 파라미터는 요청 방식을 지정하는 GET() 또는 POST() 메서드를 전달한다.
-
두 번째 파라미터는 웹사이트 주소를 전달한다.
-
세 번째 파라미터는 응답을 성공적으로 받았을 때 호출될 리스너 객체를 전달한다.
이 리스너의 onResponse() 메서드는 응답을 받았을 때 자동으로 호출된다. -
네 번째 파라미터는 에러가 발생했을 때 호출될 리스너 객체를 전달한다.
-
-
만약 요청 방식으로 POST 방식을 사용하고 요청 파라미터를 전달하고 싶다면 getParams() 메서드에서 반환하는 HashMap 객체에 파라미터 값들을 넣어주면 된다.
-
이렇게 만든 요청 객체를 요청 큐에 넣어준다. 요청 큐의 add() 메서드로 요청 객체를 넣으면 요청 큐가 자동으로 요청과 응답 과정을 진행한다.
String urlStr = "https://www.google.com/";
StringRequest request = new StringRequest(
Request.Method.GET,
urlStr,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
println("응답 : " + response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
println("에러 : " + error.toString());
}
}
){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<String,String>();
return params;
}
};
AppHelper.requestQueue.add(request);
추가적으로, 요청 객체는 cache 메커니즘을 지원하는데 이는 요청을 보낸 뒤에 그 응답 결과를 cache에 넣고 같은 요청을 보낼 때 cache에 저장된 응답 결과를 사용하는 메커니즘이다. 그렇기 때문에 이전 응답 결과를 사용하지 않겠다면 setShouldCache() 메서드를 사용해서 cache를 사용하지 않도록 설정해야 한다.
[Gson]
JSON(JavaScript Object Notation)은 자바스크립트 객체 포맷의 데이터를 주고받을 때 사용할 수 있도록 문자열로 표현한 것을 말한다. 그렇기 때문에 자바스크립트 객체 포맷과 거의 동일하다. 약간의 차이는 문자열 형식으로 표현하면서 속성의 이름과 문자열에 큰따옴표를 사용한다는 점이다.
웹 요청에 대한 응답이 JSON 포맷으로 된 데이터라면, 이를 안드로이드에서 사용할 수 있는 자바 객체로 변환하는 과정이 필요하다. Gson은 JSON 문자열을 자바 객체로 변환해 주는 외부 라이브러리이다. 즉, Gson을 이용하면 JSON 문자열을 자바 객체로 만들 수 있다. Volley를 이용해 웹서버로부터 JSON 응답을 받았다면 Gson을 이용해 자바 객체로 바꾸고 그 객체 안에 들어있는 데이터를 사용한다.
Gson은 외부 라이브러리이기 때문에 build.gradle(Module: app) 파일의 dependencies 안에 아래의 코드를 추가해야 사용이 가능하다.
implementation 'com.google.code.gson:gson:2.8.2'
Gson은 JSON 문자열을 자바 객체로 바꿔주는데 자바는 객체를 만들 때 클래스를 먼저 정의하는 과정을 거치기 때문에 JSON 문자열을 자바 객체로 변환하기 위해서는 먼저 JSON 문자열에 맞게 자바 클래스를 정의해야 한다. 그러면 Gson이 JSON 객체를 정의한 클래스에 따라 넘어온 JSON 타입을 알아서 파싱한 뒤 정의한 자바 객체로 만들어준다.
예를 들어 아래와 같은 JSON 포맷 응답이 온다고 하자.
그러면 가장 밖에 있는 boxOfficeResult를 멤버 변수로 갖는 MovieList 클래스를 만든다. 이 때 주의할 점은 Gson으로 변환하기 위해서는 들어온 key 값과 동일한 변수명이어야 하고, value 타입에 맞는 타입으로 선언되어야 한다. 여기서 value 타입도 JSON 포맷이기 때문에 MovieResult라는 클래스를 새로 만들어야 한다. 먼저 MovieList 클래스를 아래처럼 만든다.
class MovieList {
public MovieResult boxOfficeResult;
}
MovieResult 안에 데이터는 boxofficeType, showRange, dailyBoxOfficeList이다. 이 중 boxofficeType와 showRange는 문자열이고 dailyBoxOfficeList는 배열이다. 그렇기 때문에 dailyBoxOfficeList의 타입은 ArrayList로 하고 그 안에 들어갈 타입의 클래스를 새로 만들어야 한다. 먼저 MovieResult 클래스를 아래처럼 만든다.
class MovieResult {
public String boxofficeType;
public String showRange;
public ArrayList<Movie> dailyBoxOfficeList = new ArrayList<>();
}
배열 안에 데이터는 rnum, rank, movieNm, openDt로 모두 문자열이다. 그렇기 때문에 아래와 같이 Movie 클래스를 만들어준다.
class Movie {
public String rnum;
public String rank;
public String movieNm;
public String openDt;
}
이제 자바 객체를 만들 준비가 끝났으니 Gson을 사용하는 코드를 보자.
Gson gson = new Gson();
MovieList movieList = gson.fromJson(response, MovieList.class);
if (movieList != null) {
int numOfMovieList = movieList.boxOfficeResult.dailyBoxOfficeList.size();
String TypeOfBoxoffice = movieList.boxOfficeResult.boxofficeType;
...
}
Gson 객체를 만든 뒤 fromJson() 메서드에 응답으로 들어오는 문자열 response와 변환하고자 하는 클래스인 MovieList.class를 인자로 넣어주면 MovieList의 객체를 만들어서 반환한다. 그러면 우리는 Gson이 변환해준 객체를 가져다 쓰기만 하면 된다.
우리는 Volley 라이브러리를 이용해 Request를 만들 때 인자로 넣어주는 Response.Listener<> 리스너 안에 onResponse() 메서드가 응답이 왔을 때 자동으로 호출되는 메서드임을 알고 있다. 그렇기 때문에 onResponse() 메서드 안에 Gson을 이용해 변환해주는 코드를 넣으면 간단하게 우리가 응답 받은 데이터를 사용할 수 있게 된다.
'Mobile > Boost Course' 카테고리의 다른 글
[부스트코스 PJ7 정리노트] 사진촬영 구현 (0) | 2019.09.19 |
---|---|
[부스트코스 PJ6 정리노트] 데이터베이스 (0) | 2019.09.05 |
[부스트코스 PJ5 정리노트] 스레드와 핸들러 (0) | 2019.08.25 |
[부스트코스 PJ4 정리노트] 화면 내비게이션 (0) | 2019.08.18 |
[부스트코스 PJ3 정리노트] 화면 여러 개 만들기 (0) | 2019.08.10 |
- Total
- Today
- Yesterday
- SOCKET
- RecyclerView
- DiffUtil
- AsyncListDiffer
- python3
- MSSQL
- RuntimeException
- gson
- GitHub
- SQL
- 파이썬
- 알고리즘
- SQLD
- covariance
- SQLiteOpenHelper
- 위험권한
- personal access token
- Algorithm
- AndroidStudio
- Python
- pecs
- ViewHolder
- Java
- kotlin
- SQL Server
- 안드로이드
- Android
- 내용제공자
- 프로그래머스
- 부스트코스
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |