<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>batsalee의 작은바지</title>
    <link>https://smallpants.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 14 Jul 2026 18:17:35 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>batsalee</managingEditor>
    <item>
      <title>WorkManager</title>
      <link>https://smallpants.tistory.com/335</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. WorkManager란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어플리케이션 프로세스가 현재 실행되는지와 상관없이 수행해야하는 백그라운드 작업을 처리하는 API&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 즉시 실행하지 않아도 괜찮지만, 언젠가는 꼭 실행되어야하는 작업에 사용&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 특징&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 실행 보장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 앱이 꺼지거나 시스템이 재시작되어도 설정된 작업이 취소되지 않고 나중에라도 반드시 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 조건부 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 와이파이가 연결됐을때만, 충전중일때만 같은 특정 조건 충족될때 작업이 시작하도록 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 체이닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 여러 작업을 순차적/병렬로 연결해서 복잡한 작업흐름을 만들 수 있음&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 구성 요소&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) Worker / CoroutineWorker&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 백그라운드 스레드에서 동기적으로 작업을 수행하는 클래스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- doWork() 함수 내에 할 일 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 비동기적으로 작업하고 싶다면 CoroutineWorker 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) WorkRequest&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 작업의 실행 조건 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- OneTimeWorkRequest : 한번만 실행되는 WorkRequest&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- PeriodicWorkRequest : 일정 주기로 반복 실행되는 WorkRequest&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) WorkManager&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- WorkRequest를 큐에 넣고 관리하는 클래스&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 주의사항&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주기적으로 수행해야 하는 작업을 맡기는 경우 간격을 적절히 둬야 함(최소 15분 이상)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) 원인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스마트폰을 사용하지 않으면 배터리 절약을 위해 Doze모드(절전모드)에 진입하는데 이 때 불필요하게 계속 기기가 깨어나게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 여러 앱의 백그라운드 작업을 모았다가 한꺼번에 처리하는 방식인데, 이렇게되면 네트워크 연결같은 동작을 한번 하고 작업을 몰아서 할 수 있지만 계속 작업을 하면 네트워크 연결같은 작업도 계속 반복해야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 내부적으로 API24의 JobScheduler를 사용하는데 JobScheduler가 15분보다 짧으면 실행 안하게 되어있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2) 15분보다 자주 실행하려면?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Foreground Service나 AlarmManger 활용&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 사용 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) Dependency 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 꼭 2.8.1 버전이어야 하는건 아니고 최신버전 나오면 바꿔도 됨&lt;/p&gt;
