<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>cjsghkd-35.log</title>
        <link>https://velog.io/</link>
        <description>성장하고 싶은 안드로이드 개발자입니다.</description>
        <lastBuildDate>Mon, 22 May 2023 16:25:02 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>cjsghkd-35.log</title>
            <url>https://velog.velcdn.com/images/cjsghkd-35/profile/225af8f7-521d-48e5-a1cc-3cb2f2e22ca7/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. cjsghkd-35.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/cjsghkd-35" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Hi-v2] - 5_Login Publishing]]></title>
            <link>https://velog.io/@cjsghkd-35/Hi-v2-5Login-Publishing</link>
            <guid>https://velog.io/@cjsghkd-35/Hi-v2-5Login-Publishing</guid>
            <pubDate>Mon, 22 May 2023 16:25:02 GMT</pubDate>
            <description><![CDATA[<h3 id="소개">소개</h3>
<p>MSG라는 교내 동아리에서 Hi-v2(홈베이스 관리 시스템)을 만드면서 일어났던 일을 정리한 내용입니다.</p>
<hr>
<h3 id="작업-내용">작업 내용</h3>
<ul>
<li>로그인 페이지 퍼블리싱 하기</li>
</ul>
<hr>
<h3 id="구현-화면">구현 화면</h3>
<p><img src="https://velog.velcdn.com/images/cjsghkd-35/post/d4d2cdb8-b427-44cd-8405-14933d181306/image.png" alt=""></p>
<hr>
<p><a href="https://github.com/GSM-MSG">MSG 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/Hi-v2-Android">Hi-v2 Android 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/Hi-v2-Android/pull/10">작업한 PR</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[14_Kotlin_Class]]></title>
            <link>https://velog.io/@cjsghkd-35/14KotlinClass</link>
            <guid>https://velog.io/@cjsghkd-35/14KotlinClass</guid>
            <pubDate>Tue, 16 May 2023 15:35:05 GMT</pubDate>
            <description><![CDATA[<h3 id="클래스">클래스</h3>
<ul>
<li>객체(Object)를 만드는 문법적인 요소</li>
<li>설명서 (해당 클래스를 통해서 객체를 만드는 방법)</li>
<li>객체의 기능에 대한 설명</li>
</ul>
<hr>
<h3 id="생성자">생성자</h3>
<ul>
<li><p>주 생성자 (Primary Constructor)</p>
<ul>
<li><p>클래스 이름 옆에 괄호로 둘러싸인 코드</p>
</li>
<li><p>클래스를 통해서 객체를 만드는데 필요한 재료들을 적어 준다</p>
<ul>
<li>재료이름(변수명) : 재료타입(변수타입)</li>
</ul>
</li>
<li><p>반드시 한개만 존재할 수 있다</p>
</li>
<li><p>constructor 키워드를 생략할 수 있다</p>
<pre><code class="language-kotlin">// 주 생성자 -&gt; 풀버젼 (생략이 없는 버젼)
class User1 constructor(name : String) { // 클래스 네이밍은 대문자로 시작한다
val userName : String // 클래스 속성 (프로퍼티, property)은 init블럭에서 초기화 한다

init { // 클래스가 생성될때 (클래스를 통해서 객체를 만들때) 호출된다
    println(name)
    userName = name
}
}
// 주 생성자 -&gt; constructor를 생략하는 방법
class User2 (name : String) {
val userName : String = name
}</code></pre>
</li>
</ul>
</li>
<li><p>부 생성자 (Secondary Constructor)</p>
<ul>
<li><p>constructor 키워드를 생략할 수 없다</p>
</li>
<li><p>주 생성자에는 객체를 만들기 위한 필수 조건이 있다면, 부 생성자에는 객체를 만들기 위한 옵션 조건이 있다</p>
</li>
<li><p>부 생성자에는 주 생성자에서 필요한 조건을 포함하고 있어야 한다 (파라미터를 포함하고 있어야한다)</p>
</li>
<li><p>부 생성자는 주 생성자에게 생성을 위임해야한다</p>
<pre><code class="language-kotlin">class User3 constructor (name : String) {
var age : Int = 0
val name : String
val nickName : String = &quot;&quot;

init {
   println(&quot;init&quot;)
   this.name = name
   this.age = 100
}

// 부 생성자는 클래스명 우측에 올수 없다 -&gt; 클래스의 본문에 있어야한다
constructor(name : String, age : Int) : this(name) { // this = User6
   println(&quot;second&quot;)
   this.age = age
}
// 부생성자는 여러개 존재할 수 있다
constructor(name : String, age : Int, nickName : String) : this(name) {
   this.age = age
   this.nickName = nickName
}
}</code></pre>
</li>
</ul>
</li>
<li><p>init 블록 (initial, 초기) (블록 =&gt; {})</p>
<ul>
<li>초기화 블록</li>
<li>초기화 시에 필요한 작업을 하는 곳 (클래스 생성시 무조건 초기화 시켜줘야한다)</li>
</ul>
</li>
</ul>
<hr>
<h3 id="클래스의-기능">클래스의 기능</h3>
<ul>
<li><p>클래스 - 붕어빵 틀</p>
<ul>
<li>붕어빵 틀을 통해서 찍어내는 과정 -&gt; 인스턴스화 한다</li>
<li>그 결과물 -&gt; 객체(오브젝트)<ul>
<li>val book = Book(&quot;책제목&quot;)</li>
</ul>
</li>
</ul>
</li>
<li><p>붕어빵 틀을 사용하는 방법 -&gt; 생성자 사용법</p>
</li>
<li><p>결과물이 가지고 있는 것 -&gt; 속성(프로퍼티) (ex. 책 제목)</p>
</li>
<li><p>클래스 기능 추가 -&gt; 클래스안에 함수(기능)을 추가한다</p>
<pre><code class="language-kotlin">class FootballPlayer constructor(uniform : String, ball : String) {

  val uniform : String
  val ball : String

  init {
      this.uniform = uniform
      this.ball = ball
  }

  fun kick() {
      // println(&quot;공을 찼다&quot;)
      // 반복, 예외처리, 흐름제어
      if (ball == &quot;축구공&quot;) println(&quot;축구공을 찼다&quot;)
      else println(&quot;공이 없다&quot;)
  }

  fun pass() {
      println(&quot;패스를 했다&quot;)
  }
</code></pre>
</li>
</ul>
<p>}</p>
<p>val footballPlayer = FootballPlayer(&quot;빨간색 유니폼&quot;, &quot;축구공&quot;)
//println(footballPlayer.uniform)
footballPlayer.kick()</p>
<p>val footballPlayer2 = FootballPlayer(&quot;파란색 유니폼&quot;, &quot;축구공&quot;)
footballPlayer2.pass()
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Hi-v2] - 4_Splash Screen]]></title>
            <link>https://velog.io/@cjsghkd-35/Hi-v2-4Splash-Screen</link>
            <guid>https://velog.io/@cjsghkd-35/Hi-v2-4Splash-Screen</guid>
            <pubDate>Tue, 16 May 2023 15:22:03 GMT</pubDate>
            <description><![CDATA[<h3 id="소개">소개</h3>
<p>MSG라는 교내 동아리에서 Hi-v2(홈베이스 관리 시스템)을 만드면서 일어났던 일을 정리한 내용입니다.</p>
<hr>
<h3 id="작업-내용">작업 내용</h3>
<ul>
<li>기존 mipmap 파일들 -&gt; Hi-v2 Logo 들어간 mipmap 파일 만들어서 바꾸기</li>
</ul>
<hr>
<h3 id="시연-영상">시연 영상</h3>
<p>[<img src="https://velog.velcdn.com/images/cjsghkd-35/post/eeab5ecd-8d86-4f5c-b8de-c1f518cc4e4c/image.svg" alt="시연 영상">]
(<a href="https://velog.velcdn.com/images/cjsghkd-35/post/88d8a115-9881-418b-9508-73887bc4948e/image.mov">https://velog.velcdn.com/images/cjsghkd-35/post/88d8a115-9881-418b-9508-73887bc4948e/image.mov</a>)</p>
<hr>
<p><a href="https://github.com/GSM-MSG">MSG 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/Hi-v2-Android">Hi-v2 Android 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/Hi-v2-Android/pull/8">작업한 PR</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Hi-v2] - 3_DI 세팅하기]]></title>
            <link>https://velog.io/@cjsghkd-35/Hi-v2-3DI-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cjsghkd-35/Hi-v2-3DI-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 16 May 2023 15:08:56 GMT</pubDate>
            <description><![CDATA[<h3 id="소개">소개</h3>
<p>MSG라는 교내 동아리에서 Hi-v2(홈베이스 관리 시스템)을 만드면서 일어났던 일을 정리한 내용입니다.</p>
<hr>
<h3 id="작업내용">작업내용</h3>
<ul>
<li>Hilt, Retrofit, OkHttp 의존성 주입하기</li>
<li>HiltAndroidApp 만들기 (Application)</li>
<li>Base_URL을 local.properties에 저장하기</li>
<li>Network Module 만들기</li>
</ul>
<hr>
<h3 id="주요코드">주요코드</h3>
<ul>
<li><p>android.yml</p>
<ul>
<li>CI 파일에서 깃허브 시크릿 변수를 읽을 수 있게 해주는 코드입니다.
```kotlin</li>
</ul>
</li>
<li><p>name: Create LOCAL_PROPERTIES</p>
<pre><code>  run: echo &#39;${{ secrets.LOCAL_PROPERTIES }}&#39; &gt; ./local.properties</code></pre><pre><code></code></pre></li>
<li><p>app/build.gradle.kts</p>
<ul>
<li>local.properties에 저장된 변수 값 가져오는 코드입니다.<pre><code class="language-kotlin">android {
    buildConfigField(
        &quot;String&quot;,
        &quot;BASE_URL&quot;,
        getApiKey(&quot;BASE_URL&quot;)
    )
    ...
}
</code></pre>
</li>
</ul>
</li>
</ul>
<p>fun getApiKey(propertyKey: String): String {
    val propFile = rootProject.file(&quot;./local.properties&quot;)
    val properties = Properties()
    properties.load(FileInputStream(propFile))
    return properties.getProperty(propertyKey)
}</p>
<pre><code>
- NetworkModule.kt
  - Hilt를 이용한 의존성 주입을 위해 모듈을 만들었습니다.
```kotlin
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides
    @Singleton
    fun provideOkhttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .build()
    }

    @Provides
    @Singleton
    fun provideRetrofitInstance(
        okHttpClient: OkHttpClient,
        gsonConverterFactory: GsonConverterFactory
    ): Retrofit {
        return Retrofit.Builder()
            .baseUrl(BuildConfig.BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(gsonConverterFactory)
            .build()
    }

    @Provides
    @Singleton
    fun provideConverterFactory(): GsonConverterFactory {
        return GsonConverterFactory.create()
    }
}</code></pre><hr>
<h3 id="적용-중-일어났던-에러">적용 중 일어났던 에러</h3>
<ul>
<li><p>Property key &#39;BASE_URL&#39; not found in local.properties</p>
<ul>
<li>깃허브 시크릿 변수에 value 형식으로 넣어주던 값을 key-value 형식으로 수정하여 값을 넣어줬습니다.</li>
</ul>
</li>
<li><p>원래 코드</p>
<pre><code class="language-kotlin">&quot;https://www.example.com&quot;</code></pre>
</li>
<li><p>수정한 코드 </p>
<pre><code class="language-kotlin">BASE_URL=&quot;https://www.example.com&quot;</code></pre>
</li>
</ul>
<hr>
<p><a href="https://github.com/GSM-MSG">MSG 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/Hi-v2-Android">Hi-v2 Android 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/Hi-v2-Android/pull/6">작업한 PR</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[13_Kotlin_고차함수&람다]]></title>
            <link>https://velog.io/@cjsghkd-35/13Kotlin%EA%B3%A0%EC%B0%A8%ED%95%A8%EC%88%98%EB%9E%8C%EB%8B%A4</link>
            <guid>https://velog.io/@cjsghkd-35/13Kotlin%EA%B3%A0%EC%B0%A8%ED%95%A8%EC%88%98%EB%9E%8C%EB%8B%A4</guid>
            <pubDate>Sun, 14 May 2023 16:45:15 GMT</pubDate>
            <description><![CDATA[<h3 id="고차함수-high-order-function">고차함수 (High-order function)</h3>
<ul>
<li><p>함수를 인자(파라미터)로 받고 결과 값으로 내보낼수 있다</p>
</li>
<li><p>함수 타입 표시하는 방법</p>
<ul>
<li>(파라미터의 자료형1, 파리미터의 자료형2) -&gt; 결과의 자료형<pre><code class="language-kotlin">fun function2 (function : (Int, Int) -&gt; Int) {
  함수내용
}</code></pre>
</li>
</ul>
</li>
<li><p>고차함수를 호출하는 방법</p>
<ul>
<li><p>function1(100, 100) -&gt; 일반적인 함수 호출 방법</p>
</li>
<li><p>function2(::function1) // ::함수이름 으로 함수를 파라미터로 받을수 있다</p>
<pre><code class="language-kotlin">fun addTwoNumbers(number1 : Int, number2 : Int) : Int {
return number1 + number2
}

fun addTenNine(function : (Int, Int) -&gt; Int) {
val result : Int = function(10, 9)
println(&quot;결과는 ${result} 입니다&quot;)
}
addTenNine(::addTwoNumbers)</code></pre>
</li>
</ul>
</li>
</ul>
<hr>
<h3 id="람다lamda">람다(Lamda)</h3>
<ul>
<li>람다함수는 그 자체로 고차함수 이기 때문에 별도의 연산자 없이 변수에 담을수 있다</li>
<li>람다함수에서는 return을 사용할수 없고 마지막라인이 리턴된다</li>
</ul>
<hr>
<ol>
<li>풀 버젼</li>
</ol>
<ul>
<li>val function3 : (String) -&gt; Unit = { str : String -&gt; 함수내용 } // String변수를 파라미터로 받아와 Unit형태로 반환하는 함수를 타입으로 가져옴<pre><code class="language-kotlin">val addTenNine2 : (Int, Int) -&gt; Int = { number1 : Int, number2 : Int -&gt;
  // return number1 + number2 // 람다 안에서는 return을 실행할수 없다
  number1 + number2
}
addTenNine(addTenNine2) // 람다함수를 인자로 사용하는 경우에는 ::을 사용할 필요가 없다</code></pre>
</li>
</ul>
<ol start="2">
<li>축약(생략) 버젼<pre><code class="language-kotlin">// 생략버젼 1
val addTenNine3 : (Int, Int) -&gt; Int = { number1, number2 -&gt;
 number1 + number2
}
addTenNine(addTenNine3)
</code></pre>
</li>
</ol>
<p>// 생략버젼 2
val addTenNine4 = { number1 : Int, number2 : Int -&gt;
    number1 + number2
}
addTenNine(addTenNine4)</p>
<p>// 너무 간단한 경우
addTenNine {number1, number2 -&gt; number1 + number2} // Int형인걸 addTenNine 함수가 이미 알고있어서 생략가능</p>
<pre><code>
3. 파라미터가 없는 람다
```kotlin
// 파라미터가 없는 람다 함수
val addTenNine5 : () -&gt; Int = {
    10 + 9
}</code></pre><ol start="4">
<li>파리미터가 한개인 경우라면 it을 사용한다<pre><code class="language-kotlin">val function6 : (String) -&gt; Unit = { println(it) }</code></pre>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[12_Kotlin_출력]]></title>
            <link>https://velog.io/@cjsghkd-35/12Kotlin%EC%B6%9C%EB%A0%A5</link>
            <guid>https://velog.io/@cjsghkd-35/12Kotlin%EC%B6%9C%EB%A0%A5</guid>
            <pubDate>Wed, 10 May 2023 16:02:42 GMT</pubDate>
            <description><![CDATA[<h3 id="문자열-출력하는-방법">문자열 출력하는 방법</h3>
<ul>
<li><p>문자열을 직접 넣어주는 방법</p>
<pre><code class="language-kotlin">println(&quot;안녕하세요&quot;)</code></pre>
</li>
<li><p>변수를 출력하는 방법 ($변수)</p>
<pre><code class="language-kotlin">val a = &quot;녕&quot;
println(&quot;안$a하세요&quot;)

val name = &quot;이름&quot;
val myName = &quot;홍길동&quot;
println(&quot;내 ${name}은 ${myName} 입니다&quot;)

val number1 = 10
val number2 = 100
println(&quot;${number1} 더하기 ${number2} 은 ${number1 + number2}&quot;)</code></pre>
</li>
<li><p>특수문자를 출력하는 방법</p>
<ul>
<li>\ 사용<pre><code class="language-kotlin">println(&quot;\&quot;안녕하세요&quot;&quot;)
println(&quot;\$myName&quot;)</code></pre>
</li>
<li>${} 사용<pre><code class="language-kotlin">println(&quot;${&quot;}안녕하세요${&quot;}&quot;)
println(&quot;${&quot;myName&quot;}&quot;)
println(&quot;&quot; + number1 + &quot; 더하기 &quot; + number2 + &quot; 은 &quot; + &quot;${number1 + number2}&quot;)</code></pre>
</li>
</ul>
<hr>
<h3 id="주의사항">주의사항</h3>
<pre><code class="language-kotlin">println(&quot;안녕하세요&quot; + 10) // 문자열 + 다른 타입 -&gt; 문자열
// println(10 + &quot;안녕하세요&quot;) // 다른 타입 + 문자열 -&gt; 에러</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Hi-v2] - 2_기초 세팅하기]]></title>
            <link>https://velog.io/@cjsghkd-35/Hi-v2-2%EA%B8%B0%EC%B4%88-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cjsghkd-35/Hi-v2-2%EA%B8%B0%EC%B4%88-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 10 May 2023 15:58:16 GMT</pubDate>
            <description><![CDATA[<h3 id="소개">소개</h3>
<p>MSG라는 교내 동아리에서 Hi-v2(홈베이스 관리 시스템)을 만드면서 일어났던 일을 정리한 내용입니다.</p>
<hr>
<h3 id="작업내용">작업내용</h3>
<ul>
<li>Kotlin-DSL + buildSrc 적용하기</li>
<li>멀티모듈을 사용해서 패키징하기</li>
</ul>
<hr>
<h3 id="주요-코드">주요 코드</h3>
<ul>
<li>Dependency.kt</li>
</ul>
<pre><code class="language-kotlin">class Dependency {
    object AndroidX {
        const val CORE_KTX = &quot;androidx.core:core-ktx:${Versions.CORE_KTX}&quot;
        const val LIFECYCLE = &quot;androidx.lifecycle:lifecycle-runtime-ktx:${Versions.LIFECYCLE}&quot;
        const val APPCOMPAT = &quot;androidx.appcompat:appcompat:${Versions.APPCOMPAT}&quot;
    }

    object Compose {
        const val ACTIVITY_COMPOSE = &quot;androidx.activity:activity-compose:${Versions.ACTIVITY_COMPOSE}&quot;
        const val COMPOSE = &quot;androidx.compose.ui:ui:${Versions.COMPOSE}&quot;
        const val COMPOSE_PREVIEW = &quot;androidx.compose.ui:ui-tooling-preview:${Versions.COMPOSE}&quot;
        const val COMPOSE_MATERIAL = &quot;androidx.compose.material:material:${Versions.COMPOSE}&quot;
        const val COMPOSE_MATERIAL3 = &quot;androidx.compose.material3:material3:${Versions.MATERIAL3_COMPOSE}&quot;
        const val COMPOSE_TOOLING = &quot;androidx.compose.ui:ui-tooling:${Versions.COMPOSE}&quot;
    }

    object Test {
        const val JUNIT = &quot;junit:junit:${Versions.JUNIT}&quot;
        const val ANDROID_JUNIT = &quot;androidx.test.ext:junit:${Versions.ANDROID_JUNIT}&quot;
        const val ESPRESSO = &quot;androidx.test.espresso:espresso-core:${Versions.ESPRESSO}&quot;
        const val COMPOSE_JUNIT = &quot;androidx.compose.ui:ui-test-junit4:${Versions.COMPOSE}&quot;
        const val COMPOSE_MANIFEST = &quot;androidx.compose.ui:ui-test-manifest:${Versions.COMPOSE}&quot;
    }

    object Google {
        const val MATERIAL = &quot;com.google.android.material:material:${Versions.GOOGLE_MATERIAL}&quot;
    }
}</code></pre>
<ul>
<li><p>ProjectProperties.kt</p>
<pre><code class="language-kotlin">object ProjectProperties {
  object Gradle {
      const val APPLICATION = &quot;com.android.application&quot;
      const val LIBRARY = &quot;com.android.library&quot;
      const val KOTLIN = &quot;org.jetbrains.kotlin.android&quot;
      const val KTLINT = &quot;org.jlleitschuh.gradle.ktlint&quot;
  }
  object Test {
      const val TEST_RUNNER = &quot;androidx.test.runner.AndroidJUnitRunner&quot;
  }

  object Id {
      const val APPLICATION_ID = &quot;team.msg.hi_v2&quot;
  }

  object Files {
      const val CONSUMER_PROGUARDFILES = &quot;consumer-rules.pro&quot;
      const val DEFAULT_PROGUARDFILES = &quot;proguard-android-optimize.txt&quot;
      const val PROGUARDFILES = &quot;proguard-rules.pro&quot;
  }

  object Versions {
      const val COMPILE_SDK = 33
      const val MIN_SDK = 24
      const val TARGET_SDK = 33
      const val JVM_TARGET = &quot;1.8&quot;
      const val VERSION_CODE = 1
      const val VERSION_NAME = &quot;1.0&quot;
      val JAVA_VERSION = JavaVersion.VERSION_1_8
  }

  object NameSpace {
      const val PRESENTATION = &quot;team.msg.presentation&quot;
      const val DOMAIN = &quot;team.msg.domain&quot;
      const val DATA = &quot;team.msg.data&quot;
      const val APP = &quot;team.msg.hi_v2&quot;
  }

  object Action {
      const val EXCLUDES = &quot;/META-INF/{AL2.0,LGPL2.1}&quot;
  }
}</code></pre>
</li>
<li><p>Versions.kt</p>
<pre><code class="language-kotlin">object Versions {
  const val GRADLE = &quot;7.4.2&quot;
  const val KOTLIN = &quot;1.8.10&quot;
  const val KTLINT = &quot;11.3.2&quot;

  const val COMPOSE = &quot;1.4.3&quot;
  const val ACTIVITY_COMPOSE = &quot;1.5.1&quot;
  const val MATERIAL3_COMPOSE = &quot;1.0.1&quot;

  const val CORE_KTX = &quot;1.8.0&quot;
  const val LIFECYCLE = &quot;2.3.1&quot;
  const val APPCOMPAT = &quot;1.4.1&quot;

  const val JUNIT = &quot;4.13.2&quot;
  const val ANDROID_JUNIT = &quot;1.1.5&quot;
  const val ESPRESSO = &quot;3.5.1&quot;

  const val GOOGLE_MATERIAL = &quot;1.5.0&quot;
}</code></pre>
</li>
</ul>
<hr>
<h3 id="적용-중-일어났던-에러">적용 중 일어났던 에러</h3>
<ul>
<li>File must end with a newline 에러<ul>
<li>파일이 끝날 때 한 줄을 공백으로 추가하였다.<pre><code class="language-kotlin">plugins {
id(ProjectProperties.Gradle.LIBRARY)
id(ProjectProperties.Gradle.KOTLIN)
}
</code></pre>
</li>
</ul>
</li>
</ul>
<p>android {
    namespace = ProjectProperties.NameSpace.DOMAIN
    compileSdk = ProjectProperties.Versions.COMPILE_SDK</p>
<pre><code>defaultConfig {
    minSdk = ProjectProperties.Versions.MIN_SDK
    testInstrumentationRunner = ProjectProperties.Test.TEST_RUNNER
    consumerProguardFiles(ProjectProperties.Files.CONSUMER_PROGUARDFILES)
}

buildTypes {
    release {
        isMinifyEnabled = false
        proguardFiles(
            getDefaultProguardFile(ProjectProperties.Files.DEFAULT_PROGUARDFILES),
            ProjectProperties.Files.PROGUARDFILES
        )
    }
}
compileOptions {
    sourceCompatibility = ProjectProperties.Versions.JAVA_VERSION
    targetCompatibility = ProjectProperties.Versions.JAVA_VERSION
}
kotlinOptions {
    jvmTarget = ProjectProperties.Versions.JVM_TARGET
}</code></pre><p>}
// 공백인 줄 한줄 추가</p>
<p>```</p>
<hr>
<p><a href="https://github.com/GSM-MSG">MSG 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/Hi-v2-Android">Hi-v2 Android 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/Hi-v2-Android/pull/4">작업한 PR</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Hi-v2] - 1_CI 세팅하기]]></title>
            <link>https://velog.io/@cjsghkd-35/Hi-v2-1CI-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cjsghkd-35/Hi-v2-1CI-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 09 May 2023 00:35:38 GMT</pubDate>
            <description><![CDATA[<h3 id="소개">소개</h3>
<p>MSG라는 교내 동아리에서 Hi-v2(홈베이스 관리 시스템)을 만드면서 일어났던 일을 정리한 내용입니다.</p>
<hr>
<h3 id="작업내용">작업내용</h3>
<ul>
<li>깃허브 액션을 사용하여 CI 환경 구축하기</li>
</ul>
<hr>
<h3 id="주요코드">주요코드</h3>
<ul>
<li>android.yml<pre><code class="language-kotlin">name: Android CI
</code></pre>
</li>
</ul>
<p>on:
  push:
    branches: [ &quot;master&quot;, &quot;develop&quot; ]
  pull_request:
    branches: [ &quot;master&quot;, &quot;develop&quot; ]</p>
<p>jobs:
  build:</p>
<pre><code>runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: set up JDK 11
  uses: actions/setup-java@v3
  with:
    java-version: &#39;11&#39;
    distribution: &#39;temurin&#39;
    cache: gradle

- name: Cache Gradle Packages
  uses: actions/cache@v2
  with:
      path: |
        ~/.gradle/caches
        ~/.gradle/wrapper
      key: ${{runner.os}}-gradle-${{hashFiles(&#39;**/*.gradle*&#39;, &#39;**/gradle-wrapper.properties&#39;)}}
      restore-keys: |
        ${{runner.os}}-gradle-  
- name: Grant execute permission for gradlew
  run: chmod +x gradlew

- name: Run ktlint
  run: ./gradlew ktlintCheck

- name: Build with Gradle
  run: ./gradlew build</code></pre><pre><code>
---

### 적용 중 일어났던 에러
- ktlint 에러
   - 버전 에러가 일어나서 버전을 수정해주었다. ( 8.0.1 -&gt; 7.4.2 )
```kotlin
plugins {
    id &#39;com.android.application&#39; version &#39;7.4.2&#39; apply false
    id &#39;com.android.library&#39; version &#39;7.4.2&#39; apply false
    id &#39;org.jetbrains.kotlin.android&#39; version &#39;1.7.20&#39; apply false
    id &#39;org.jlleitschuh.gradle.ktlint&#39; version &#39;11.3.2&#39;
}</code></pre><hr>
<p><a href="https://github.com/GSM-MSG">MSG 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/Hi-v2-Android">Hi-v2 Android 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/Hi-v2-Android/pull/2">작업한 PR</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[11_Kotlin_예외처리]]></title>
            <link>https://velog.io/@cjsghkd-35/11Kotlin%EC%98%88%EC%99%B8%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@cjsghkd-35/11Kotlin%EC%98%88%EC%99%B8%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Wed, 03 May 2023 15:05:56 GMT</pubDate>
            <description><![CDATA[<h3 id="예외처리">예외처리</h3>
<ul>
<li>예외가 발생하는 부분 -&gt; try{}</li>
<li>예외를 처리하는 부분 -&gt; catch{}</li>
</ul>
<hr>
<pre><code class="language-kotlin">try {
    코드 -&gt; 예외발생 가능한 코드
} catch(변수명 : 예외타입A) {
    예외를 처리하는 코드
} catch(변수명 : 예외타입B) {
    예외를 처리하는 코드
} finally { // finally는 꼭 안써줘도 된다
    예외가 발생하여도 무조건 실행되어야 할 코드
}</code></pre>
<ul>
<li>try문에서 A라는 예외가 발생하면 catch문에서 A라는 예외를 처리하겠다고 명시적으로 적어줘야한다 그렇지않으면 오류가 발생한다</li>
<li>모든 종류의 예외를 포함하는 예외타입 -&gt; Exception</li>
<li>try, catch는 독립적으로 사용할수 없다 (둘이 같이 써줘야한다)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[10_Kotlin_반복문]]></title>
            <link>https://velog.io/@cjsghkd-35/10Kotlin%EB%B0%98%EB%B3%B5%EB%AC%B8</link>
            <guid>https://velog.io/@cjsghkd-35/10Kotlin%EB%B0%98%EB%B3%B5%EB%AC%B8</guid>
            <pubDate>Mon, 01 May 2023 15:36:33 GMT</pubDate>
            <description><![CDATA[<h3 id="for-문">for 문</h3>
<ul>
<li>기본 format<pre><code class="language-kotlin">  for(변수명 in 범위){
        반복문 내용
  }</code></pre>
</li>
</ul>
<hr>
<h3 id="while">While</h3>
<ul>
<li>기본 format<pre><code class="language-kotlin">  While(조건) {
      반복문 내용
  }</code></pre>
</li>
<li>조건을 만족하는 동안 본문(내용)을 반복한다</li>
</ul>
<hr>
<h3 id="dowhile">Do/While</h3>
<ul>
<li>기본 format<pre><code class="language-kotlin">  do {
      반목문 내용
  } while(조건)</code></pre>
</li>
<li>조건을 만족하지 못하더라도 최소 한번은 무조건 실행한다</li>
</ul>
<hr>
<h3 id="키워드">키워드</h3>
<pre><code class="language-kotlin">fun abe() {
    for (i in range(1..10) { // i 반복문
        for (j in range(1..10) { // j 반복문
            반복문 내용 1
            키워드 (break, continue, return)
            반복문 내용 2 
        }
    }
}</code></pre>
<h4 id="break">break</h4>
<ul>
<li>반복문 실행중에 가장 가까운 루프를 탈출 // i 반복문으로 탈출<h4 id="continue">continue</h4>
</li>
<li>반복문 실행중에 가장 가까운 루프의 시작점으로 탈출 // j 반복문으로 탈출<h4 id="return">return</h4>
</li>
<li>반복문 실행중에 가장 가까운 함수를 탈출 // abe 함수로 탈출<h4 id="label">label</h4>
</li>
<li>위 3가지 키워드들의 탈출지점을 정해준다 -&gt; (가장 가까운 대신 -&gt; 라벨로 설정한)</li>
<li>라벨로 설정할 수 있어야 하고, 설정한 라벨을 명시할 수 있어야 된다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[GCMS] - 자동 로그인 로직]]></title>
            <link>https://velog.io/@cjsghkd-35/GCMS-%EC%9E%90%EB%8F%99-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EB%A1%9C%EC%A7%81</link>
            <guid>https://velog.io/@cjsghkd-35/GCMS-%EC%9E%90%EB%8F%99-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EB%A1%9C%EC%A7%81</guid>
            <pubDate>Mon, 01 May 2023 15:26:05 GMT</pubDate>
            <description><![CDATA[<h3 id="소개">소개</h3>
<h4 id="msg라는-교내-동아리에서-만든-gcms교내-동아리-관리-시스템을-유지보수-하면서-일어났던-일을-정리한-내용입니다">MSG라는 교내 동아리에서 만든 GCMS(교내 동아리 관리 시스템)을 유지보수 하면서 일어났던 일을 정리한 내용입니다.</h4>
<hr>
<h3 id="문제상황">문제상황</h3>
<p>수정하기 전 자동 로그인 로직은 accessToken이 만료된다면 로그인을 다시 해서 토큰을 갱신시켜줬어야했다.</p>
<hr>
<h3 id="작업내용">작업내용</h3>
<ul>
<li><p>만약 accessToken이 만료된다면 accessToken을 재발급받아서 로그인을 다시 할 필요없게 만들어줬다.</p>
</li>
<li><p>token을 받아서 바로 요청보내면 400(Bad Request)가 발생하여 JSONObject에 담아서 보내줬다.</p>
</li>
</ul>
<hr>
<h3 id="주요코드">주요코드</h3>
<ul>
<li>accessToken 재발급 코드<pre><code class="language-kotlin">val reAccessToken = authDataStorage.getAccessToken()
              val reAccessRequest = chain.request()
                  .newBuilder()
                  .addHeader(&quot;Authorization&quot;, &quot;Bearer $reAccessToken&quot;)
                  .build()
              return chain.proceed(reAccessRequest)</code></pre>
</li>
<li>RefreshRequest.toRequestBody() 로직 변경<ul>
<li>JSONObject에 넣어준 이유는 body를 JSON 형식으로 보내기 위해서이다.<pre><code class="language-kotlin">fun RefreshRequest.toRequestBody() =
JSONObject().apply {
    put(&quot;token&quot;, this@toRequestBody.token)
}.toString().toRequestBody(&quot;application/json&quot;.toMediaTypeOrNull())</code></pre>
</li>
</ul>
</li>
</ul>
<hr>
<p><a href="https://github.com/GSM-MSG">MSG 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/GCMS-Android">GCMS-Android 깃허브</a></p>
<p><a href="https://github.com/GSM-MSG/GCMS-Android/pull/422">작업한 PR</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[09_Kotlin_Iterable]]></title>
            <link>https://velog.io/@cjsghkd-35/09KotlinIterable</link>
            <guid>https://velog.io/@cjsghkd-35/09KotlinIterable</guid>
            <pubDate>Fri, 21 Apr 2023 18:02:05 GMT</pubDate>
            <description><![CDATA[<h3 id="iterable">Iterable</h3>
<ul>
<li>아이터러블, 이터러블</li>
<li>반복이 가능하다 -&gt; 시작과 끝이 있다 -&gt; 범위가 있다</li>
</ul>
<hr>
<ul>
<li>Collection<ul>
<li>listOf</li>
<li>setOf</li>
<li>mapOf</li>
<li>mutableListOf</li>
<li>(1, 2, 3, 4)</li>
<li>(1)</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>Array<ul>
<li>(1, 2, 3, 4)</li>
<li>(1)</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>Progression<ul>
<li>시작점과 끝점이 있고, 범위를 정할 수 있다</li>
<li>구간<ul>
<li>구간 1 : 반복을 할 때 1씩 이동한다</li>
<li>구간 1 : range</li>
</ul>
</li>
<li>1..10 step 2 (1, 3, 5, 7, 9)</li>
<li>10 downTo 1 step 2 (10, 8, 6, 4, 2)</li>
<li>(1..10).reversed() // 10부터 1까지</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>Range<ul>
<li>구간이 1인인 Progression</li>
<li>1..10 -&gt; 1부터 10까지</li>
<li>1.rangeTo(10) -&gt; 1부터 10까지</li>
<li>1 until 10 -&gt; 1부터 9까지</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>닫힌구간/열린구간<ul>
<li>닫힌구간 : 해당 시작점/끝점을 포함</li>
<li>열린구간 : 해당 시작점/끝점을 제외</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Glide]]></title>
            <link>https://velog.io/@cjsghkd-35/Glide</link>
            <guid>https://velog.io/@cjsghkd-35/Glide</guid>
            <pubDate>Thu, 20 Apr 2023 15:46:24 GMT</pubDate>
            <description><![CDATA[<h4 id="glide에-대해-정리한-내용입니다">Glide에 대해 정리한 내용입니다.</h4>
<hr>
<h3 id="glide">Glide?</h3>
<p>글라이드는 구글에서 제작한 이미지 로드 라이브러리들중 하나입니다.
글라이드는 이미지 로드 라이브러리들 중에서도 가장 많이 사용합니다.</p>
<hr>
<h3 id="glide-장점">Glide 장점?</h3>
<ul>
<li>이미지를 다운받을 때 작은 사이즈로 받아 용량이 적다.</li>
<li>사용법이 간단하다.</li>
<li>확장성이 좋다.</li>
<li>섬네일을 지원한다.</li>
</ul>
<hr>
<h3 id="glide-메서드">Glide 메서드</h3>
<ul>
<li>with()<ul>
<li>View, Activity, Fragment 등에서 Context를 가져온다.</li>
</ul>
</li>
<li>load()<ul>
<li>로드할 이미지를 선택한다.</li>
</ul>
</li>
<li>placeholder()<ul>
<li>이미지가 로드될 때 동안 대신할 이미지를 선택한다.</li>
</ul>
</li>
<li>error()<ul>
<li>이미지 로드가 실패했을 때 대신할 이미지를 선택한다.</li>
</ul>
</li>
<li>centerCrop()<ul>
<li>imageView 크기에 맞춰 이미지 중간부분을 잘라 보여준다.</li>
</ul>
</li>
<li>override()<ul>
<li>이미지 사이즈를 선택한다.</li>
</ul>
</li>
<li>fallback()<ul>
<li>로드할 이미지가 없을 때, 즉 널일 때 보여줄 이미지를 선택한다.</li>
</ul>
</li>
<li>thumbnail()<ul>
<li>이미지가 너무 클 때 점차 선명해지는 이미지를 선택한다.</li>
</ul>
</li>
<li>asGif()<ul>
<li>.gif 이미지를 보여준다.</li>
</ul>
</li>
</ul>
<hr>
<p>Glide에 대해 정리해봤습니다.
틀린 부분이 있다면 말해주세요!</p>
<hr>
<p><a href="https://velog.io/@krrong/Android-Glide-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0">참고한 블로그 1</a></p>
<p><a href="https://velog.io/@hhb041127/Glide-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0">참고한 블로그 2</a></p>
<p><a href="https://hanyeop.tistory.com/135">참고한 블로그 3</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[08_Kotlin_Collection]]></title>
            <link>https://velog.io/@cjsghkd-35/08KotlinCollection</link>
            <guid>https://velog.io/@cjsghkd-35/08KotlinCollection</guid>
            <pubDate>Thu, 20 Apr 2023 15:21:00 GMT</pubDate>
            <description><![CDATA[<h3 id="콜렉션-collection">콜렉션 (Collection)</h3>
<hr>
<h4 id="mutable-immutable">mutable, Immutable</h4>
<ul>
<li><p>콜렉션은 전부다 크기가 고정되어 있지 않다</p>
</li>
<li><p>기본적으로 불변한 immutable를 사용하는 것이 좋다</p>
</li>
<li><p>변경가능 여부</p>
<ul>
<li>Mutable -&gt; 변경가능</li>
<li>Immutable -&gt; 불변</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>List<ul>
<li>Immutable<ul>
<li>형태<ul>
<li>listOf&lt;자료형&gt;(값1, 값2, 값3)</li>
<li>val numbers = lisfOf<Int>(1, 2, 3)</li>
</ul>
</li>
</ul>
</li>
<li>Mutable<ul>
<li>형태<ul>
<li>mutableListOf&lt;자료형&gt;(값1, 값2, 값3)</li>
<li>val numbers = mutableListOf<Int>(1, 2, 3)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>Set<ul>
<li>집합 -&gt; 똑같은 값을 허락하지 않는다</li>
<li>immutable<ul>
<li>형태<ul>
<li>setOf&lt;자료형&gt;(값1, 값2, 값3, 값1, 값1) -&gt; setOf&lt;자료형&gt; (값1, 값2, 값3) // 중복 제거</li>
</ul>
</li>
</ul>
</li>
<li>mutable<ul>
<li>형태<ul>
<li>mutableSetOf&lt;자료형&gt; (값1, 값2, 값3)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>Map<ul>
<li>키-벨류 (key-value) -&gt; 저장 방식</li>
<li>immutable<ul>
<li>형태<ul>
<li>mapOf&lt;자료형1,자료형2&gt;(키1 to 벨류1, 키2 to 벨류2 ...)</li>
<li>var numbers = mapOf&lt;Int, String&gt;(1 to &quot;일&quot;, 2 to &quot;이&quot;)</li>
</ul>
</li>
</ul>
</li>
<li>mutable<ul>
<li>형태<ul>
<li>mutableMapOf&lt;자료형1,자료형2&gt;(키1 to 벨류1, 키2 to 벨류2 ...)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[07_Kotlin_배열]]></title>
            <link>https://velog.io/@cjsghkd-35/07Kotlin%EB%B0%B0%EC%97%B4</link>
            <guid>https://velog.io/@cjsghkd-35/07Kotlin%EB%B0%B0%EC%97%B4</guid>
            <pubDate>Wed, 19 Apr 2023 15:00:47 GMT</pubDate>
            <description><![CDATA[<h3 id="배열">배열</h3>
<hr>
<ul>
<li>특정 하나의 변수에 복수개의 값을 할당하고 싶은 경우
var number : Int = 10 -&gt; 10이라는 값이 number라는 변수에 할당이 된다
var exam_scores : Int = 100, 98, 75</li>
<li>배열은 저장될 수 있는 값의 갯수를 정해놓아야하고, 이 갯수는 변경할 수 없다</li>
</ul>
<hr>
<h4 id="1-배열을-선언하는-방법-1">1. 배열을 선언하는 방법 (1)</h4>
<ul>
<li><p>arrayOf&lt;자료형/생략&gt;(값1, 값2, 값3)</p>
<ul>
<li>생략했을 경우 복수개의 자료형이 배열의 인자로 올수 있다</li>
<li>var array1 = arrayOf(true, false, &quot;안녕하세요&quot;, 10, 2.2)</li>
</ul>
</li>
<li><p>자료형을 적어 줬을 경우, 해당 자료형만 인자로 들어올 수 있다</p>
<ul>
<li>var array2 = arrayOf&lt;자료형&gt;(10, 20, 30)</li>
<li>var array3 = arrayOf&lt;자료형&gt;(2.2, 4.5)</li>
</ul>
</li>
<li><p>&lt;자료형&gt; -&gt; 대체할수 있는 방법</p>
<ul>
<li>var array4 = intArrayOf(1, 2, 3, 4, 5)</li>
<li>var array5 = booleanArrayOf(true, false, true)</li>
</ul>
</li>
<li><p>null을 인자로 받는 배열 // 거의 사용하지 않음</p>
<ul>
<li>var nulls = arrayOfNull<Int>(4)</li>
</ul>
<hr>
</li>
</ul>
<h4 id="2-배열을-선언하는-방법-2--잘-사용하지-않는다-string-배열-불가능">2. 배열을 선언하는 방법 (2) // 잘 사용하지 않는다 (String 배열 불가능)</h4>
<ul>
<li><p>자료형/생략Array(크기, {값 / 생략가능})</p>
<ul>
<li>var array6 = Array(10, {0}) -&gt; 10칸짜리 배열을 만들고 기본값으로 0을 넣어준다</li>
</ul>
</li>
<li><p>자료형 명시</p>
<ul>
<li>var array7 = IntArray(10, {0})</li>
<li>var array8 = DoubleArray(10, {0})</li>
<li>var array9 = StringArray(10, {&quot;Hi&quot;}) -&gt; 사용 불가능 -&gt; 지금은 몰라도 된다</li>
</ul>
<hr>
</li>
</ul>
<h4 id="3-배열을-선언하는-방법-3">3. 배열을 선언하는 방법 (3)</h4>
<ul>
<li><p>Array&lt;자료형/생략가능&gt;(크기, {값/생략가능})</p>
<ul>
<li>var array10 = Array(10, {0}) -&gt; 생략을 했을 경우에는 디폴트 값의 자료형으로 정해진다</li>
<li>var array11 = Array&lt;자료형&gt;(10, {0})</li>
<li>var array12 = Array&lt;자료형&gt;(10, {&quot;Hi&quot;})</li>
</ul>
<hr>
</li>
</ul>
<h4 id="4-배열애-값을-넣는-방법">4. 배열애 값을 넣는 방법</h4>
<ul>
<li><p>1번 방법 -&gt; 배열명[index] = 값</p>
<ul>
<li>array12[2] = 100</li>
<li>array[0] = 1</li>
</ul>
</li>
<li><p>2번 방법 -&gt; 배열명.set(index, 값)</p>
<ul>
<li>array12.set(2, 100)</li>
<li>array12.set(0, 1)</li>
</ul>
<hr>
</li>
</ul>
<h4 id="5-배열에-있는-값을-가져오는-방법">5. 배열에 있는 값을 가져오는 방법</h4>
<ul>
<li>배열명[index]<ul>
<li>val value = array12[3]</li>
</ul>
</li>
<li>배열명.get(index)<ul>
<li>val value2 = array12.get(0)</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[06_Kotlin_판단문]]></title>
            <link>https://velog.io/@cjsghkd-35/06Kotlin%ED%8C%90%EB%8B%A8%EB%AC%B8</link>
            <guid>https://velog.io/@cjsghkd-35/06Kotlin%ED%8C%90%EB%8B%A8%EB%AC%B8</guid>
            <pubDate>Tue, 18 Apr 2023 12:10:45 GMT</pubDate>
            <description><![CDATA[<h3 id="판단문">판단문</h3>
<hr>
<p>흐름제어</p>
<p>if (만약에)</p>
<ul>
<li>만약에 ~라면 A를 해라
if (A) </li>
<li>만약에 ~라면 A를 하고 만약에 B라면 B을 해라
if (A) / else if (B)</li>
<li>만약에 ~라면 A를 하고 만약에 B라면 B을 그리고 나머지 경우에는 C를 해라
  if (A) / else if (B) / else (C)</li>
</ul>
<hr>
<h3 id="if">if</h3>
<p>if (num == 5) { // 조건 -&gt; 숫자 5라면
    동작1
} else if (num == 10) { // 조건 -&gt; 숫자 10이라면
    동작2
} else { // 조건 -&gt; 나머지
    동작3
}</p>
<ul>
<li>else if 는 여러개 올 수 있다</li>
<li>if 와 else는 1개만 쓸 수 있다</li>
<li>else 와 else if 는 필요하지 않으면 사용하지 않을 수 있다</li>
</ul>
<hr>
<h3 id="when">when</h3>
<p>when (num) { // &quot;안녕하세요&quot;
    10 -&gt; 동작1 // num이 10 이면 동작1 실행
    20 -&gt; 동작2 // num이 20 이면 동작2 실행
    else -&gt; 동작3 // 나머지는 동작3 실행
}</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[05_Kotlin_메소드]]></title>
            <link>https://velog.io/@cjsghkd-35/05Kotlin%EB%A9%94%EC%86%8C%EB%93%9C</link>
            <guid>https://velog.io/@cjsghkd-35/05Kotlin%EB%A9%94%EC%86%8C%EB%93%9C</guid>
            <pubDate>Mon, 17 Apr 2023 16:14:53 GMT</pubDate>
            <description><![CDATA[<h3 id="메소드">메소드</h3>
<hr>
<p>메소드 = 함수 = function
변수 = 파라미터(parameter) = 인자</p>
<hr>
<ul>
<li>함수란?<ul>
<li>공장</li>
<li>재료를 넣어주면 완제품이 나온다</li>
<li>어떤 재료를 넣어줘야 하나?, 완제품은 무엇인가?</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>기본형
fun 함수명(변수명:타입, 변수명:타입, ...):반환형 {
  함수내용
  함수내용
  ...
  return 반환값
}</li>
</ul>
<hr>
<ul>
<li>기본값이 있는 함수 // 변수에 기본값 (변수 모두에 넣을 필요는 없다)
fun 함수명(변수명:타입 = 기본값, 변수명:타입, ...):반환형 {
  함수내용
  함수내용
  ...
  return 반환값
}</li>
</ul>
<hr>
<ul>
<li>반환값이 없는 함수
fun 함수명(변수명:타입, 변수명:타입, ...):Unit {
  함수내용
  함수내용
  ...
}
fun 함수명(변수명:타입, 변수명:타입, ...) {
  함수내용
  함수내용
  ...
}</li>
</ul>
<hr>
<ul>
<li>간단하게 선언하는 방법
fun 함수명(변수명:타입, ...) = 함수내용</li>
</ul>
<hr>
<ul>
<li>가변인자를 갖는 함수
fun 함수명(vararg 변수명:타입):반환형  {
  variable argument
  함수내용
  함수내용
  ...
  return 반환값
}</li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[04_Kotlin_연산자]]></title>
            <link>https://velog.io/@cjsghkd-35/04Kotlin%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@cjsghkd-35/04Kotlin%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Fri, 14 Apr 2023 01:20:13 GMT</pubDate>
            <description><![CDATA[<h3 id="연산자">연산자</h3>
<hr>
<ol>
<li>산술연산자
=&gt; +, -, *, /, %</li>
</ol>
<ul>
<li>%<ul>
<li>나머지를 반환</li>
<li>ex&gt; 5 % 2 -&gt; 1</li>
</ul>
</li>
</ul>
<hr>
<ol start="2">
<li>대입연산자 ( = )</li>
</ol>
<ul>
<li>A = B -&gt; B가 A에 할당된다</li>
<li>X = 2 -&gt; 2가 X에 할당된다<ul>
<li>우변에 있는 것이 좌변에 할당된다</li>
</ul>
</li>
</ul>
<hr>
<ol start="3">
<li>복합대입연산자 (산술연산자 + 대입연산자)</li>
</ol>
<ul>
<li>+=, -=, **=, /=, %=<ul>
<li>A += B -&gt; A = A+B</li>
<li>A /= B -&gt; A = A/B</li>
</ul>
</li>
</ul>
<hr>
<ol start="4">
<li>증감연산자 (증가하거나 감소하는 연산자)</li>
</ol>
<ul>
<li>++, --<ul>
<li>A++, B-- : 값을 먼저 반환하고 증가한다</li>
<li>--A, ++B : 증감을 먼저하고 값을 반환한다.</li>
<li>5++ -&gt; 5</li>
<li>++5 -&gt; 6</li>
</ul>
</li>
</ul>
<ol start="5">
<li>비교연산자</li>
</ol>
<ul>
<li><p>=&gt; &gt;, &gt;=, &lt;, &lt;=</p>
<ul>
<li>A &gt; B</li>
<li>A &lt;= B</li>
</ul>
</li>
<li><p>==</p>
<ul>
<li>A == B</li>
<li>같은가?</li>
</ul>
</li>
<li><p>!=</p>
<ul>
<li>A != B</li>
<li>다른가?</li>
</ul>
</li>
<li><p>===</p>
<ul>
<li>A === B</li>
<li>객체가 같은가?</li>
</ul>
</li>
<li><p>!==</p>
<ul>
<li>A !== B</li>
<li>객체가 다른가?</li>
</ul>
</li>
<li><p>비교연산자의 결과는 항상 Boolean으로 나온다</p>
</li>
</ul>
<hr>
<ol start="6">
<li>논리연산자</li>
</ol>
<ul>
<li><p>논리연산자는 boolean을 대상으로만 연산할 수 있다
=&gt; &amp;&amp;, ||, !</p>
</li>
<li><p>&amp;&amp;</p>
<ul>
<li>A &amp;&amp; B -&gt; 둘다 true 이면 true이고 그렇지 않으면 false</li>
<li>And 조건</li>
</ul>
</li>
<li><p>||</p>
<ul>
<li>A || B -&gt; 둘중에 하나라도 true이면 true이고 그렇지 않으면 false</li>
<li>or 조건</li>
</ul>
</li>
<li><p>!</p>
<ul>
<li>참, 거짓 바꾸기</li>
<li>!A -&gt; A가 true 인 경우에는 false, A가 false인 경우에는 true가 된다.</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li><p>연산자 우선순위 ( 5 + 3 * 3 )</p>
<ul>
<li>더하기 -&gt; 나누기    X</li>
<li>나누기 -&gt; 더하기    O
5 + (3 / 3)
(5 + 5) / 3</li>
</ul>
</li>
<li><p>연산자 우선순위를 고려하지 않으면서 개발하는게 좋다면 괄호를 사용해야 한다</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[03_Kotlin_Null]]></title>
            <link>https://velog.io/@cjsghkd-35/03KotlinNull</link>
            <guid>https://velog.io/@cjsghkd-35/03KotlinNull</guid>
            <pubDate>Thu, 13 Apr 2023 15:00:18 GMT</pubDate>
            <description><![CDATA[<h3 id="null">Null?</h3>
<ul>
<li>상태를 모름, 존재하지 않음</li>
<li>0과는 다르다</li>
<li><blockquote>
<p>0 : 두루마리휴지에서 심지만 남은 상태, Null : 두루마리휴지가 없음</p>
</blockquote>
</li>
<li>Null을 대상으로는 연산을 할 수 없다 (+,-,*,/)<ul>
<li>Null + 3  = Null</li>
<li>비교연산은 가능하다</li>
</ul>
</li>
</ul>
<hr>
<h3 id="c--a--b">c = a + b</h3>
<p>위에 코드에서 발생할 수 있는 문제</p>
<ul>
<li><p>a or b 가 Null인 경우 에러 발생</p>
</li>
<li><p>더하기 연산을 하기 전에, a or b가 Null인지 확인</p>
</li>
</ul>
<hr>
<h3 id="nullsafety-null로-부터-안전해지자">NullSafety (Null로 부터 안전해지자)</h3>
<ul>
<li>코틀린의 가장 큰 특징중 하나</li>
</ul>
<h3 id="null의-필요성">Null의 필요성?</h3>
<ul>
<li>변수에 값 + 상태도 표현할 수 있다면 좋은거 아닌가?</li>
</ul>
<hr>
<h3 id="null을-표현-하는-방법">Null을 표현 하는 방법</h3>
<p>val/var 변수명 : 자료형? = 값</p>
<ul>
<li>Null은 값 자리에 들어 올수 있다.
  val/var 변수명 : 자료형? = null<ul>
<li>val number : Int? = null -&gt; null 가능</li>
<li>val number : Int = 10 -&gt; null 불가능</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Room]]></title>
            <link>https://velog.io/@cjsghkd-35/Room</link>
            <guid>https://velog.io/@cjsghkd-35/Room</guid>
            <pubDate>Thu, 13 Apr 2023 11:29:29 GMT</pubDate>
            <description><![CDATA[<p>Room에 대해 정리한 내용입니다.</p>
<hr>
<h3 id="room">Room?</h3>
<p>안드로이드에서 사용할 수 있는 로컬 데이터베이스들중 하나입니다.
룸은 SQLite를 더 쉽게 사용하기 위해 나온 ORM 라이브러리입니다.</p>
<hr>
<h3 id="room의-기본-구성요소">Room의 기본 구성요소?</h3>
<p><img src="https://velog.velcdn.com/images/cjsghkd-35/post/c4596ad2-0c8f-4201-874c-ef275ac369d2/image.png" alt=""></p>
<ol>
<li><p>Entity</p>
<ul>
<li>엔터티는 앱 데이터베이스의 테이블입니다.</li>
</ul>
</li>
<li><p>DAO</p>
<ul>
<li>앱이 데이터베이스의 데이터를 삽입, 삭제, 업데이트, 가져오기를 할 수 있는 메서드를 정의하는 클래스입니다.</li>
</ul>
</li>
<li><p>Database</p>
<ul>
<li>데이터베이스를 생성하고 관리하는 클래스입니다.</li>
</ul>
</li>
</ol>
<hr>
<h3 id="room의-장점">Room의 장점?</h3>
<ul>
<li><p>쿼리문을 잘 몰라도 로컬 데이터베이스를 사용할 수 있다.</p>
</li>
<li><p>SQL 쿼리의 컴파일 시간 확인할 수 있다.</p>
</li>
<li><p>SQLite API를 직접 사용할 때보다 코드가 간소해진다.</p>
</li>
</ul>
<hr>
<h3 id="room의-단점">Room의 단점?</h3>
<ul>
<li><p>간단한 데이터를 저장하기에는 다른 로컬 데이터베이스를 사용하는 방법이 적합하다. (다른 로컬 데이터베이스 사용하는 방법보다 코드가 길다)</p>
</li>
<li><p>복잡한 쿼리를 작성하는데는 어려움이 있을 수 있다.</p>
</li>
</ul>
<hr>
<h3 id="sqlite-api-보다-room">SQLite API 보다 Room</h3>
<ul>
<li><p>SQLite API를 직접 사용하면 컴파일 시간을 확인할 수 없다.</p>
</li>
<li><p>SQLite API를 직접 사용하면 SQL 쿼리와 데이터 객체 간에 변환하려면 많은 상용구 코드를 사용해야 합니다.</p>
</li>
</ul>
<hr>
<p>Room에 대해 정리해봤습니다.
틀린 부분이 있다면 말해주세요!</p>
<hr>
<p><a href="https://developer.android.com/training/data-storage/room?hl=ko">구글 공식 문서</a></p>
<p><a href="https://show-me-the-money.tistory.com/entry/Android-%EB%A1%9C%EC%BB%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-Room-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%B4%9D%EC%A0%95%EB%A6%AC">참고한 블로그</a></p>
]]></description>
        </item>
    </channel>
</rss>