Learn & Record

[FastCampus] Android (Network 이론 4 ~ 실습 3 4 5 6) 본문

Dev/Android

[FastCampus] Android (Network 이론 4 ~ 실습 3 4 5 6)

Walker_ 2024. 2. 11. 09:20

Network
- 두대 이상의 컴퓨터를 연결하는 것
- 클라이언트와 서버의 연결
    - 클라이언트 : 사용자가 볼 수 있는 기기 (N개)
    - 서버 : 사용자가 볼 수 없는 기기 (1개)

- 네트워크가 필요한 이유
    1> 클라이언트(앱) -> (internet) -> 서버 : 요청(내가 지금 첫화면을 그리려고하는데 데이터 좀 줘)
    2> 서버 -> (internet) -> 클라이언트(앱) : 화면을 그릴 수 있는 데이터가 도착 (응답)
    클라이언트의 Request(요청) 서버가 response(응답)를 보낸다

- 대부분의 앱들이 정보를 서버로부터 받아서 하면을 구성한다. 문제점은 없을까?
    - 매번 똑같은 화면을 그리는데 매번 요청을 하면 -> 낭비다.
    -> 해결책 : 캐싱
        - 한번 받은 대이터를 클라이언트가 로컬 데이터베이스에 저장을 하고
          다시 필요한 경우에 서버에게 요청을 하는 것이 아니라 로컬 데이터베이스에 있는 데이터를 이용한다
    -> 캐싱은 구현 난이도가 높다

- 네트워킹
    - 서버와 클라이언트의 의사소통
    - 네트워크 약속(프로토콜) 존재한다

네트워크 프로토콜(규약)
- FTP -> 파일 전송 규약
- SMTP -> 메일 전송 규약
- HTTP -> 인터넷 서비스를 위한 규약

Request (클라이언트가 서버에게 보내는 요청)
Request Header
    - 요청에 대한 추가 정보
Request Body
    - 추가 정보
    - JSON 형태로 보낸다
Request Method

Response(서버가 클라이언트에게 보내는 응답)
Response Code
    - 응답의 요약
Response

JSON
- {} 객체 표현
- [] 배열 표현
- 키-벨류 방식


- 문자열
- 숫자 (정수, 소수)
- 객체
- 배열
- 불린
- 널

 

 

Serializing (Serializer)

- 꼬챙이로 객체를 담는다

- 학생 객체 (이름, 번호, 나이)

- * 객체를 전송을 위한 데이터 포맷으로 바꿔준다 

 

클라이언트    ------>   시리얼 라이징 --------> 서버

 

HttpURLConnection

- 안드로이드에서 기본으로 제공해주는 네트워크 모듈

- 매우 번거롭다

 

HttpURLConnection의 사용을 편하게 만들어준 라이브러리

- Volly, Retrofit, OKHttp 등

 


 

New Activity > (Run) Edit config 변경 > Manifests 메인 변경

 

Retrofit

- 라이브러리 추가 

- 라이브러리 추가 전 Github 스타 수 등 신뢰할만한 지표 확인

- build.gradle (Module) 에 라이브러리 추가

implementation 'com.squareup.retrofit2:retrofit:2.9.0'

 

- val retrofit 객체 생성

- base URL 기입

- Converter(Gson) 기입

- Gson : 읽을 수 없는 데이터를 코틀린 객체로 바꿔준다

- Gson 라이브러리 추가

implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

 

- 버전은 레트로핏과 맞춰주면 좋음

val retrofit = Retrofit.Builder()
    .baseUrl("http://mellowcode.org/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

- Builder Build 패턴

- 서비스 파일 생성

- Retrofit 액티비티에서 서비스 파일 객체 생성

- enqueue : 대기줄 

- RecyclerView 생성

- POST 생성 ( "json/student")

@POST("json/students/")
fun createStudent(
    @Body params: HashMap<String, Any>
): Call<StudentFromServer>

 

- POST 요청 시 URL 가장 뒤에 / 를 붙혀야 될 때도 있음

 

package com.example.fastcampus

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatViewInflater
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

class RetrofitActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_retrofit)

        // 서버 -> 읽을 수 없는 데이터 -> JSON -> Gson
        // Gson -> 읽을 수 없는 데이터를 코틀린 객체로 바꿔준
        val retrofit = Retrofit.Builder()
            .baseUrl("http://mellowcode.org/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        val retrofitService = retrofit.create(RetrofitService::class.java)
        retrofitService.getStudentList().enqueue(object : Callback<ArrayList<StudentFromServer>>{
            override fun onResponse(
                call: Call<ArrayList<StudentFromServer>>,
                response: Response<ArrayList<StudentFromServer>>
            ) {
                if(response.isSuccessful) {
                    val studentList = response.body()
                    findViewById<RecyclerView>(R.id.studentsRecyclerView).apply{
                        this.adapter = StudentListRecyclerViewAdapter(
                            studentList!!,
                            LayoutInflater.from(this@RetrofitActivity)
                        )
                        this.layoutManager = LinearLayoutManager(this@RetrofitActivity)

                    }
                }
            }

            override fun onFailure(call: Call<ArrayList<StudentFromServer>>, t: Throwable) {
            }
        })

        findViewById<TextView>(R.id.createStudent).setOnClickListener {

            val student = HashMap<String, Any>()
            student.put("name", "코카콜라")
            student.put("intro", "펩시")
            retrofitService.createStudent(student).enqueue(object: Callback<StudentFromServer> {
                override fun onResponse(
                    call: Call<StudentFromServer>,
                    response: Response<StudentFromServer>
                ) {
                    Log.d("testt", response.message())
                    Log.d("testt", response.errorBody().toString())
                    if (response.isSuccessful) {
                        val student = response.body()
                        Log.d("testt", "등록한 학생 : " + student!!.name)
                    }
                }

                override fun onFailure(call: Call<StudentFromServer>, t: Throwable) {
                    Log.d("testt", "요청 실패")
                }
            })

        }

    }
}

class StudentListRecyclerViewAdapter (
    var studentList : ArrayList<StudentFromServer>,
    var inflater: LayoutInflater
        ): RecyclerView.Adapter<StudentListRecyclerViewAdapter.ViewHolder>(){

    inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
        val studentName:TextView
        val studentAge:TextView
        val studentIntro:TextView

        init {
            studentName = itemView.findViewById(R.id.student_name)
            studentAge = itemView.findViewById(R.id.student_age)
            studentIntro = itemView.findViewById(R.id.student_intro)
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = inflater.inflate(R.layout.student_item, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.studentName.text = studentList.get(position).name
        holder.studentAge.text = studentList.get(position).age.toString()
        holder.studentIntro.text = studentList.get(position).intro
    }

    override fun getItemCount(): Int {
        return studentList.size
    }
}

 

- 아직은 이해가 잘 안되지만 언제나처럼 하다보면 잘 될거다

 

FastCampus 강의 : https://fastcampus.co.kr/dev_online_androidstandard

 

Android 앱 개발의 정석 with Kotlin 올인원 패키지 Online. | 패스트캠퍼스

앱 개발 기초 지식부터 배포 후 유지·보수까지 한 번에 끝내는 Android 앱 개발 입문 강의 | 입문자부터 주니어 개발자까지, 모두를 위한 Android 앱 개발 강의! 3개의 클론프로젝트와 4개의 기능 구

fastcampus.co.kr