&lt;pre id=&quot;code_1783420610384&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;implementation(&quot;androidx.work:work-runtime-ktx:2.8.1&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) Worker 구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Worker 혹은 CoroutineWorker를 상속받고 doWork를 오버라이딩한다&lt;/p&gt;
&lt;pre id=&quot;code_1783421125156&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MyWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
    override suspend fun doWork(): Result {
    
    	// do something...
        
        return withContext(Dispatchers.IO) { // 코루틴을 어느 Dispatcher에게 맡길지
            return@withContext try {
                // do something...
                Result.success()
            } catch (throwable: Throwable) {
                Result.failure()
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) WorkManager 구현 및 WorkRequest&lt;/p&gt;
&lt;pre id=&quot;code_1783423085679&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private val workManager = WorkManager.getInstance(context)

fun enqueue() {
    val workerBuilder = OneTimeWorkRequestBuild&amp;lt;MyWorker&amp;gt;() // 한번만 실행하는 WorkRequest일 때
    val workerBuilder = PeriodicWorkRequestBuild&amp;lt;MyWorker&amp;gt;() // 일정 주기로 실행하는 WorkRequest일 때
    workManager.enqueue(workerBuilder.build())
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) 체이닝 사용 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CleanupWorker -&amp;gt; BlurWorker -&amp;gt; SaveImageToFileWorker순으로 체인을 만들어 실행함&lt;/p&gt;
&lt;pre id=&quot;code_1783424035059&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private val workManager = WorkManager.getInstance(context)

fun enqueue() {
    var continuation = workManager.beginWith(OneTimeWorkRequest.from(CleanupWorker::class.java))
    // continuation에는 WorkContinuation 객체가 들어가며 체인의 첫번째 작업 요청이 있는 WorkRequest 체인의 시작점이 된다.
    
    val blurBuilder = ~~
    continuation = continuation.then(blurBuilder.build())
    
    val save = OneTimeWorkRequestBuilder&amp;lt;SaveImageToFileWorker&amp;gt;().build()
	continuation = continuation.then(save)
    
    continuation.enqueue() // 작업 시작
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이어서 작성중....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 참고 문헌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- android basics with compose&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;a href=&quot;https://developer.android.com/courses/android-basics-compose/course?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.android.com/courses/android-basics-compose/course?hl=ko&lt;/a&gt;&lt;/p&gt;</description>
      <category>Kotlin/안드로이드</category>
      <author>batsalee</author>
      <guid isPermaLink="true">https://smallpants.tistory.com/335</guid>
      <comments>https://smallpants.tistory.com/335#entry335comment</comments>
      <pubDate>Tue, 7 Jul 2026 20:37:23 +0900</pubDate>
    </item>
    <item>
      <title>안드로이드 빌드 환경</title>
      <link>https://smallpants.tistory.com/334</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. gradle&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 자동화 도구 &lt;br /&gt;C++로&amp;nbsp;비유하면&amp;nbsp;CMake,&amp;nbsp;Make,&amp;nbsp;vcpkg&amp;nbsp;같은걸&amp;nbsp;다&amp;nbsp;합쳐놓은&amp;nbsp;개념 &lt;br /&gt;빌드의&amp;nbsp;주체같은&amp;nbsp;느낌인데&amp;nbsp;소스코드를&amp;nbsp;컴파일러에게&amp;nbsp;전달하고,&amp;nbsp;리소스(다국어&amp;nbsp;등)를&amp;nbsp;챙기고,&amp;nbsp;외부&amp;nbsp;라이브러리를&amp;nbsp;가져와서&amp;nbsp;최종적으로&amp;nbsp;앱으로&amp;nbsp;만들어내는&amp;nbsp;모든&amp;nbsp;과정을&amp;nbsp;자동화해주는&amp;nbsp;도구 &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Kotlin/안드로이드</category>
      <author>batsalee</author>
      <guid isPermaLink="true">https://smallpants.tistory.com/334</guid>
      <comments>https://smallpants.tistory.com/334#entry334comment</comments>
      <pubDate>Tue, 30 Jun 2026 22:22:57 +0900</pubDate>
    </item>
    <item>
      <title>안드로이드의 4대 컴포넌트</title>
      <link>https://smallpants.tistory.com/333</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;본격적인 안드로이드 공부 시작...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;추가 확인 필요한 사항&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 서비스 라이프사이클(foregroud, background, bound)&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;안드로이드 4대 컴포넌트&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- Activity, Service, Broadcast Receiver, Content Provider&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 안드로이드 앱의 필수적인 구성요소이며, 각각은 시스템이나 앱에 들어올 수 있는 진입점&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 각 컴포넌트는 독립적으로 존재, 고유의 기능을 수행하며, 인텐트를 통해 상호작용한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 모든 컴포넌트는 메인스레드(UI스레드)에서 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;1. Activity&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 사용자와 상호작용을 담당하는 인터페이스&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 사용자에게 실제로 보이는 화면을 의미&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 액티비티는 두개 이상 동시에 보일 수 없음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 어플리케이션은 반드시 하나 이상의 액티비티가 있어야 함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 앱을 실행할땐 앱 전체를 호출한다기보다는 앱의 액티비티를 호출하는 것&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 액티비티는 인텐트를 통해 다른 어플리케이션의 액티비티 호출 가능&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 액티비티는 한개 이상의 view(텍스트/버튼/이미지) or ViewGroup(레이아웃)을 포함&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 액티비티 내에 프래그먼트를 추가해서 화면을 분할시킬 수 있음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;2. Service&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 주로 background에서 어떠한 작업을 처리하기 위해 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; - 액티비티는 사용자와 상호작용한다면 Service는 내부에서 동작&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 다만 항상 그런건 아니고 foreground service/background service로 나뉨&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;1) foreground service&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- foreground service는 사용자에게 잘 보이는 작업이고, 서비스가 수행하는 동작을 사용자에게 알릴때 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 사용자가 앱과 상호작용하지 않을때도 계속 실행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 활성화된 액티비티와 동일한 우선순위&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;다만 애초에 서비스의 주목적이 백그라운드니까 foreground service 동작은 WorkManager를 쓰는게 더 좋다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2) backgroud service&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- background service는 사용자에게 직접 보이지 않는 작업(주로 서비스를 이 용도로 사용)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 다만 우선순위가 낮아서 시스템 리소스가 부족하면 강제종료될 수 있음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; - 그러므로 즉각적인 실행이 필요하면 foreground service/WorkManager 사용&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 어플리케이션이 종료되어도 이미 시작된 서비스는 background에서 계속 동작한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; - 예를들어 타이머 앱은 타이머 시작 후 앱을 종료해도 시간이 계속 흘러간다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 또는 &lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;어플리케이션을 사용하면서 파일을 다운로드 받을때 서비스를 사용&lt;/span&gt; &lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 네트워크와 연동 가능&lt;/span&gt;&lt;br /&gt;- &lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;현재 비활성화된 Activity보다 우선순위가 높다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;Activity와 Service는 메인스레드(UI스레드)에서 실행된다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;그러므로 서비스에서 일 시키려면 다른 쓰레드 생성해서 일 시켜야한다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;3) bound service&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- bound service는 IBinder 인터페이스로 서버-클라이언트 관계처럼 서비스와 상호작용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 여러 프로세스에서 Bound Service에 바인딩해서 작업 수행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; - 바인딩된 컴포넌트 모두 소멸되면 해당 Bind Service도 소멸&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;3. Broadcast Receiver&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 안드로이드 OS로부터 발생하는 각종 이벤트와 정보를 받고 핸들링하는 컴포넌트&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 대부분 UI는 없고 안드로이드 장비상황을 OS가 감시하다가 이벤트가 발생하면 Broadcast Receiver에게 전달하고, 해당 이벤트에 맞는 동작을 Broadcast Receiver가 수행&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 대부분 UI가 없긴한데 상태표시줄 알림을 생성해서 사용자에게 이벤트가 발생했다고 알리는 동작은 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 안드로이드 OS가 보내주는 Broadcast를 받는 방법은 안드로이드 라이브러리에 BroadCastReceiver라는 클래스가 추상클래스로 구현되어 있는데, 이걸 상속받아서 onReceive(context, intent) 함수 오버라이딩하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- onReceive() 내에서 if (intent.action == &quot;com.abc.def&quot;) 라면 어떤 동작을 한다처럼 인텐트마다 동작 구현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- BroadCastReceiver를 상속받아 구현한 브로드캐스트 클래스를 AndroidManifest.xml에 receiver로 등록하고, 그 receiver내에서 어떤 인텐트들을 받을지 나열해두면 운영체제가 broadcast 보낼 때 해당 앱에서 그 인텐트를 받는지 보고 동작을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;4. Content Provider&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 안드로이드에서는 각 앱이 자신만의 샌드박스를 가지기 때문에 A앱이 B앱을 절대 읽을 수 없다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 그래서 데이터 공유를 하려면 공식적인 창구가 필요하고 그게 Content Provider&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 즉, 어플리케이션 간 데이터 관리 및 다른 어플리케이션의 데이터를 제공하는데 사용되는 컴포넌트&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 작은 데이터는 intent로 어플리케이션간 공유할 수 있지만, 음악/사진같은 용량 큰 파일을 Content Provider로 공유&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 데이터 관리는 SQLite DB/Web/파일 입출력 방식으로 관리하며 read/write는 권한이 있어야 접근 가능해서 현재 실행중인 어플리케이션에 접근 못하게 하거나, 원하는 일부 데이터만 접근 허용하는 등의 동작 가능&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;앱 처음 설치할때 전화, 사진에 접근 권한 요청 이런거 뜨는게 이게 Content Provider가 접근해야해서 그렇다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트-서버 구조처럼 사용하며 Content Provider(서버)가 데이터를 가지고 있는 DB의 역할이고 Content Resolver(클라이언트)가 데이터를 요청하는 앱이 된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청은 uri를 사용한 쿼리로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드상 구현&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;uri에 content://로 시작하는 문구를 넣고 쿼리를 날린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ContentProvider 클래스를 상속받아서 onCreate, query, insert, update, delete 등의 함수를 오버라이딩해서 사용한다. &lt;br /&gt;진짜 db에 뭐 요청하는 느낌처럼 쓸 수 있다.&lt;br /&gt;&lt;br /&gt;A앱에서 뭔가 insert하고 다른데서 query로 get하는 모양새가 된다.&lt;br /&gt;보통&amp;nbsp;insert하는&amp;nbsp;앱을&amp;nbsp;Data&amp;nbsp;Provider,&amp;nbsp;query로&amp;nbsp;get하는&amp;nbsp;앱을&amp;nbsp;Data&amp;nbsp;Consumer라고&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;정확하게는 Content Provider가 데이터를 보관하는건 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A앱에서 본인의 데이터를 가지고 있고, 그 데이터에 접근할 수 있는 인터페이스를 uri 형태로 만들어 진입로를 Content Provider에 저장해두는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 진입로는 &quot;content://com.abc.def&quot;같은 형태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 B앱에서 &quot;content://com.abc.def&quot;로 query&amp;nbsp;호출하면&amp;nbsp;안드로이드OS가&amp;nbsp;A앱의&amp;nbsp;프로세스를&amp;nbsp;띄워서&amp;nbsp;데이터를&amp;nbsp;가져다가&amp;nbsp;B앱에&amp;nbsp;준다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 사용 예시 insert하는쪽과 query하는 쪽 둘 다 좀 적어두면 좋을 듯&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;5. Intent&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 컴포넌트간에 통신 수단&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; - 컴포넌트에 Action, Data 등을 전달&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; - 주로 가장 많이 사용되는건 화면전환&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- Intent로 다른 어플리케이션의 컴포넌트를 활성화 시킬 수 있음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- Intent이름은&amp;nbsp; &quot;VIT_&quot; 형태의 문자열이나 &quot;com.abc.dce&quot;같은 역순uri같은 문자열로 주로 쓴다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;단순한 문자열은 아니고 Intent의 멤버변수들이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; - action : &quot;com.abc.def&quot;같은&amp;nbsp;문자열이며&amp;nbsp;무엇을&amp;nbsp;할&amp;nbsp;것인가를&amp;nbsp;의미하는&amp;nbsp;함수명같은&amp;nbsp;개념 &lt;br /&gt;&amp;nbsp; &amp;nbsp; - data : content://contacts/people같은 어떤 데이터를 대상으로 할 것인가의 개념 &lt;br /&gt;&amp;nbsp; &amp;nbsp; - category : 문자열 리스트를 전달하면 되고 어떤 환경에서 실행되어야 하는가의 개념&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;앱 목록에 노출할지, 웹브라우저에서 실행가능하게 할지&lt;br /&gt;&amp;nbsp; &amp;nbsp; - extras : String-Object 형태의 map이며 intent와 함께 전달할 매개변수들을 넣는 곳 &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1782825207766&quot; class=&quot;kotlin&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;val intent = Intent(&quot;com.abc.def&quot;)
intent.putExtra(&quot;name&quot;, &quot;abc&quot;)
intent.putExtra(&quot;width&quot;, 10.5)
sendBroadcast(intent)

//위처럼 보내고 onReceive에서 아래처럼 사용

if (intent.action =- &quot;com.abc.def&quot;) {
    val name = intent.extras?.getString(&quot;name&quot;)
    val width = intent.extras?.getDouble(&quot;width&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;안드로이드 액티비티의 생명주기(Life Cycle)&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- Activity는 클래스다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 액티비티는 안드로이드 4대 컴포넌트 중 하나&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- UI와 가장 밀접한 관련&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 앱은 하나 이상의 액티비티가 서로 연결된 형태로 구성&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;1.&amp;nbsp; 액티비티 예시&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 카카오톡 실행 시 처음 나오는 카카오톡 로고가 하나의 액티비티&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 그 후 진입되는 친구목록이나 채팅목록 화면도 별도의 하나의 액티비티&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 카카오톡을 내리고 유투브를 켜면 유투브 액티비티가 보이게 됨&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 이렇게 액티비티가 전환될때마다 각자 생명주기에 따라 호출되는 함수가 있음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;2. 액티비티 함수&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- onCreate() : 최초 앱 실행 시 단 한번만 호출, 주로 초기화 관련 작업 수행&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- onStart() : 액티비티가 화면에 표시되기 직전에 호출(화면에 진입할때마다 호출되어야 하는 작업 구현)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- onResume() : 액티비티가 화면에 표시된 직후에 호출(액티비티가 포커스된 상태)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- onPause() : 액티비티가 보여지지 않은 직후에 호출(포커스를 잃은 상태), 저장해야하는 데이터가 있다면 여기서 저장(단 다른 액티비티가 보여지게 되므로 너무 무거운 작업하면 안됨)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- onStop() : 액티비티가 완전히 보이지 않게 됐을때&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- onDestroy() : 액티비티가 종료/앱 프로세스가 종료됐을때&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- onRestart() : onStop() 상태인데 해당 액티비티로 전환되서 보여지게되면 onRestart() 호출하고 바로 onStart()호출&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;다른 액티비티(불투명하고 화면 꽉채우는게)가 올라오게되면 onPause()랑 onStop() 연달아서 둘 다 호출된다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;그러니까 onPause()만 호출하고 onStop() 호출 안하는 케이스는 투명한 새로운 액티비티 호출하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;3.&amp;nbsp; 다이얼로그&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;다이얼로그는 액티비티의 일부이다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;그래서 액티비티 위에 다이얼로그가 올라와서 화면 가려지면 onPause가 호출되어야할것같지만 액티비티가 다른 액티비티로 가려진게 아니라서 호출되지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;4. 프래그먼트&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 이건 일단 개념은 보긴 할건데 우리 프로젝트는 프래그먼트 일부러 안쓰고 액티비티만 쓰게 구현해놔서... 차후 확인 예정&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 앱 UI의 재사용 가능한 부분(모듈성/재사용성)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 자체 레이아웃 정의/관리하고 자체 생명주기를 가지며, 자체입력이벤트 처리 가능&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 단독으로 실행불가능하고 액티비티나 다른 프래그먼트에서 호스팅해야함&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;- 액티비티가 onStart 상태에 있는 동안 프래그먼트를 추가/교체/제거할 수 있다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Kotlin/안드로이드</category>
      <author>batsalee</author>
      <guid isPermaLink="true">https://smallpants.tistory.com/333</guid>
      <comments>https://smallpants.tistory.com/333#entry333comment</comments>
      <pubDate>Tue, 30 Jun 2026 22:07:20 +0900</pubDate>
    </item>
    <item>
      <title>Kotlin 기본 문법 정리</title>
      <link>https://smallpants.tistory.com/332</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 변수, 상수&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) 선언 방식&lt;/h4&gt;
&lt;pre id=&quot;code_1732439412484&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 자료형이 예측 가능하다면 생략 가능
var r = 1
val l = 1

// 혹은
var r : Int = 1
var l : Int = 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2) 변수, 상수&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- var : 변수(변경 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- val : 상수(변경 불가)&lt;/p&gt;
&lt;pre id=&quot;code_1732439278891&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
    var r : Int = 1
    val l : Int = 1
    r = 2
    l = 2  // 오류발생
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 조건문&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) if&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- C++과 완전히 동일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- if문법 뿐 아니라 !으로 not 걸거나, ==으로 비교하는 등 모두 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2) when&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- C++의 switch문과 대응되는 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 값 -&amp;gt; 행동 으로 작성하며, default 값의 경우 else -&amp;gt; 행동 으로 작성&lt;/p&gt;
&lt;pre id=&quot;code_1732439751330&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
    var r = 1
    when(r) {
        1 -&amp;gt; print(1)
        2 -&amp;gt; print(2)
        else -&amp;gt; print(0)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3) 표현식&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 값 자체를 if-else를 이용해서 지정할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1732439878696&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
    var r = 1
    var result = if(r == 1) 1 else if(r == 2) 2 else 0
    print(result)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Kotlin/기본 문법 정리</category>
      <author>batsalee</author>
      <guid isPermaLink="true">https://smallpants.tistory.com/332</guid>
      <comments>https://smallpants.tistory.com/332#entry332comment</comments>
      <pubDate>Sun, 24 Nov 2024 18:57:57 +0900</pubDate>
    </item>
    <item>
      <title>stash(스테이시)</title>
      <link>https://smallpants.tistory.com/331</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 스테이시란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 작업이 아직 완료되지 않은 상태에서 다른 브랜치로 체크아웃 하고 싶을 때, 결과물을 스테이시 영역에 잠시 보관할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 사용 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- git stash : 스테이시에 보관&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- git stash list : 스테이시 목록 조회&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- git stash pop : 저장내용을 현재 브랜치에 적용 후 stash 목록에서 drop&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- git stash apply : stash에 저장된 내용을 브랜치에 적용하되 목록에서 drop하지는 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- git stash drop stash@{O} : stash에 저장된 내용을 삭제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS 지식/Git &amp;amp; GitHub</category>
      <author>batsalee</author>
      <guid isPermaLink="true">https://smallpants.tistory.com/331</guid>
      <comments>https://smallpants.tistory.com/331#entry331comment</comments>
      <pubDate>Sun, 10 Nov 2024 17:38:00 +0900</pubDate>
    </item>
    <item>
      <title>switch와 checkout의 차이점</title>
      <link>https://smallpants.tistory.com/330</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 공통점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Git 브랜치를 전환하귀 위해 사용하는 명령어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. checkout&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 브랜치 전환, 파일 체크아웃, 커밋으로 돌아가기 등 다양한 용도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 하나의 명령어로 여러 기능을 수행할 수 있으므로 혼란을 줄 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. switch&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 오직 브랜치 전환에서만 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 명령어 사용이 더 단순명확하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 요약하면 브랜치 전환 목적에서만 보면 둘 다 사용 가능하고, checkout은 다른 용도로도 사용할 수 있다.&lt;/p&gt;</description>
      <category>CS 지식/Git &amp;amp; GitHub</category>
      <author>batsalee</author>
      <guid isPermaLink="true">https://smallpants.tistory.com/330</guid>
      <comments>https://smallpants.tistory.com/330#entry330comment</comments>
      <pubDate>Sun, 10 Nov 2024 17:34:25 +0900</pubDate>
    </item>
    <item>
      <title>cherry-pick</title>
      <link>https://smallpants.tistory.com/329</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 체리픽이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다른 브랜치에 있는 커밋을 내 브랜치에 적용시킬 때 사용하는 명령어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- merge나 rebase의 경우 다른 브랜치의 모든 내용을 현재 브랜치에 반영하게 되지만 체리픽은 원하는 특정 커밋만 가져와서 반영할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다만 체리픽은 같은 내용의 커밋을 여러개 생성하므로 꼭 필요할 때만 사용하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 사용 방법&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;137&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brmrgO/btsKDQSdF1S/kpk1IOyWj9YH7WaYaQOgek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brmrgO/btsKDQSdF1S/kpk1IOyWj9YH7WaYaQOgek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brmrgO/btsKDQSdF1S/kpk1IOyWj9YH7WaYaQOgek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrmrgO%2FbtsKDQSdF1S%2Fkpk1IOyWj9YH7WaYaQOgek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;137&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;137&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 상황일 때 feature/#1 브랜치의 커밋 중 34b4cab와 13f03ab 커밋을 master 브랜치에 적용하고 싶다면 아래와 같이 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731226943380&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# git cherry-pick {커밋 해시}
git cherry-pick 34b4cab
git cherry-pick 13f03ab

# 또는 
git cherry-pick 34b4cab 13f03ab

# 연속적인 커밋일 경우
git cherry-pick 34b4cab..fe834e9
// 단 연속 커밋의 경우 내가 적용하고자 하는 커밋의 다음 값을 지정해야 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;충돌 발생 시&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 충돌난 코드 수정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) git add {충돌난 코드 경로}&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) git cherry-pick --continue&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;cherry-pick 중단 시&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- git cherry-pick --abort&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. 소스트리에서 사용 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 병합받고자 하는 브랜치로 체크아웃&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 체리픽 해올 커밋의 브랜치로 가서 해당 커밋 우클릭 후 체리 픽&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;998&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/On7Hl/btsKDCmmEPj/wAnokDRTUvSXu98LCY5V61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/On7Hl/btsKDCmmEPj/wAnokDRTUvSXu98LCY5V61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/On7Hl/btsKDCmmEPj/wAnokDRTUvSXu98LCY5V61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOn7Hl%2FbtsKDCmmEPj%2FwAnokDRTUvSXu98LCY5V61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1304&quot; height=&quot;998&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;998&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>CS 지식/Git &amp;amp; GitHub</category>
      <author>batsalee</author>
      <guid isPermaLink="true">https://smallpants.tistory.com/329</guid>
      <comments>https://smallpants.tistory.com/329#entry329comment</comments>
      <pubDate>Sun, 10 Nov 2024 17:31:18 +0900</pubDate>
    </item>
    <item>
      <title>문자열로 된 2진수값을 쉽게 10진수로 변환하는 법</title>
      <link>https://smallpants.tistory.com/328</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11179&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/11179&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 문제를 풀면서 10진수와 2진수간 변환을 좀 더 편하게 할 방법이 없을까 싶어서 코파일럿에게 물어본 결과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stoi를 이용해서 2진수 문자열을 10진수로 쉽게 변환하는 방법이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stoi(binary, nullptr, 2); 라고 하게 되면 nullptr은 기본값이라 10진수로 출력하게 되며, 2는 2진수-&amp;gt;10진수를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2를 8로 바꾸면 8진수로 인식해서 8진수 -&amp;gt; 10진수로 변환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1728720670759&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;

int main()
{
	ios::sync_with_stdio(false); cin.tie(NULL);

	int N;
	cin &amp;gt;&amp;gt; N;

	string bs = bitset&amp;lt;8 * sizeof(N)&amp;gt;(N).to_string();
	string binary = bs.substr(bs.find_first_not_of('0'));
	reverse(binary.begin(), binary.end());

	cout &amp;lt;&amp;lt; stoi(binary, nullptr, 2);

	return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>C, C++/Code Keeping</category>
      <author>batsalee</author>
      <guid isPermaLink="true">https://smallpants.tistory.com/328</guid>
      <comments>https://smallpants.tistory.com/328#entry328comment</comments>
      <pubDate>Sat, 12 Oct 2024 17:16:32 +0900</pubDate>
    </item>
    <item>
      <title>enum / enum class</title>
      <link>https://smallpants.tistory.com/327</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;enum&lt;/h2&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;enum은 내부적으로 int와 동일하게 사용되며, 값을 지정하지 않으면 가장 첫 값부터 0으로 시작해서 1씩 증가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 아래처럼 Red라고 사용하면 그냥 0과 동일하게 사용되며, WaterMelon::Black처럼 어느 enum의 값인지 명시할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제점&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서로 다른 enum에 같은 이름을 중복해서 사용할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 또한 int와 같게 처리되므로 암시적으로 실수가 발생할 여지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 예를들어 서로 다른 enum의 값간에 대소비교&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 공간복잡도 최적화 상황에서 1 ~ 2바이트로도 충분한 경우의 효율문제&lt;/p&gt;
&lt;pre id=&quot;code_1727766328105&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

void main() 
{
	enum WaterMelon
	{
		Red,   // 0
		Green, // 1
		Black  // 2
	};

	enum PineApple
	{
		Yellow, // 0
		// Green   // 1, 다른 enum 멤버의 이름과 중복될 수 없음
	};

	int a = Red;
	int b = WaterMelon::Black;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;enum class&lt;/h2&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Modern C++ 11에 추가됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 enum에 더 강한 제약을 두면서도 더 명확한 의미를 갖게 하여 enum의 문제점들을 해결했다.&lt;/p&gt;
&lt;pre id=&quot;code_1727766901776&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

void main() 
{
	enum class WaterMelon
	{
		Red,   // 0
		Green, // 1
		Black  // 2
	};

	enum class PineApple
	{
		Yellow, // 0
		Green   // 1
	};

	WaterMelon a = WaterMelon::Red;
	WaterMelon b = WaterMelon::Green;
	PineApple c = PineApple::Green;

	// int d = Red; // 오류
	// int e = WaterMelon::Red; // 오류
	int f = static_cast&amp;lt;int&amp;gt;(WaterMelon::Red);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;enum과의 차이점&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 클래스명을 반드시 같이 적어줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Red처럼 사용 불가능하고 WaterMelon::Red처럼 명확히 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 서로 다른 enum class에 같은 이름의 값을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- WaterMelon과 PineApple 양쪽 모두 Green이 있지만 문제없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 내부적으로 int로 처리하지 않고 다른 자료형으로 처리하게 만들 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1727767060323&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum class Color : char {
    RED,
    GREEN,
    BLUE
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) 먼저 선언만 해두고 나중에 정의할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 선언만 해두고 나중에 정의하거나, 헤더에 선언만 해두고 cpp에 정의하는 식으로 구현 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1727767151664&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum class PineApple; // 선언

enum class WaterMelon
{
	Red,   // 0
	Green, // 1
	Black  // 2
};

enum class PineApple // 정의
{
	Yellow, // 0
	Green   // 1
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;제약이 추가된 이유&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 실수할 수 있는 부분에 제약을 추가해서 버그를 방지하기 위한 목적도 있지만 사용이 더 불편해진것 또한 사실이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 다른 언어들은 enum을 C++의 enum class와 유사하게 사용하기 때문에 언어간의 통일성 및 표준화를 위한 목적도 있다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;결론&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 본인이 enum을 여러개 정의해야해서 변수명이 겹칠것 같거나, 실수할 여지가 있다면 enum class를 선택하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 갑작스럽게 enum class로 정의된 코드를 만났을 때 이해만 할 수 있으면 되겠다.&lt;/p&gt;</description>
      <category>C, C++/modern C++</category>
      <author>batsalee</author>
      <guid isPermaLink="true">https://smallpants.tistory.com/327</guid>
      <comments>https://smallpants.tistory.com/327#entry327comment</comments>
      <pubDate>Tue, 1 Oct 2024 16:25:55 +0900</pubDate>
    </item>
    <item>
      <title>Intro sort 기준</title>
      <link>https://smallpants.tistory.com/326</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 16개 이하 : 삽입정렬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 스택 2 * log(N) 이하 : 퀵정렬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 스택 2 * log(N) 초과 : 힙정렬&lt;/p&gt;</description>
      <category>Notepad/Notepad</category>
      <author>batsalee</author>
      <guid isPermaLink="true">https://smallpants.tistory.com/326</guid>
      <comments>https://smallpants.tistory.com/326#entry326comment</comments>
      <pubDate>Thu, 12 Sep 2024 02:43:32 +0900</pubDate>
    </item>
  </channel>
</rss>