<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>JoJo_DevStory</title>
        <link>https://velog.io/</link>
        <description>12년도부터 대학에서 안드로이드 모바일을 전공으로 시작하여 "진짜 개발자"를 꿈꾸며 개발공부를 시작했습니다. SW 개발이 재밌어서 여러 방면으로 스터디하며 현재는 새로운 환경 및 새로운 트렌드에도 유연하게 적응을 잘하는 개발자로 성장해 나가는 중입니다. 글 내용에 대한 피드백은 언제나 환영입니다!</description>
        <lastBuildDate>Mon, 20 Jul 2020 01:36:47 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>JoJo_DevStory</title>
            <url>https://images.velog.io/images/jojo_devstory/profile/f160f5e9-d7cc-4092-ae20-dd6841d80ac6/20190104_101243_376.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. JoJo_DevStory. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jojo_devstory" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Spring] 전자정부프레임워크란?]]></title>
            <link>https://velog.io/@jojo_devstory/Spring-%EC%A0%84%EC%9E%90%EC%A0%95%EB%B6%80%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EB%9E%80</link>
            <guid>https://velog.io/@jojo_devstory/Spring-%EC%A0%84%EC%9E%90%EC%A0%95%EB%B6%80%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EB%9E%80</guid>
            <pubDate>Mon, 20 Jul 2020 01:36:47 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요!
이번 포스팅은 이전과는 조금 다른 내용입니다.
바로 Spring 기반의 전자정부프레임워크 입니다.</p>
<p>과연 이 프레임워크가 무엇이고, 왜 사용하는지에 대해 한번 알아보겠습니다.</p>
<h2 id="1-전자정부프레임워크가-뭘까요">1. 전자정부프레임워크가 뭘까요?</h2>
<p><a href="https://www.egovframe.go.kr/EgovIntro.jsp?menu=1&amp;submenu=1">https://www.egovframe.go.kr/EgovIntro.jsp?menu=1&amp;submenu=1</a>
위 링크는 전자정부프레임워크의 소개 페이지 입니다.
위 페이지에 나온 내용은 아래와 같습니다.</p>
<p><strong>등장배경 및 목적</strong>
개발프레임워크는 정보시스템 개발을 위해 필요한 기능 및 아키텍처를 미리 만들어 제공함으로써 효율적인 어플리케이션 구축을 지원합니다.
“전자정부 표준프레임워크”는 공공사업에 적용되는 개발프레임워크의 표준 정립으로 응용 SW 표준화, 품질 및 재 사용성 향상을 목표로 합니다.
이를 통해“전자정부 서비스의 품질향상” 및 “정보화 투자 효율성 향상”을 달성하고, 대ㆍ중소기업이 동일한 개발기반 위에서 공정 경쟁이 가능하게 됩니다.</p>
<p>※ 표준프레임워크는 기존 다양한 플랫폼(.NET, php 등) 환경을 대체하기 위한 표준은 아니며, java 기반의 정보시스템 구축에 활용하실 수 있는 개발·운영 표준 환경을 제공하기 위한 것입니다.</p>
<p><img src="https://images.velog.io/images/jojo_devstory/post/29b68c1b-6c7c-4deb-85ae-cd32d29d0860/image.png" alt=""></p>
<p>이렇게 공식적으로 소개가 되어있습니다.</p>
<p>즉, 전자정부프레임워크란 행정안전부 산하 한국정보화진흥원에서 만든 웹 기반 어플리케이션 프레임워크로서 <strong>정부 및 공공기관, 공기업</strong> 등의 웹사이트에 자주 쓰이는 공통 기능들을 <strong>Java의 Spring 프레임워크와 유명 Java 라이브러리(iBatis/MyBatis, Jackson, Apache Commons 등)를 가지고 미리 만들어 놓은 공통컴포넌트와 이를 개발하는 개발환경, 실행환경, 운영환경, 관리환경 등으로 구성</strong>되어있다.</p>
<h2 id="2-왜-이것을-사용할까요">2. 왜 이것을 사용할까요?</h2>
<p>먼저 이 전자정부프레임워크를 주로 사용하는 발주처가 정부기관이며 이러한 프로젝트를 수주하는 사업에는 필수 요구사항이라는게 있습니다.
주로 수주를 할때 해당 발주처에서 필요한 하드웨어는 어떠한 것을 사용하며 소프트웨어는 어떤걸 쓰겠다 라는 것이 다 기술 되어있습니다.
그래서 이러한 문서인 사업제안서는 이 <strong>요구사항을 기반으로 작성</strong>되어 있습니다.</p>
<p>전자정부프레임워크를 &#39;왜 사용하나요?&#39; 라는 질문을 하면 <strong>고객이 요구</strong>했기 때문에 라고 답하는게 제일 정확한 답변입니다.
고객이 원하는 대로 시스템 및 프로그램을 개발해주는 것이 기본이기 때문입니다.
그런데 고객이 왜 그걸 원하느냐 라는 의문이 여기서 발생합니다.
실제로 프레임워크의 장단점과 보안이 좋다 안좋다의 주제는 중요하지 않습니다.
전자정부 프레임워크는 아시다시피 Spring + 기타 플러그인(컴포넌트)를 하나로 묶어 패키지화 한 것 입니다.</p>
<p>그렇기에 Spring을 사용해보신분들은 아시겠지만 Spring의 장점은 확장성이 뛰어나며 JAVA로 이루어져 있습니다. 그런데 그 뛰어난 범용성과 확장성 만큼 플러그인들끼리의 층돌로 인한 오동작이 있을 수 있기에 개인 또는 프로젝트를 수주받은 개발사에서 플러그인을 자기들 편하대로 사용을 한다면 해당 웹사이트에는 어떤 코드가 들어 있는지 알 수가 없는 신뢰 할 수 없는 코드가 됩니다.</p>
<p>그렇기에 전자정부프레임워크 처럼 이런 프레임워크를 신뢰할 수 있고 책임질 수 있는 개인이나 단체가 한가지 형태로 통합해서 그걸 패키지로 배포하는 경우는 개인이나 개발사에서 중구난방으로 플러그인을 적용하고 이것저것 추가 하는 것 보다는 적어도 정상적으로 프로그램이 작동 됨과 동시에 코드에 문제가 없음을 알리는 신뢰성이 있는 즉, 검증된 코드가 됩니다.
마찬가지로 이러한 프레임워크를 관리를 하는 곳이 존재 하니 문제가 생기면 기술지원도 받을 수 있다는 것이 장점입니다.</p>
<p>프레임워크라는 단어에서 보듯이 이 하나의 공통된 프레임워크를 사용하면 특정 개발사에 종속되지 않고 여러 곳의 개발사에 그때그때 조건에 따라 발주가 가능하며 개발 했던 개발사가 유지보수를 하지 않더라도 다른 개발사에서 이어받아서 유지보수가 가능하게 됩니다.
즉, <strong>정부기관에서 관리하는 검증된 오픈 소스로 구성된 무료 프레임워크</strong>라는 점이 강점입니다.</p>
<p>아래 이미지는 공식 홈페이지에서 소개하는 적용효과 입니다.
<img src="https://images.velog.io/images/jojo_devstory/post/57f2e0be-6d14-478c-a89d-cad823432fb8/%EC%BA%A1%EC%B2%98.PNG" alt=""></p>
<p>하지만 이것은 일반적인 사용이유이며 사실은 정부에서 모든 정부기관에 무조건 사용하라고 지침이 내려졌기 때문에 사용이유를 따지지 않고 사용하는 경향이 강합니다.</p>
<h2 id="3-그렇다면-단점은-없을까요">3. 그렇다면 단점은 없을까요?</h2>
<p>있습니다.
실제 정부에서 생각하는 것과 개발하는 개발 당사자인 개발자들 입장에서는 생각의 차이가 존재 하기 때문에 단점 또한 명확합니다.</p>
<p>전자정부표준프레임워크, 약칭 eGov는 공공기관 웹사이트 개발 과정을 표준화하기 위한 의도에서 시작되었으나, 그러한 의도로 인해 <strong>구조가 경직되고 최신 기술을 반영하지 못하는 보수적인 기술이라는 것이 문제점으로 작용</strong>하고 있다. 특히 정부발 프로젝트에 기대는 SI 회사가 절대 다수를 차지하는 현실로 인해 <strong>한국의 SW 시장이 Java + Spring으로 획일화</strong>되다시피 하는 결과를 낳았으며, 이는 곧 국내 소프트웨어 기술력 자체의 저하로 이어졌습니다.😩 SI는 기본적으로 안정성과 유지보수를 추구하는 업계이지, 새로운 기술과 변화를 추구하는 곳이 아니기 때문. 그런데 사용하는 프레임워크와 제반 기술들까지 일원화되니 다양성이 죽어버린 것입니다. 그나마 삼성전자와 네이버 등의 극소수 대기업들이 어느 정도 커버를 하는 상황....이지만 그렇게 좋다고 할 수도 없습니다.</p>
<p>물론 이것이 eGov의 잘못이라 하기는 어렵고, 진짜 원인은 SI 쪽으로 편중된 한국의 S/W 시장에 있습니다. 어지간한 대기업이 아니라면 SI를 빼고는 소프트웨어 사업을 벌이는 것이 불가능할 정도로 우리나라의 시장 상황은 열악합니다. 어느 나라든 관공서가 아닌 민간 시장을 대상으로 자사 솔루션을 개발, 판매하는 기업들이 소프트웨어 시장의 기술 발전을 선도하는 편인데, 한국에는 이런 업체가 상대적으로 부족하다는 것이 근본적인 문제인 것입니다.</p>
<p>또한 오라클이 나날이 자바 라이선스에 관련해서 갑질을 하고 있고 이로 인해 자바에서 이탈하는 기업도 늘어나고 있는데, 오라클의 갑질에 의한 피해를 막기 위해서는 장기적으로 자바기반에서 벗어나야 할 것인데.....</p>
<p>스프링이나 자바를 하지 못하고 싫어하는 개발자라면 단점이 될 수도 있겠네요.</p>
<p>그 외에 공통 컴포넌트들에 대한 자잘한 이슈 문제는 계속 관리처에 이슈를 제기 하고 공론화 시켜야 문제가 해결될 것으로 보이고 다른 좋은 프레임워크가 나오지 않는 이상 향후 10년간은 문제없이 사용 될 것으로 보입니다.</p>
<p>마지막으로 저 또한 사용하면서 불편한 점은 한 둘이 아니고 개발하기 싫은적도 많습니다만... 개인이 시장을 뭐 어떻게 할 수도 없으니.. 익숙해지는것 외엔 방법이 없네요.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[근래들어 포스팅이 소홀해진 이유]]></title>
            <link>https://velog.io/@jojo_devstory/%EA%B7%BC%EB%9E%98%EB%93%A4%EC%96%B4-%ED%8F%AC%EC%8A%A4%ED%8C%85%EC%9D%B4-%EC%86%8C%ED%99%80%ED%95%B4%EC%A7%84-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@jojo_devstory/%EA%B7%BC%EB%9E%98%EB%93%A4%EC%96%B4-%ED%8F%AC%EC%8A%A4%ED%8C%85%EC%9D%B4-%EC%86%8C%ED%99%80%ED%95%B4%EC%A7%84-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Tue, 07 Jul 2020 00:14:16 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요.</p>
<p>오랜만입니다.</p>
<p>요즘들어 이직이라던지...기타 개인사정으로 일이 많아서 포스팅이 소홀해졌네요.</p>
<p>현재는 이직이 잘되어서 다행이지만 아직은 이직 초반이라 이래저래 회사에제출할 서류도 많고 정신이 없네요.</p>
<p>거기다 해외축구 영국 리그인 EPL도 챙겨보느라고 시간가는 줄 모르겠네요ㅎㅎ</p>
<p>다음번엔 안드로이드 또는 다른 IT관련 좋은 내용으로 포스팅 하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] Android Studio 4.0 출시 🎉🎉🎊]]></title>
            <link>https://velog.io/@jojo_devstory/Android-AndroidStudio-4.0-%EC%B6%9C%EC%8B%9C</link>
            <guid>https://velog.io/@jojo_devstory/Android-AndroidStudio-4.0-%EC%B6%9C%EC%8B%9C</guid>
            <pubDate>Tue, 09 Jun 2020 14:56:07 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요!</p>
<p>정말 오랜만에 다시 포스팅 하네요.</p>
<p>그간 이직 문제로 면접을 수도 없이 보느라 정신이 없어서 포스팅을 게을리 했습니다.</p>
<p>조금 지난 일이지만 하나 포스팅 해보려고 합니다.</p>
<p>바로 안드로이드 스튜디오의 4.0 버전 정식 출시를 알리는 내용이죠!</p>
<p>작년부터 구글에서 추가될 내용에 대해 미리 프리뷰로 소개도 하고 했는데 벌써 시간이 이렇게 흘렀네요.</p>
<p>아래는 이번 업데이트에서 중점적으로 추가된 내용들 입니다!</p>
<h3 id="😍-motion-editor">😍 Motion Editor</h3>
<p><img src="https://images.velog.io/images/jojo_devstory/post/353d6d90-1f8b-4fc1-b54a-23fe92697a0f/image7.gif" alt="Motion Editor">
모션 에디터(Motion Editor)는 MotionLayout 타입을 위한 비주얼 디자인 편집기이며 애플리케이션의 모션과 위젯 애니메이션을 관리하기 위해 MotionLayout API를 사용하는 데 있어 그 과정을 더 간편하게 해줍니다.
또한 XML 파일이 생성돼 개발자가 해당 작업을 수동으로 처리하지 않아도 된다는 점이 정말 좋습니다.</p>
<h3 id="🔎-live-layout-inspector">🔎 Live Layout Inspector</h3>
<p><img src="https://images.velog.io/images/jojo_devstory/post/772d55a5-f002-47b0-8115-31d19a814ec1/0_DDu5ks9oAIBuRVbD.gif" alt="Live Layout Inspector">
<img src="https://images.velog.io/images/jojo_devstory/post/fa7dd98f-3ce8-4b3f-98de-518a27473771/image1.png" alt="Layout Validation">
드디어 새롭게 업그레이드된 레이아웃 인스펙터(Layout Inspector)는 실행 중인 앱으로 계속 업데이트되는 데이터에 접근해 IDE 자체에서 리소스 사용을 분석해줌으로써 UI 디버깅을 직관적으로 만들어 줍니다. 제가 아마 이전에도 잠깐 소개를 했었던 기억이 나네요.
또한 레이아웃 밸리데이션 기능(Layout Validation)도 추가되어 여러 디바이스의 화면 비율 및 해상도에 따라 UI를 비교할 수 있게 해줍니다.</p>
<h3 id="🔨-build-analyzer">🔨 Build Analyzer</h3>
<p><img src="https://images.velog.io/images/jojo_devstory/post/14570e97-d4cd-4c71-bfca-6a5aeb651767/image9.png" alt="Build Analyzer">
빌드 분석기(Build Analyzer)는 앱을 빌드시 비활성화된 최적화 혹은 잘못 구성된 작업 등 빌드에서 발생하는 병목 현상을 해결해주며 빌드할때 문제가 생길 수 있는 부분에 대해 개발자에게 알려줍니다. 이 Build Analyzer는 Java 8을 사용하고 Dynamic Feature Module 간에 기능 종속성을 생성하는 Android Gradle 4.0.0 plug-in를 통해 지원됩니다.</p>
<h3 id="📈-overhauled-cpu-profiler">📈 Overhauled CPU Profiler</h3>
<p><img src="https://images.velog.io/images/jojo_devstory/post/64d086fc-8262-4324-b063-0cebefdbd086/image2.png" alt="Overhauled CPU Profiler">
CPU 프로파일러(CPU Profiler)는 안드로이드 스튜디오의 기본 프로파일러 타임라인과 별개로 CPU 사용량을 제공하며, 분석하기 용이하도록 그룹으로 구성됩니다.</p>
<p>특히 모션 레이아웃을 위해 추가한 모션 에디터에 대해 가장 많은 신경을 쓴게 눈에 보이네요!</p>
<p>그외 Java8에 대한 Dex 컴파일(D8,R8) 관련도 추가 되었습니다.</p>
<p>더 자세한 사항은 아래 공식 문서를 참조 부탁드립니다.</p>
<p>유튜브 영상도 있어서 정보를 간편하게 요약해서 알려줍니다.</p>
<p>👏<a href="https://android-developers.googleblog.com/2020/05/android-studio-4.html?m=1">https://android-developers.googleblog.com/2020/05/android-studio-4.html?m=1</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Flutter란? - Flutter에 대해 알아보자!]]></title>
            <link>https://velog.io/@jojo_devstory/Flutter%EB%9E%80-Flutter%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@jojo_devstory/Flutter%EB%9E%80-Flutter%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Mon, 11 May 2020 08:14:49 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요!</p>
<p>오늘은 Flutter에 대해 알아보도록 하겠습니다!</p>
<h2 id="1-flutter란🤨">1. Flutter란?🤨</h2>
<p>Flutter는 Google에서 개발하고 Mobile World Congress 2018에서 최초 베타 릴리스를 발표하면서 새롭게 소개된 크로스 플랫폼 모바일 앱 개발 프레임워크입니다.
또한 개발자가 iOS와 Android 두 OS에 대해 고품질 기본 인터페이스를 제작하는 데 도움을 주는 크로스 플랫폼 프레임워크라고 할 수 있습니다.</p>
<p>기존 UI를 모두 버리고 자체적으로 UI를 렌더링하기 때문에 iOS에서 material 디자인과 ripple 애니메이션 을 볼 수 있고 Android 에서 cupertino 디자인을 볼 수 있습니다.
마치 화면 전체를 2D 그래픽 API로 fillRect 하고 drawText drawImage 해서 앱을 만드는 것처럼 Flutter 엔진이 Skia 기반으로 렌더링 해줍니다. 웹 개발에서 HTML을 모두 무시하고 전체를 flash나 canvas로 만드는 것과 같습니다.
<br>
<br></p>
<h2 id="2-왜-crossplatform을-사용할까요🙋🏻">2. 왜 CrossPlatform을 사용할까요?🙋🏻</h2>
<p>모바일 개발의 경우 iOS와 Android 모바일 개발자가 각각 따로 있다면 꼭 크로스 플랫폼으로 앱을 개발하지 않아도 됩니다. 하지만, 각 OS 별로 유저들에게 동일한 UI와 UX를 제공하면서 개발한다는 것은 쉬운일도 아닐뿐더러 각각 전문 개발자들이 필요하게 되니 개발 자원이 2배이상 필요하게 됩니다. 그리고 한 명의 개발자가 둘다 개발을 한다고 가정하면 각 OS의 개발 방식이 서로 다르기 때문에(IDE, 개발언어, 툴 등등) 따로 공부해야하는 필요성도 있습니다.</p>
<p>설령 개발을 완료 했다 하더라도 앱의 유지보수가 쉽지 않다는 단점이 있습니다. 안드로이드, IOS 따로 유지보수(추가 기능, 오류, 앱스토어 관리 등등) 관리를 해야하기 때문입니다.
그래서 크로스 플랫폼을 사용한다면 우선 개발 자원을 줄일 수가 있습니다. 하나의 프레임워크로 안드로이드, iOS 모두를 동시 개발이 가능하기 때문입니다.
관리 역시도 하나의 개발 소스만 관리하면 해결되기 때문에 훨씬 편리합니다.</p>
<p>하지만 이미 시장에는 모바일 크로스플랫폼 개발하면 떠오르는 프레임워크로 Facebook에서 개발을 주도하는 React-Native가 있으며 많은 개발자분들이 React-Native와 Flutter를 두고 고민을 하는 상황입니다.</p>
<p>아래는 React-Native vs Flutter 비교 유튜브 영상입니다.
!youtube[BqGxJ_ybE6k]
<br>
<br>
<br></p>
<h2 id="3-flutter는-어떤-언어를-사용하나요🧐">3. Flutter는 어떤 언어를 사용하나요??🧐</h2>
<p><img src="https://images.velog.io/images/jojo_devstory/post/8ca198de-96a6-4648-9144-5617a1d2d3e9/77-772776_transparent-curly-bracket-png-dart-programming-language-logo.png" alt="Dart">
보통 Flutter를 배울때 가장 큰 진입 장벽이 Flutter가 Dart언어를 사용하기 때문입니다.
물론 Flutter라고 해도 각 OS별 Native 코드를 사용하며 Android는 kotlin, iOS는 Swift를 사용합니다.
이전에 Dart는 2018년 프로그래밍 언어에서 배우면 안되는 언어 1위로 뽑혔습니다.
하지만 그땐 Flutter가 나오기전이라 그렇고 Flutter가 맹렬히 추격한 결과 현재는 10위 내외로 사용률이 왔다갔다 하는 중 입니다.
<br>
<br></p>
<h2 id="4-flutter의-특징">4. Flutter의 특징</h2>
<p>장단점은 아래와 같습니다.</p>
<p><strong>장점</strong></p>
<ul>
<li><p>통합 개발 환경 지원
Flutter는 다양한 Editor(Android Studio, VS Code 등등)를 사용하여 빌드가 가능합니다.
Android Studio는 Flutter Inspector와 Flutter Outline이라는 개발 도구를 추가적으로 지원해줍니다. VS code 에서는 간단하게 Extension 으로 Flutter를 설치하여 Flutter를 사용할 수 있습니다.</p>
</li>
<li><p>성능 문제 해결
기존 React Native 혹은 Hybrid App의 경우 네이티브 브릿지를 통한 통신이 불가피했습니다. 하지만 Flutter는 직접 컴파일되서 Render를 직접 하기때문에 성능이 빠릅니다. 애니메이션 속도가 60프레임은 가뿐히 넘어서는 것이 기존 크로스 플랫폼시장의 주류였던 React Native와 Flutter를 비교하는 많은 글들에서 Flutter를 내세우는 부분입니다.</p>
</li>
<li><p>머티리얼 디자인과 쿠퍼티노
Flutter는 Androd와 iOS의 대표 디자인 가이드를 기본적으로 제공합니다.
구글의 머티리얼 디자인(Material Design)의 홈페이지에는 이미 Flutter가 포함되어 있고 가이드만 제공하는 것 뿐만아니라 Flutter 프로젝트에 바로 추가하여 사용할 수 있는 패키지도 제공합니다.
안드로이드와 iOS에서 같은 머티리얼 디자인을 사용하더라도 플랫폼에 따라 다르게 출력되는 부분을 각각 디자인 가이드에 맞게 화면을 그립니다.
iOS앱을 개발하는 경우 iOS특유의 디자인 시스템인 쿠퍼티노(Cupertino) 위젯을 제공합니다.
그렇기에 선택의 폭이 정해져 있기 때문에 어떤 UI 라이브러리를 사용할 것인지 고민 할 필요가 없습니다만 이건 장점이자 단점이 될수도 있습니다.</p>
</li>
<li><p>Dart를 사용하지만 Native 코드도 사용
앞서 Dart를 사용한다고 했지만 결국엔 크로스 플랫폼이기에 해당 OS에 최적화된 앱을 만들려면 Native 코드를 사용할수밖에 없고 Dart와 섞어서 사용을 합니다.
즉, Dart만 사용하는것이 아니라 Android면 Kotlin, iOS면 Swift도 사용합니다.
이는 기존의 Native 코드를 사용한 개발자라면 장점이 됩니다.</p>
<br>

</li>
</ul>
<p><strong>단점</strong>
Flutter의 경우 Github 이슈란에 가보면 엄청난 이슈가 올라와 있는 것이 눈에 보입니다.
물론 이는 Flutter 자체가 이슈 항목에 아무나 이슈제의가 가능하도록 했기 때문에 그런점도 있습니다.</p>
<p>여기서 몇가지만 정리 하도록 하겠습니다.</p>
<ul>
<li><p>Native API를 Dart에서 직접 호출 불가합니다.
특별히 심하게 문제가 되진 않지만 외부 플러그인을 써야합니다.</p>
</li>
<li><p>Code Pushing
코드를 고치려면 새 버전을 배포해야 합니다.
React Native, Cordova, Ionic 에선 이미 지원 중 입니다.
<a href="https://github.com/flutter/flutter/issues/14330">https://github.com/flutter/flutter/issues/14330</a></p>
</li>
<li><p>Air BNB Lotti 사용 불가합니다.
Flutter는 지원하지 않습니다.
Android, iOS, React-Native만 지원
로티는 어플리케이션에 Fancy 한 에니메이션을 넣어주는 라이브러리이며 제가 개인적으로 좋아하는 라이브러리 입니다.
<a href="https://airbnb.design/lottie/">https://airbnb.design/lottie/</a> </p>
</li>
<li><p>웨어러블 디바이스앱에 약합니다.
<a href="https://pub.dev/packages/wear">https://pub.dev/packages/wear</a> 
위 플러그인이 있지만 Native 마냥 쉽게 되지 않습니다.</p>
</li>
<li><p>C/C++ 라이브러리 호출이 안됩니다.
NDK C/C++ 라이브러리 호출이 Dart에서 안됩니다. 
외부 플러그인을 써야하고, 원하는 플러그인이 없다면 만들어야 하는데 이는 보통일이 아닙니다.</p>
</li>
<li><p>지원되는 플러그인이 부족하다.
아직 플러그인들은 부족한 편입니다.
어플을 생성할 때, Webview, Map 등 플러그인은 필요합니다. 
하지만 Flutter의 이러한 플러그인들은 전부 0.4, 0.3 등등 1.0을 넘는 버전을 보기가 힘듭니다. 따라서 지속적으로 업데이트가 되고있고, 업데이트가 될때마다 다시 붙이고 테스트해보는 것은 어마어마하게 번거로운 일이 될 것입니다.</p>
</li>
<li><p>아직까진 국내에 개발관련 자료가 많이 없다.
Android, iOS Native는 나온지 오래되서 자료가 많다보니 문제해결이 쉽습니다만, 국내엔 아직까진 자료가 많다고 할수가 없어 이슈 상황 발생시 자료 찾기가 어렵습니다.
또한, Flutter 개발자들도 그렇게 많은 편이 아니기에 도움을 구하기도 어느정도 힘이 듭니다.</p>
<br>
<br>

</li>
</ul>
<h2 id="5-결론">5. 결론</h2>
<p>이 밖에도 약 7500개가 넘는 Issue가 현재 Github에 열려 있습니다.
앞으로 모바일 시장을 Flutter가 전부 지배할 것이라고 말하시는 분도 있습니다만.... 그런 상황은 오지 않을 겁니다. 결국엔 Flutter도 Native 코드를 사용하기 때문이고 하나의 개발 방법이기 때문입니다. 거기다 어느정도 여유가 되는 회사라면 각각의 플랫폼 전문가를 뽑아서 개발을 하는것이 소프트웨어 품질에 있어 좋기 때문입니다.</p>
<p><strong>그래도 Flutter가 좋다!</strong>
이 세상에 완벽한 것은 없습니다. Android만 보아도 Butterknife라는 유명한 라이브러리가 있고 한때 완벽한 라이브러리라고 칭송받았지만 결국엔 모바일 디바이스 성능의 변화, 개발 스킬의 다양화로 인해 Deprecated가 되며 데이터바인딩으로 대체 되었습니다. 영원한 것은 없는 것 입니다.
하지만, Flutter는 이미 크로스 플랫폼 계열에서 어마무시하게 강력합니다.
이미 구글 애드워즈, 구글 스태디아, 알리바바 - 텐센트에서 Flutter를 사용중입니다.
<a href="https://flutter.dev/showcase">https://flutter.dev/showcase</a></p>
<p>Flutter 는 Native로 빌드와 컴파일을 지원하기 때문에 빠른 성능이 매우 인상적이지만
Dart가 가지는 문제점 및 React-Native와의 경쟁 등 넘어야 할 산이 많습니다.
하지만 지속적으로 업데이트되고 성능만 본다면 React-Native와는 비교도 되지 않기에 Android와 iOS 둘다 서비스 출시를 하는 프로젝트에 도입을 고려해본다면 나쁘지 않다고 생각합니다.
<br></p>
<h3 id="참고내용">참고내용</h3>
<p><a href="https://flutter-ko.dev/docs">https://flutter-ko.dev/docs</a>
<a href="https://namu.wiki/w/Flutter(%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC)">나무위키</a>
<a href="https://jaceshim.github.io/2019/01/22/flutter-study-about-flutter/index.html">https://jaceshim.github.io/2019/01/22/flutter-study-about-flutter/index.html</a>
<a href="https://engineering.linecorp.com/ko/blog/flutter-pros-and-cons/">https://engineering.linecorp.com/ko/blog/flutter-pros-and-cons/</a>
<a href="https://sambalim.tistory.com/33">https://sambalim.tistory.com/33</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] AndroidX - ActivityResultContract ]]></title>
            <link>https://velog.io/@jojo_devstory/Android-AndroidX-ActivityResultContract</link>
            <guid>https://velog.io/@jojo_devstory/Android-AndroidX-ActivityResultContract</guid>
            <pubDate>Sat, 02 May 2020 08:14:03 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요!</p>
<p>오늘은 ActivityResultContract에 대해 좋은 포스팅이 있어 링크 공유할까 합니다.</p>
<p>AndroidX가 업데이트 되면서 Activity와 Fragment에 많은 변화가 오고 있는데요.</p>
<p>Activity Result를 처리하는 ActivityResultContract API가 업데이트 됨과 동시에</p>
<p>그 중 아래의 API 목록이 Deprecated가 되었습니다.</p>
<ul>
<li><strong>startActivityForResult()</strong></li>
<li><strong>onActivityResult()</strong></li>
<li><strong>requestPermissions()</strong></li>
<li><strong>onRequestPermissionsResult()</strong></li>
</ul>
<p>앗...아아.. 보시다시피 자주 사용하던 API들인데... Deprecated 된다니!</p>
<p>하지만 아직까지는 알파버전이기 때문에 실제 적용하기까지는 시간이 많이 남았습니다.</p>
<p>미리 어떤 방식으로 Migration 하는지 살펴보는게 좋겠네요.</p>
<p>제가 기존에 정리하고 있었지만... Pluu님이 더 깔끔하게 정리를 잘하셔서</p>
<p>이 분 글을 보는게 더 낫다고 판단하여(ㅜㅠ) 링크로 대체합니다.</p>
<p>아래 링크로 가시면 국내 Android 커뮤니티에서 유명하신 Pluu님이 포스팅을 작성하였습니다.</p>
<p><a href="http://pluu.github.io/blog/android/2020/05/01/migation-activity-result/">http://pluu.github.io/blog/android/2020/05/01/migation-activity-result/</a></p>
<p><strong>참고 내용</strong>
<a href="https://qiita.com/takahirom/items/658ebabea3dc8c1c5a6c">https://qiita.com/takahirom/items/658ebabea3dc8c1c5a6c</a>
이 링크는 일본 개발자 분이 나름 정리 해놓은 글이라 일본어 서술 되어 있어서 일본어를 아시는분에게 추천합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] Android Studio 4.1 - Dagger Navigation]]></title>
            <link>https://velog.io/@jojo_devstory/Android-Android-Studio-4.1-Dagger-Navigation</link>
            <guid>https://velog.io/@jojo_devstory/Android-Android-Studio-4.1-Dagger-Navigation</guid>
            <pubDate>Mon, 27 Apr 2020 09:52:58 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요!</p>
<p>오늘도 좋은 포스팅 하나 공유 합니다!</p>
<p><img src="https://images.velog.io/images/jojo_devstory/post/2882f204-9774-4000-b3df-3ed12f99eada/1*bVcgswg-IQ0lvbkkvhBZww.gif" alt="Dagger"></p>
<p>바로 안드로이드 스튜디오 4.1에 적용된 Dagger Navigation 입니다.</p>
<p>이 기능으로 해당 의존성이 어디서 사용되고 있고 어디서 주입이 되었는지 Inspector를 볼수가 있습니다.</p>
<p>자세한 내용은 아래에서 보시죠!</p>
<p><a href="https://link.medium.com/1jq1CldsV5">https://link.medium.com/1jq1CldsV5</a>
-Manuel Vivo</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] 이미지 로딩 라이브러리 - Coil 을 알아보자!😉]]></title>
            <link>https://velog.io/@jojo_devstory/Android-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%A1%9C%EB%94%A9-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-Coil-%EC%9D%84-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@jojo_devstory/Android-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%A1%9C%EB%94%A9-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-Coil-%EC%9D%84-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Wed, 22 Apr 2020 08:38:06 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요!</p>
<p>이번 포스팅은 이미지 로딩 라이브러리중 하나인 Coil에 대해 알아보겠습니다.</p>
<p>이미지 라이브러리라고 하면 제일 유명한 Glide, Fresco 등 많이 있지만</p>
<p>나름 장점이 있으니 제가 소개 해드릴까 합니다.</p>
<h2 id="1-coil-코일-넌-누구냐🙄">1. Coil??? 코일?? 넌 누구냐!🙄</h2>
<p><img src="https://images.velog.io/images/jojo_devstory/post/993fae96-2598-41a3-97c6-51575171afa2/%EC%BD%94%EC%9D%BC.gif" alt="https://shinycaterpie.tumblr.com/post/99332903043"> <strong><center>저는 듣자마자 이 녀석을 떠올렸습니다.</center></strong>
<strong><center>(포켓몬스터에 등장하는 포켓몬🧲👁🧲)</center></strong>
<br>
Coil은 <strong>Co</strong>routine <strong>I</strong>mage <strong>L</strong>oader의 약자이며 <strong>Kotlin Coroutines(코루틴)</strong>으로 만들어진 가벼운 <strong>Android 백앤드 이미지 로딩 라이브러리</strong>입니다.
그래서 코루틴자체가 내장이 되어 있어 코루틴 라이브러리를 별도로 설치하지 않아도 되는 장점이 있습니다.
현재 Coil의 관리 주체는 <a href="https://www.instacart.com">InstaCart</a>라고 하는 미국의 농작물 배송 서비스 업체에서 관리중이며 현재 자신들의 앱 서비스에 적용하여 사용 중 입니다. 그리고 인스타카트의 수석 엔지니어인 Colin White에 의해 처음 소개되었습니다.</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">It&#39;s finally public. I&#39;ve been working on this for the past few months - really excited to share it with the community. <a href="https://t.co/5rzMAakoWd">https://t.co/5rzMAakoWd</a></p>&mdash; Colin White (@colinwhi) <a href="https://twitter.com/colinwhi/status/1160943333033648128?ref_src=twsrc%5Etfw">August 12, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<h2 id="2-아니-glide-같은-좋은-라이브러리가-많은데-굳이🤔">2. 아니 Glide 같은 좋은 라이브러리가 많은데 굳이?🤔</h2>
<p>맞습니다. 이미 업계에서는 성능과 신뢰성이 검증되고 확실하게 자리잡은 이미지 라이브러리가 많습니다.
하지만 그럼에도 불구하고 Coil에는 이러한 장점이 있습니다.</p>
<h4 id="장점">장점</h4>
<ul>
<li>Glide, Fresco보다 상대적으로 가볍다.<br></li>
<li>코루틴이 기본이지만 메인까지는 아니며 심플함과 최소한의 보일러 플레이트(boilerplate)를 위하여 Kotlin의 기능을 활용하여 Kotlin을 잘 다룬다면 사용하기가 매우 쉽다.<br></li>
<li>메모리와 디스크의 캐싱, 메모리의 이미지 다운 샘플링, Bitmap 재사용, 일시정지/취소의 자동화 등등 수 많은 최적화 작업을 수행하므로 처리 속도가 굉장히 빠릅니다.<br></li>
<li>다이나믹 이미지 샘플링을 지원하며 이는 Coil에서 자동으로 알아서 처리됩니다.<br></li>
<li>Coil의 이미지 파이프라인(PipeLine)은 크게 세 가지로 구성됩니다.</li>
<li><em>Mappers, Fetchers, Decoders*</em> 이러한 인터페이스를 사용하여 기본 이미지 로딩 기능을 강화하거나 재정의하고 Coil에 새로운 파일 형식에 대한 지원을 추가할 수 있습니다.<br></li>
<li>Kotlin으로 개발 되었으며 Coroutines, OkHttp, Okio, AndroidX Lifecycles등의 최신 라이브러리를 사용합니다.</li>
</ul>
<p>하지만 단점 또한 명확 합니다.</p>
<h4 id="단점">단점</h4>
<ul>
<li>버전이 아직 정식버전이라고는 할 수 없어서 신뢰성이 낮아 실무에서 사용하는 기업이 많이 없다.</li>
<li>최소 Android SDK 버전 14부터 지원을 하나 최신버전에서 사용을 하는 것을 권장함.(AndroidX)</li>
<li>Kotlin을 모른다면 사용하기 어렵다.</li>
<li>일부 기능 사용을 위해 Coroutines이 무엇인지 개념적으로 어느정도 알아야 한다.</li>
</ul>
<h2 id="3-어떻게-프로젝트에-적용-할까요🧑🏻💻">3. 어떻게 프로젝트에 적용 할까요?🧑🏻‍💻</h2>
<p>간단하게 초기 적용법만 설명하겠습니다.</p>
<ol>
<li><p>먼저 gradle에 Coil을 추가합니다.</p>
<pre><code class="language-kotlin">implementation(&quot;io.coil-kt:coil:0.10.0&quot;)</code></pre>
</li>
<li><p>ImageView로 이미지를 로딩하기 위해, Coil의 load 메서드를 사용합니다.</p>
</li>
</ol>
<pre><code class="language-kotlin">// 각 방식은 아래와 같습니다.
// URL
imageView.load(&quot;https://www.example.com/image.jpg&quot;)

// Resource
imageView.load(R.drawable.image)

// File
imageView.load(File(&quot;/path/to/image.jpg&quot;))</code></pre>
<p>이게 다입니다. 정말 간단하죠?</p>
<ol start="3">
<li>추가로 이미지 핸들링을 하려면 trailing lambda 식을 이용하여 아래와 같이 추가 설정을 할 수 있습니다.<pre><code class="language-kotlin">// CircleCrop(이미지 원형으로 자르기) 예시
imageView.load(&quot;https://www.example.com/image.jpg&quot;) {
 crossfade(true)
 placeholder(R.drawable.image)
 transformations(CircleCropTransformation())
}</code></pre>
4가지의 Image Transformations을 제공합니다.</li>
</ol>
<ul>
<li><strong>BlurTransformation</strong>
이미지를 흐릿하게 보이기하는 가우시안 블러(Gaussian Blur)를 적용합니다.</li>
<li><strong>CircleCropTransformation</strong>
이미지의 중심을 기준으로 원형으로 이미지를 자릅니다. (예. 카카톡의 원형 프로필 이미지)</li>
<li><strong>GrayscaleTransformation</strong>
그레이스케일로 음영처리를 적용합니다.</li>
<li><strong>RoundedCornersTransformation</strong>
사이즈에 맞도록 이미지를 자르고 이미지 모서리를 둥글게 라운드를 적용합니다.</li>
</ul>
<h2 id="결론👍👍👍">결론👍👍👍</h2>
<p>직접 예제로 사용을 해보았는데 코일은 Kotlin기반의 안드로이드를 위한 가볍고 깔끔한 이미지 로딩 라이브러리 였습니다.
Kotlin 기반 이면서 최신 라이브러리가 듬뿍 적용되어 미래가 기대되는 이미지 라이브러리라고 생각하며 현재 업데이트도 활발히 이루어지고 있습니다.
성능면이나 사용성이나 다른 이미지 라이브러리에 별로라고 생각이 들지도 않네요.
하지만..... 아직까지는 국내에서 사용사례를 찾아보기 드물고 관련자료가 많이 없다보니 실무에 적용하기에는 이르지 않나 싶습니다.😭😢
그래도 한번 자신의 개인 프로젝트에 마이그레이션 하여 적용 및 사용해보는 경험 또한 나쁘지 않다고 생각합니다.😋</p>
<p><strong>참고 내용</strong>
<a href="https://coil-kt.github.io/coil/">https://coil-kt.github.io/coil/</a>
<a href="https://github.com/coil-kt/coil/blob/master/README-ko.md">https://github.com/coil-kt/coil/blob/master/README-ko.md</a>
<a href="https://android.jlelse.eu/taking-a-look-at-coil-217e1f02ef5e">https://android.jlelse.eu/taking-a-look-at-coil-217e1f02ef5e</a>
<a href="https://hub.packtpub.com/introducing-coil-an-open-source-android-image-loading-library-backed-by-kotlin-coroutines/">https://hub.packtpub.com/introducing-coil-an-open-source-android-image-loading-library-backed-by-kotlin-coroutines/</a>
<a href="https://tech.instacart.com/introducing-coil-kotlin-first-image-loading-on-android-f0fdc7a2a99e">https://tech.instacart.com/introducing-coil-kotlin-first-image-loading-on-android-f0fdc7a2a99e</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] 코로나 19 관련 Google Play 서비스 관련 알림]]></title>
            <link>https://velog.io/@jojo_devstory/Android-%EC%BD%94%EB%A1%9C%EB%82%98-19-%EA%B4%80%EB%A0%A8-Google-Play-%EC%84%9C%EB%B9%84%EC%8A%A4-%EA%B4%80%EB%A0%A8-%EC%95%8C%EB%A6%BC</link>
            <guid>https://velog.io/@jojo_devstory/Android-%EC%BD%94%EB%A1%9C%EB%82%98-19-%EA%B4%80%EB%A0%A8-Google-Play-%EC%84%9C%EB%B9%84%EC%8A%A4-%EA%B4%80%EB%A0%A8-%EC%95%8C%EB%A6%BC</guid>
            <pubDate>Tue, 21 Apr 2020 08:23:18 GMT</pubDate>
            <description><![CDATA[<p>현재 코로나 때문에 구글플레이 스토어에 대해 정책이 일시적으로 변경이 되었습니다.</p>
<p>하지만 요 정책이 일관적이게 적용이 되지 않아서 말도 많습니다.</p>
<p>가령 전혀 위배되지도 않았는데 앱 삭제가 된다던지 하는......</p>
<p>미리 확인해서 자신의 앱을 지킵시다!</p>
<p>자세한 정책 사항은 아래 Google Developer 국문 블로그 링크 참조 부탁드립니다!</p>
<p><a href="https://developers-kr.googleblog.com/2020/04/google-play-updates-and-information17.html">https://developers-kr.googleblog.com/2020/04/google-play-updates-and-information17.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] Realm이란? - SQLite보다 좋다던데...😕]]></title>
            <link>https://velog.io/@jojo_devstory/Android-Realm%EC%9D%B4%EB%9E%80-SQLite%EB%B3%B4%EB%8B%A4-%EC%A2%8B%EB%8B%A4%EB%8D%98%EB%8D%B0</link>
            <guid>https://velog.io/@jojo_devstory/Android-Realm%EC%9D%B4%EB%9E%80-SQLite%EB%B3%B4%EB%8B%A4-%EC%A2%8B%EB%8B%A4%EB%8D%98%EB%8D%B0</guid>
            <pubDate>Tue, 21 Apr 2020 07:15:32 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요.</p>
<p>이번 포스팅은 모바일에서 많이 사용하는 로컬DB의 하나인 Realm에 대하여 알아보겠습니다.</p>
<h2 id="1-realm이란🤨">1. Realm이란?🤨</h2>
<p>Realm(렘)이란 오픈소스 데이터베이스 관리시스템(DBMS)으로 특히, 모바일 환경을 주요 타깃으로 삼은 데이터베이스입니다.
기존 안드로이드에서 사용하던 SQLite와 iOS에서 사용하는 Core Data를 대체하는 모바일 데이터 베이스 입니다.
그래서 SQLite나 다른 SQL 데이터베이스와 관련이 없으며, 이들이 가진 많은 문제들을 해결하는 것을 목표로 합니다.
2010년도 후반기에 Alexander Stigsen, Bjarne Christiansen이라는 두 분이 TightDB라는 프로젝트명으로 시작했으며 2014년 Realm으로 이름을 변경하였고 점차 그 가치를 인정받아 실리콘밸리의 떠오르는 스타트업으로 자리 잡았습니다.
현재 Realm은 NoSQL의 대표주자인 MongoDB에 인수되었습니다.</p>
<h2 id="2-realm의-특징과-기능💾">2. Realm의 특징과 기능💾</h2>
<p>Realm 데이터베이스의 특징으로는 기존의 정형화된 데이터베이스와 다르게 NoSQL 데이터베이스를 지향합니다.</p>
<blockquote>
<p><strong>NoSQL이란?</strong>
단어 뜻 그 자체를 따지자면 &quot;Not only SQL&quot;로, SQL만을 사용하지 않는 데이터베이스 관리 시스템(DBMS)을 지칭하는 단어이다. 
관계형 데이터베이스를 사용하지 않는다는 의미가 아닌, 여러 유형의 데이터베이스를 사용하는 것이다.
데이터를 조직하는 방법에는 리스트, 해시 테이블, 트리, 그래프 등의 다양한 방법이 있고 각각은 장점과 단점이 명확하기 때문에 단순히 NoSQL이라고만 해서는 너무 뜬구름 잡는 얘기가 된다.
NoSQL이라는 단어는 RDBMS가 데이터베이스의 독점적인 지위를 차지하고 있는 현재 상황에 반발하는 정신을 담고 있다.
-나무위키</p>
</blockquote>
<p>데이터 모델 구조 자체가 객체 컨테이너로 구성되어 있습니다. 또한, <strong>Realm 데이터베이스는 rawSQL을 사용할 수 없으며 자체의 Realm API를 통해 실행</strong>됩니다. 이를 통해 좀 더 직관적인 사용이 가능해지고 데이터 처리 속도가 향상된 장점이 있지만, 기존 데이터베이스들과 달리 Realm의 자체 사용법에 대해 조금 더 공부를 해야 하는 러닝커브가 존재합니다.</p>
<p><img src="https://images.velog.io/images/jojo_devstory/post/a3ce716e-f7fb-48f1-a42e-30f2e619f1d2/1*SWLddOMTSeVv_np66p2xSg.png" alt="성능">
하지만 성능면에서는 현재까지 Realm이 으뜸이라고 생각하고 있고 실제로 Github에 많이 있는 Realm 예제코드를 이용해 사용해보니 그 성능에서 많은 차이가 났습니다.
위의 그래프에서도 보듯이 다른 로컬DB를 압도하고 있습니다.</p>
<p>장점을 간단하게 아래에 나열해보았습니다.</p>
<ul>
<li>기본적인 데이터 입출력인 모델, 쓰기, 읽기, 일반적인 쿼리 등을 제공.</li>
<li>AES-256 암호화를 지원</li>
<li>하나의 앱에서 다양한 데이터베이스를 사용할 수 있음.</li>
<li>Realm을 메모리에 저장하여 사용할 수 있음(In memory 기능)</li>
<li>Mac OS 에서는 Realm Studio 이용하여 Realm 파일을 보거나 수정이 가능.</li>
<li>가능한한 타입과 구조 변환을 최소화하여 객체를 직접 디스크에 유지함.</li>
<li>Listener, 마이그레이션 기능 제공.</li>
<li>Realm 공식 홈페이지에서는 한국어 <a href="https://realm.io/kr/docs/java/latest/">문서</a>를 제공함.</li>
<li><a href="https://github.com/realm/realm-java">Github</a>에서 진행사항을 확인 가능</li>
<li><a href="https://github.com/realm/realm-java/blob/master/CHANGELOG.md">패치노트</a> 관리가 잘되어있음.</li>
</ul>
<p>단점 입니다.</p>
<ul>
<li>다중 쓰레드에서의 Realm 객체 관리 (쓰레드별 객체 관리 필요함)</li>
<li>쓰레드 흐름에 익숙하지 않다면 거의 사용하기 힘들기 때문에 러닝커브가 어느정도 존재함.</li>
<li>바이너리 용량이 늘어남</li>
<li>다양한 쿼리를 지원하지 않음</li>
<li>iOS8부터 지원가능</li>
<li>알 수 없는 예외가 자주 발생함.</li>
</ul>
<h2 id="3-결론">3. 결론</h2>
<p>Realm은 현재 모바일에서 가장 많이 쓰이고 개발자들이 애용하는 로컬 DB가 되었습니다.
물론 SQlite가 무조건 안좋은게 아닙니다.
자신의 프로젝트 특성이나 자신이 잘 사용하는 정도에 따라 선택하여 프로젝트에 적용을 하면 되지만
Realm에 한번 적응하기 시작하면 사용성이나 성능면에서 SQlite가 따라올 수 없습니다.
근래에는 무선통신이 아주 빨라지고 네트워크 DB의 성능도 향상된 것이 사실입니다만 특정한 상황이나 빠른 로딩을 위해 로컬DB를 사용해야 하는 경우도 많습니다.
이럴 경우 고민을 하고 계신다면 Realm 사용을 추천해드립니다.</p>
<p><strong>참고 내용</strong>
<a href="https://realm.io/kr/docs/">https://realm.io/kr/docs/</a>
<a href="https://academy.realm.io/kr/posts/gdg-seoul-realm-introduce/">https://academy.realm.io/kr/posts/gdg-seoul-realm-introduce/</a>
<a href="https://academy.realm.io/kr/posts/realm-object-centric-present-day-database-mobile-applications/">https://academy.realm.io/kr/posts/realm-object-centric-present-day-database-mobile-applications/</a>
<a href="https://medium.com/@hesam.kamalan/database-benchmark-realm-vs-snappydb-f4b89711f424">https://medium.com/@hesam.kamalan/database-benchmark-realm-vs-snappydb-f4b89711f424</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] LiveData...넌 누구냐?]]></title>
            <link>https://velog.io/@jojo_devstory/Android-LiveData...%EB%84%8C-%EB%88%84%EA%B5%AC%EB%83%90</link>
            <guid>https://velog.io/@jojo_devstory/Android-LiveData...%EB%84%8C-%EB%88%84%EA%B5%AC%EB%83%90</guid>
            <pubDate>Sun, 19 Apr 2020 09:59:59 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요.</p>
<p>이번 포스팅의 주제는 LiveData 입니다.</p>
<p>안드로이 아키텍쳐 패턴(MVP, MVM, MVVM 등)에서 빠질 수 없는 것들이 몇가지 존재 하는데요.</p>
<p>그 중에서 저번시간에 소개드린 Databinding에 이어서 이번엔 LiveData입니다.
<a href="https://velog.io/@jojo_devstory/Android-Databinding%EC%9D%84-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90">https://velog.io/@jojo_devstory/Android-Databinding을-알아보자</a></p>
<p>둘이 같이 쓰면 정말 찰떡궁합인데요.🥳</p>
<p>역시나 이 녀석도 <strong>Android JetPack 라이브러리의 하나의 기능</strong> 입니다.</p>
<p>한번 이 녀석이 뭐하는 녀석인지 간단하게 개념만 알아보도록 합시다.</p>
<h2 id="1-livedata란">1. LiveData란?</h2>
<p>LiveData는 Data의 변경을 관찰 할 수 있는 Data Holder 클래스 입니다.
<strong>일반적인 Observable과는 다르게 LiveData는 안드로이드 생명주기(LifeCycle)를 알고 있습니다. (Lifecycle-Aware)</strong>
즉, 액티비티나, 프레그먼트, 서비스 등과 같은 안드로이드 컴포넌트의 생명주기(Lifecycle)를 인식하며 그에따라 <strong>LiveData는 활성상태(active)일때만 데이터를 업데이트(Update) 합니다.</strong>
활성상태란 <strong>STARTED</strong> 또는 <strong>RESUMED</strong>를 의미합니다.</p>
<p>또한 LiveData 객체는 Observer 객체와 함께 사용됩니다. LiveData가 가지고 있는 <strong>데이터에 어떠한 변화가 일어날 경우</strong>, LiveData는 등록된 <strong>Observer 객체에 변화를 알려주고</strong>, <strong>Observer의 onChanged() 메소드가 실행</strong>되게 됩니다.</p>
<h2 id="2-livedata가-어떻게-생명주기를-알아요">2. LiveData가 어떻게 생명주기를 알아요?</h2>
<p>바로 <strong>LifeCycleOwner</strong>이라는 녀석이 안드로이드 생명주기 (Android LifeCycle)를 알고 있는 클래스라 보면 됩니다.
메서드가 오직 <strong>getLifeCycle()</strong> 밖에 없는 ** 단일 메소드 인터페이스 클래스** 이며, Activity나 Fragment에서 이를 상속하고 있습니다.
한 마디로 LiveData의 Observer 메소드의 LifeCycleOwner를 Activity나 Fragment를 변수로써 사용한다면 각 화면 별 생명주기에 따라 LiveData는 자신의 임무를 수행 합니다.</p>
<h2 id="3-뭔-엄청좋은거-같은데장점이-뭐죠">3. 뭔 엄청좋은거 같은데....장점이 뭐죠..?</h2>
<ul>
<li><strong>Data와 UI간 동기화</strong>
LiveData는 Observer 패턴을 따릅니다. 그에따라 LiveData는 안드로이드 생명주기에 데이터 변경이 일어날 때마다 Observer 객체에 알려줍니다.
그리고 이 Observer 객체를 사용하면 데이터의 변화가 일어나는 곳마다 매번 UI를 업데이트하는 코드를 작성할 필요 없이 통합적이고 확실하게 데이터의 상태와 UI를 일치시킬 수 있습니다.</li>
<li><strong>메모리 누수(Memory Leak)가 없습니다.</strong>
Observer 객체는 안드로이드 생명주기 객체와 결합되어 있기 때문에 컴포넌트가 Destroy 될 경우 메모리상에서 스스로 해제합니다.</li>
<li><strong>Stop 상태의 액티비티와 Crash가 발생하지 않습니다.</strong>
액티비티가 Back Stack에 있는 것처럼 Observer의 생명주기가 inactive(비활성화) 일 경우, Observer는 LiveData의 어떤 이벤트도 수신하지 않습니다.</li>
<li><strong>생명주기에 대한 추가적인 handling을 하지 않아도 됩니다.</strong>
LiveData가 안드로이드 생명주기에 따른 Observing을 자동으로 관리를 해주기 때문에 UI 컴포넌트는 그저 관련 있는 데이터를 &quot;관찰&quot;하기만 하면 됩니다.</li>
<li><strong>항상 최신 데이터를 유지합니다.</strong>
화면 구성이 변경되어도 데이터를 유지합니다.
예를 들어, 디바이스를 회전하여 세로에서 가로로 화면이 변경될 경우에도 LiveData는 회전하기 전의 최신 상태를 즉시 받아옵니다.</li>
<li><strong>자원(Resource)를 공유할 수 있습니다.</strong>
LiveData를 상속하여 자신만의 LiveData클래스를 구현할 수 있고 싱글톤 패턴을 이용하여 시스템 서비스를 둘러싸면(Wrap) 앱 어디에서나 자원을 공유 할 수 있습니다.</li>
</ul>
<h2 id="4-livedata-사용시-주의-할-점">4. LiveData 사용시 주의 할 점</h2>
<p>LiveData 객체를 사용하기 위해서는 다음 내용을 알고 계시면 됩니다.</p>
<ul>
<li>Generic을 사용해 관찰하고자 하는 데이터의 타입(Type)을 갖는 LiveData 인스턴스를 생성합니다.
(보통 LiveData 객체는 안드로이드 아키텍쳐 패턴의 ViewModel 클래스 내에서 함께 사용됩니다.)<br></li>
<li>LiveData 클래스의 observe() 메소드를 사용해 Observer 객체를 LiveData 객체에 &quot;결합&quot; 합니다. 이때 observe() 메소드는 LifecycleOwner 객체를 필요로 하며 보통은 Activity를 전달합니다.
LiveData에 저장된 데이터에 어떠한 변화가 일어난 경우 결합된 LifecycleOwner에 의해서 상태가 active(활성)인 한 모든 데이터에 대해 Trigger가 발생합니다.<br></li>
<li>Observer 객체를 생성합니다..
생성시 LiveData가 들고있는 데이터가 변화가 일어났을 때 수행해야 할 로직이 들어있는 onChanged() 메서드를 정의해야 합니다.
보통은 액티비티나 프래그먼트 같은 UI Controller 내에서 해당 메서드를 생성합니다.<br></li>
<li>observeForever(Observer)를 통해 LifeCycleOwner 없이 Observer를 생성하여 등록할 순 있지만, 이 경우에는 Observer는 항상 active(활성) 상태이므로 데이터 변화를 항상 전달 받습니다. 단, removeObserver(Observer) 메소드를 통해 Observer를 제거 할 수 있습니다.</li>
</ul>
<h2 id="5-livedata의-간단한-사용법-예제-코드">5. LiveData의 간단한 사용법 (예제 코드)</h2>
<p>앞에서 설명드린 것 처럼 LiveData는 주로 안드로이드 아키텍처 패턴의 ViewModel과 함께 사용되기 때문에, 예제 코드도 ViewModel을 상속받아 클래스 내에서 정의한 LiveData로 작성했습니다.
ViewModel이 무엇인지 알고 싶으시다면 <a href="https://velog.io/@jojo_devstory?tag=%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98">이전 포스팅</a>들을 참조 바랍니다.</p>
<p><strong>예제 코드들은 Kotlin으로 작성했습니다.</strong></p>
<ol>
<li>ViewModel 클래스 생성
아래의 코드에서는 <strong>MutableLiveData</strong>를 사용했지만 불변(Immutable)객체로 LiveData&lt;&gt;를 사용해도 상관없습니다.<pre><code class="language-kotlin">class TestLiveDataViewModel : ViewModel() {
 // String 타입의 MutableLiveData 생성, by lazy로 초기화는 뒤에
 val textValue: MutableLiveData&lt;String&gt; by lazy {
     MutableLiveData&lt;String&gt;()
 }
}</code></pre>
위에서 만든 ViewModel 클래스 내의 LiveData 객체를 Activity에서 사용을 할텐데 대부분의 경우 <strong>LiveData에 Observer를 결합하는 코드는 컴포넌트의 onCreate() 메소드 내에 위치하는 것이 바람직합니다.</strong>
그 이유는 2가지가 있습니다.<ul>
<li>안드로이드 생명주기인 onResume()에 하게될 경우 <strong>pause()</strong> 나 <strong>stop()</strong> 에 의해서 잠시 백그라운드 상에서 inactive(비활성화)된 앱이 다시 active(활성화)가 되면서 LiveData에 대한 코드가 <strong>중복호출</strong>이 될 수 있기 때문입니다. 
이는 앞에서 설명드렸던 내용들 중에 LiveData의 장점 중 <strong>{생명주기에 대한 추가적인 handling을 하지 않아도 됨}</strong>에 대해 반대되는 잘못된 방식입니다. </li>
</ul>
</li>
</ol>
<ul>
<li>액티비티나 프래그먼트가 active(활성화) 되자마자 UI에 표시 할 수 있는 데이터를 가질 수 있기 때문에 해당 컴포넌트는 <strong>STARTED</strong> 상태가 되자마자 LiveData 객체로부터 <strong>가장 최신의 값을 수신</strong>해야 합니다.</li>
</ul>
<ol start="2">
<li><p>메인 액티비에의 onCreate에 Observer를 세팅합니다.</p>
<pre><code class="language-kotlin">class MainActivity : AppCompatActivity() {
 // 전역 변수로 ViewModel lateinit 세팅
 private lateinit var model: TestLiveDataViewModel

 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)

     // ViewModel을 가져옵니다.
     model = ViewModelProvider(this).get(TestLiveDataViewModel::class.java)

     // Observer를 생성한 뒤 UI에 업데이트 시켜 줍니다.
     val testObserver = Observer&lt;String&gt; { textValue -&gt;
         // 현재 MainActivity에는 TextView가 하나만 존재합니다.
         // 다른 데이터를 받는 UI 컴포넌트가 있다면 같이 세팅 해줍니다.
         tv_livedata_test.text = textValue
     }

     // LiveData를 Observer를 이용해 관찰하고
     // 현재 Activity 및 Observer를 LifecycleOwner로 전달합니다.
     model.textValue.observe(this, testObserver)
 }
}</code></pre>
</li>
</ol>
<h2 id="6-결론">6. 결론</h2>
<p>LiveData를 통해서 UI를 업데이트하는 경우 일반적으로 Activity나 Fragment 내에서 직접 선언하는 것보다 위의 예제처럼 <strong>ViewModel</strong> 내에서 정의하고 호출하여 사용하는 것이 더 좋습니다.
이유는 다들 ViewModel이 뭔지 알고 계시듯이 <strong>액티비티와 데이터 간의 결합도를 낮추고(의존성)</strong>, <strong>UI Controller는 오직 data를 display만 하는 것을 수행</strong>하게 하는 안드로이드 아키텍처 패턴(디자인)을 유지하기 위해서입니다.</p>
<p>까놓고 말해서 LiveData는 그냥 LiveData만 쓰면 좋은점을 크게 느끼기 힘듭니다.
하지만 <strong>Databinding, ViewModel, RoomDatabase, Reactive Programing</strong>등과 함께 쓸 경우 그 진가가 발휘되며 개발자는 아주 편하게 코딩이 가능하기 때문에 UI 출력 데이터에 관한 실수 또한 줄여줍니다.</p>
<p><strong>참고내용</strong>
<a href="https://developer.android.com/topic/libraries/architecture/livedata?hl=ko">https://developer.android.com/topic/libraries/architecture/livedata?hl=ko</a>
<a href="https://www.charlezz.com/?p=363">https://www.charlezz.com/?p=363</a>
<a href="https://aonee.tistory.com/entry/Android-ACC-MVVM%ED%8C%A8%ED%84%B4-Repository-LiveData-DataBinding-%EA%B3%B5%EB%B6%80-%ED%9B%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EC%97%90-%EC%A0%81%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0">https://aonee.tistory.com/entry/Android-ACC-MVVM패턴-Repository-LiveData-DataBinding-공부-후-프로젝트에-적용해보기</a>
<a href="https://readystory.tistory.com/101">https://readystory.tistory.com/101</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] Databinding을 알아보자!😎]]></title>
            <link>https://velog.io/@jojo_devstory/Android-Databinding%EC%9D%84-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@jojo_devstory/Android-Databinding%EC%9D%84-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Sat, 18 Apr 2020 13:19:30 GMT</pubDate>
            <description><![CDATA[<h2 id="1-databinding이란">1. Databinding이란?</h2>
<p>Android 생태계에서 이미 많이 사용되고 있는 DataBinding(데이터바인딩)은 간단하게 xml파일에 Data를 연결(binding)해서 사용할 수 있게 도와주며 <strong>Android JetPack 라이브러리의 하나의 기능</strong> 입니다.</p>
<p>즉, 데이터바인딩은 애플리케이션 로직과 레이아웃을 binding하는 데 필요한 <strong>글루 코드</strong>를 최소화합니다.</p>
<blockquote>
<p>글루 코드란?
프로그램의 요구사항 구현에는 기여하지 않지만, 본래 호환성이 없는 부분끼리 결합하기 위해 작동하는 코드
-제타위키</p>
</blockquote>
<p>내용이 이렇다 보니 findViewById를 사용하지 않아도 되며 보통 <strong>MVVM 패턴을 구현 할 때 &quot;LiveData&quot;와 함께 거의 필수적으로 사용</strong>합니다.</p>
<h2 id="2-databinding의-간단한-기본-사용법">2. Databinding의 간단한 기본 사용법</h2>
<p>먼저 샘플용으로 만들어 볼 앱은 메인 화면의 TextView에 &quot;Hello World!&quot;가 표시되고 Button을 Click하게 되면 TextView에 &quot;Hello Databinding!&quot;이 출력 됩니다.
코드는 코틀린으로 진행합니다.</p>
<p>먼저 graddle에서 아래의 세팅의 추가 합니다.
 kotlin-kapt plugin이 설치가 되어 있지 않다면 해당 세팅 값에 마우스를 올려두면 설치하라고 메시지가 뜨는데 설치해주시면 됩니다.</p>
<pre><code class="language-kotlin">android {
    ...
   dataBinding {    
        enabled true
   }
}</code></pre>
<p>그 후 데이터바인딩을 설정할 액티비티 뷰의 xml로 이동해서 소스를 열어봅니다.
최상단 루트를 layout 태그로 감싸줍니다.
기존의 xml 소스를 수정하는거라면 기존 최상단 레이아웃(예. ConstraintLayout 등)을 &quot;layout&quot; 바로 아래로 내리시면 됩니다.
그 후 이벤트를 만들때 참조할 데이터바인딩 변수명이 필요하니 <strong>data</strong>, <strong>vairable</strong> 태그를 추가하고 name에는 변수명을, type에는 데이터 바인딩을 통한 이벤트를 세팅할 (내 패키지명 + 액티비티 명 또는 프래그먼트 명)을 적어주면 됩니다.</p>
<ol>
<li><p>MainActivity이며 TextView만 Button을 추가한 ConstraintLayout의 xml 입니다.</p>
<pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout     xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
 xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
 xmlns:tools=&quot;http://schemas.android.com/tools&quot;
 android:layout_width=&quot;match_parent&quot;
 android:layout_height=&quot;match_parent&quot;
 tools:context=&quot;.MainActivity&quot;&gt;

 &lt;TextView
     android:id=&quot;@+id/hello_text_view&quot;
     android:text=&quot;Hello!&quot;
     android:layout_width=&quot;wrap_content&quot;
     android:layout_height=&quot;wrap_content&quot;
     app:layout_constraintLeft_toLeftOf=&quot;parent&quot;
     app:layout_constraintRight_toRightOf=&quot;parent&quot;
     app:layout_constraintTop_toTopOf=&quot;parent&quot;
     app:layout_constraintBottom_toBottomOf=&quot;parent&quot;/&gt;

 &lt;Button
     android:id=&quot;@+id/btn_change&quot;
     android:text=&quot;Text Change!&quot;
     android:layout_width=&quot;wrap_content&quot;
     android:layout_height=&quot;wrap_content&quot;
     app:layout_constraintLeft_toLeftOf=&quot;parent&quot;
     app:layout_constraintRight_toRightOf=&quot;parent&quot;
     app:layout_constraintTop_toBottomOf=&quot;@+id/hello_text_view&quot;
     app:layout_constraintBottom_toBottomOf=&quot;parent&quot;/&gt;
</code></pre>
</li>
</ol>
<p>&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;</p>
<pre><code>
2. 여기에서 최상단의 ConstraintLayout을 layout 아래로 둡니다.
  그리고 **data**, **variable**을 추가합니다.
```xml
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;layout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;&gt;

    &lt;data&gt;
      &lt;variable
         name=&quot;main&quot;
         type=&quot;com.joel.jojo.MainActivity&quot;/&gt;
    &lt;/data&gt;

    &lt;androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        tools:context=&quot;.MainActivity&quot;&gt;

        &lt;TextView
            android:id=&quot;@+id/hello_text_view&quot;
            android:text=&quot;Hello!&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            app:layout_constraintLeft_toLeftOf=&quot;parent&quot;
            app:layout_constraintRight_toRightOf=&quot;parent&quot;
            app:layout_constraintTop_toTopOf=&quot;parent&quot;
            app:layout_constraintBottom_toBottomOf=&quot;parent&quot;/&gt;

        &lt;Button
            android:id=&quot;@+id/btn_change&quot;
            android:text=&quot;Text Change!&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            app:layout_constraintLeft_toLeftOf=&quot;parent&quot;
            app:layout_constraintRight_toRightOf=&quot;parent&quot;
            app:layout_constraintTop_toBottomOf=&quot;@+id/hello_text_view&quot;
            app:layout_constraintBottom_toBottomOf=&quot;parent&quot;/&gt;

    &lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;
&lt;/layout&gt;</code></pre><ol start="3">
<li><p>그리고 세팅한 xml의 액티비티 소스로 이동합니다.</p>
<pre><code class="language-kotlin">class MainActivity : AppCompatActivity() {
 // xml 파일명이 카멜케이스로 클래스가 자동생성 됩니다.
 private lateinit var binding: ActivityMainBinding

 var text = &quot;Hello!&quot;

 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     // binding 세팅
     binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
     // 현재 binding시킨 xml의 variable name
     binding.main = this
     // binding 버튼 클릭 이벤트
     binding.btnChange.setOnClickListener {
         text = &quot;Hello Binding!&quot;
         // Data가 변동될 경우 binding된 View들에 Data 변화를 알려줌
         binding.invalidateAll()
     }
 }
}</code></pre>
</li>
</ol>
<h2 id="3-결론">3. 결론</h2>
<p>위 샘플용 코드는 간단하게 어떤 형식으로 사용을 하는지 알아보는 예제 입니다.
단순하게 하나의 TextView를 사용하여 Text를 바인딩 하기 때문에 이게 어디가 좋다는거지???라고 하실 수 있겠으나 xml에 DTO 또는 데이터 집합 클래스를 Bind 해서 해당 클래스가 변경되면 연결된 여러개의 View가 한번에 변경되기 때문에 엄청나게 편해집니다.
또 Databinding과 같이 <strong>BindingAdapter</strong>를 이용해 ImageView에 Glide, Fresco 같은 이미지 로딩 라이브러리를 이용해서 이미지를 출력을 쉽게 할 수 있고 Databinding과 찰떡궁합인 <strong>LiveData</strong>를 사용하면 Data가 실시간으로 변경될 때 View도 같이 변경되니 <strong>MVVM 패턴</strong> 구현 시 엄청나게 편리해집니다.</p>
<p>정리하면 다음과 같습니다.</p>
<ol>
<li>Databinding을 사용하면 findViewById(), 버터나이프를 쓰지 않아도 xml에 만든 View들을 자동으로 만들어 준다.</li>
<li>Data가 바뀌면 알아서 바뀐 Data로 View를 변경하게 할수도 있다. (옵저블 사용시)</li>
<li>RecyclerView에서 각각의 item을 세팅 해주는 작업도 xml에서 다 써주면 알아서 척척 값이 들어간다. (요거 엄청 편리합니다.)</li>
<li>JakeWharton의 Butterknife가 Deprecated 되었고 구글에서 권장하므로 앞으로는 Databinding을 사용 해야한다.</li>
</ol>
<p>본 포스팅은 내용이 지속적으로 업데이트 됩니다.</p>
<p><strong>참고내용</strong>
<a href="https://developer.android.com/topic/libraries/data-binding">https://developer.android.com/topic/libraries/data-binding</a>
<a href="https://developer.android.com/jetpack?hl=ko">https://developer.android.com/jetpack?hl=ko</a>
<a href="https://www.vogella.com/tutorials/AndroidDatabinding/article.html">https://www.vogella.com/tutorials/AndroidDatabinding/article.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DI(Dependency Injection)에 대해 알아보자]]></title>
            <link>https://velog.io/@jojo_devstory/DIDependency-Injection%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@jojo_devstory/DIDependency-Injection%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Thu, 16 Apr 2020 09:00:38 GMT</pubDate>
            <description><![CDATA[<p>요즘들어 삘을 받아서 폭풍 포스팅 중 입니다.🤗</p>
<p>이번 포스팅은 DI(Dependency Injection) - 의존성 주입에 대한 내용인데요.</p>
<p>먼저 DI가 무엇인지 알아보고 안드로이드에서 많이 쓰이는 DI 라이브러리들을 간단히 무엇이 있는지 알아보도록 하겠습니다.</p>
<h2 id="1-di의존성주입-이걸-왜-하나요🤔">1. DI...의존성...주입??? 이걸 왜 하나요??🤔</h2>
<p>자 먼저 의존성이란것을 알아보도록 합시다.</p>
<p>(1) 의존성이란?
가령 직장인이 출근을 할때 직장이 멀다면 교통수단에 <strong>의존</strong>해서 출근을 해야합니다.
프로그래밍에서도 <strong>의존</strong>은 뜻이 같습니다. <strong>의존성은 함수에 필요한 클래스 또는 참조변수나 객체에 의존하는 것</strong>이라고 볼 수 있습니다.</p>
<p>(2) 주입이란?
그렇다면 위의 함수에 필요한 클래스 또는 참조변수나 객체 같은 것들은 어떻게 생성될까요?
직접 생성하거나 누군가 생성해준 것을 이용하는 방법이 있지만 이럴때 DI(의존성 주입)를 사용합니다. 보통은 내부에서 필요한 내용(객체)을 생성하여 참조/사용을 내부가 아니라 <strong>외부에서 객체를 생성해서 넣어주는 것을 주입</strong>한다고 합니다. 그렇기 때문에 개발자들이 객체를 생성하는 번거로움과 다양한 테스트 케이스를 고려하는 경우를 줄이고 변수 사용과 개발에 더욱이 집중할 수 있게 해주며 <strong>클래스간의 결합도(coupling)를 낮추어 의존성을 줄입니다.</strong></p>
<p>의존성 주입이란 정리하면 이렇습니다.</p>
<ul>
<li>코드에서 두 모듈 간의 연결의 의미함.</li>
<li>일반적으로 둘 중 하나가 다른 하나를 어떤 용도를 위해 사용함.</li>
<li>객체지향언어에서는 두 클래스 간의 관계라고도 말함.</li>
<li>클래스간의 의존성이 줄어들면 유지보수시 매우 편함.</li>
</ul>
<p>자 그럼 장점 또한 정리해보겠습니다.</p>
<ul>
<li>Unit Test가 용이해짐.</li>
<li>코드의 재사용성을 높여준다.</li>
<li>리팩토링이 수월함.</li>
<li>객체 간의 의존성(종속성)을 줄이거나 없앨 수 있음.</li>
<li>객체 간의 결합도(coupling)를 낮추면서 유연한 코드를 작성할 수 있음.</li>
<li>보일러 플레이트 코드 감소.</li>
<li>스코프를 이용한 객체 관리.</li>
</ul>
<p>다만 단점도 있습니다.</p>
<ul>
<li>의존성 주입을 위한 선행작업이 필요함.</li>
<li><strong>코드를 추적하고 읽기가 어려워짐.</strong></li>
</ul>
<p>자신이 처음부터 개발했던 프로젝트라면 모르겠으나 중간에 투입이되어 소스를 파악(Reading)해야하는 상황이라면 소스를 처음보기 때문에 코드를 추적하고 읽기가 어렵습니다.
<del>하지만 장점이 더 많고 일단 유지보수하기가 용이해지므로 단점은 넘어가도록 합시다😜</del></p>
<h2 id="2-의존성-주입-예시🧑🏻💻">2. 의존성 주입 예시🧑🏻‍💻</h2>
<p><img src="https://images.velog.io/images/jojo_devstory/post/70f2f49d-d9ec-4abe-98b4-c7aa67d690be/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202020-04-16%20%EC%98%A4%ED%9B%84%203.06.53.png" alt="동숲맨"> <strong><center>저는 어릴때부터 게임을 엄청좋아해서 간단하게 게임에 빗대어 예를 들어보겠습니다.</center></strong></p>
<p>가령 &quot;<a href="https://www.nintendo.co.kr/software/switch/acbaa/">동물의 숲</a>&quot;이라는 게임에서 쇠로된 도끼, 쇠로된 삽을 만드려면 철광석이 필요합니다.</p>
<p>각 도구별로 <strong>공통적</strong>으로 철광석이 1개씩 있어야 합니다.</p>
<p>코드로 표현하면 아래와 같습니다.</p>
<pre><code class="language-kotlin">  // 철광석 클래스
  class IronNugget {
    ...
  }

  // Axe클래스 내부에서 IronNugget 클래스를 생성하여 사용
  class Axe {
      val ironNugget = IronNugget()
    ...
  }

  // Shovel 클래스 내부에서 IronNugget 클래스를 생성하여 사용
  class Shovel {
      val ironNugget = IronNugget()
    ...
  }</code></pre>
<p>이렇게 되면 의존성이 생기게 되는데요 도끼(Axe)라는 클래스가 내부에서 철광석(IronNugget)이라는 클래스를 참조하는 경우 <strong>도끼 클래스 -&gt; 철광석 클래스 형식으로 의존성을 갖는다</strong>고 말할 수 있습니다.
삽(Shovel) 클래스도 마찬가집니다.</p>
<p>근데 이렇게 <strong>의존성이 생기게 되면 철광석 클래스의 변화가 생기면 의존성을 갖는 도끼 클래스도 같이 변경을 해야하는 문제가 발생</strong>합니다.
만약 <strong>철광석 클래스가 바뀌면 철광석 클래스의 의존성을 갖는 모든 클래스가 변경</strong>이 되어야 합니다.
애플리케이션의 규모가 작아서 철광석 클래스에 의존성을 갖는 클래스가 한 두개라면 상관이 없겠지만 애플리케이션의 규모가 커지면서 점점 의존성을 갖는 클래스가 많아지면 유지보수시 개판5분전이 되기 시작합니다. <del>🔥🔥🔥🧑🏻‍💻신난다! 워라밸 끝!</del></p>
<p>만약 <strong>철광석 클래스에 의존성이 생긴다고 가정</strong>해본다면 아래와 같이 <strong>생성자를 추가</strong>하여 바뀌어야 합니다.</p>
<p>예시 코드로 확인해보겠습니다.</p>
<pre><code class="language-kotlin">  // 바위 클래스
  class Rock {
    ...
  }

  // 철광석 클래스
  class IronNugget(val rock: Rock) { {
    ...
  }

  // Axe클래스 내부에서 IronNugget 클래스를 생성하여 사용
  class Axe {
      val ironNugget = IronNugget(Rock()) // &lt;-- 변경됨
    ...
  }

  // Shovel 클래스 내부에서 IronNugget 클래스를 생성하여 사용
  class Shovel {
      val ironNugget = IronNugget(Rock()) // &lt;-- 변경됨
    ...
  }</code></pre>
<p>저는 <strong>클래스 생성에서 의존성을 주입</strong>을 했습니다.
즉, 철광석(IronNugget) 클래스에 바위(Rock) 클래스에 대한 의존성을 생성자를 이용하여 주입(Injection)했습니다.
의존하는 클래스를 직접 생성하는 것이 아닌, 주입해줌으로써 객체 간의 결합도를 줄이고 좀 더 유연한 코드를 작성할 수 있게됩니다.</p>
<p>이때 외부에서 객체를 관리하게 되는데 이를 IOC(inversion of Control, 제어의 역전)라 합니다.
IOC는 객체의 생성부터 생명주기(LifeCycle) 관리까지 컨테이너에 의해 제어 되는 것을 의미하며 의존성 주입(DI)은 객체간의 의존성을 자기 자신이 아닌 외부에서 주입받는 개념입니다.</p>
<p><strong>&quot;외부에서 제어 및 객체간의 의존성을 최소화 한다&quot;</strong> 
여기서 무엇인가 눈치 챈 분들이 계실텐데 그렇습니다.
아키텍쳐 패턴들(MVP, MVM, MVVM)에서 중점적으로 보이는 장점중의 하나입니다.
그래서 해당 모델들을 구현할때는 DI 라이브러리를 사용하는 것이 개발함에 있어 이제는 필수중의 필수가 되었습니다.</p>
<h2 id="3-하지만-일일히-di의존성-주입하기엔-너무-귀찮다-라이브러리를-쓰자">3. 하지만 일일히 DI(의존성 주입)하기엔 너무 귀찮다.. 라이브러리를 쓰자!!</h2>
<p>자 우리가 누굽니까?
귀찮은것을 극도로 싫어하는 개발자들 입니다.
이를 간단히 해결하려면 어떻게 해야 할까요??
잘 만들어진 DI 라이브러리를 사용하는겁니다.</p>
<p>대표적인 안드로이드 DI 라이브러리는 다음과 같습니다.</p>
<ul>
<li>Dagger2
Dagger2는 자바와 안드로이드를 위해 만들어진 컴파일타임 의존성주입 프레임워크 입니다.
원래는 Square라는 회사에서 주도적으로 개발하였으나(Dagger) 지금은 구글이 관리하고 있는중(Dagger2)입니다.
여기서 말하는 Dagger는 모두 Square의 Dagger를 포크(Fork)하여 Google이 만든 Dagger2를 뜻합니다.
Dagger2는 추적 가능한 보일러 플레이트 자바 코드를 컴파일 타임에 자동으로 생성하고 리플렉션 사용이 없기 때문에 많은 안드로이드 개발자들이 사용하고 있습니다.</li>
<li>Koin
Koin은 코틀린을 위한 DI 라이브러리로 러닝커브(학습곡선)가 가파른 Dagger에 비해 상대적으로 낮은 러닝커브를 가지고 있고 <strong>순수 코틀린만으로 작성</strong>이 되어있으며 어노테이션(@) 프로세싱을 및 리플렉션을 사용하지 않기 때문에 상대적으로 더 가볍습니다.
또한 아키텍처 중에 하나인 VM(ViewModel)을 이용하기 위해 별도의 라이브러리도 제공하고 있기 때문에 아주 쉽게 MVVM 패턴을 만들 수 있습니다. 하지만 아직 UI의 Controller별 Scope 관리 및 Compile 시간에 오류를 확인하는 등의 기능은 Dagger에 비해서 많이 좀 아쉽습니다. 물론 유닛테스트 단계를 통해서 Runtime시 에러가 발생하는 것을 방지할 수는 있습니다.
계속 발전하는 신규 라이브러리라 더욱 기대가 되지만 현재로서는 2019 Android Dev Summit에서 구글이 Dagger2를 권장을 했고 Dagger2가 이미 업계에서 굳건히 버티고 있어 기업에서 사용하는 경우를 찾기 힘드네요.
더 자세한 내용은 <a href="https://insert-koin.io">Koin 오피셜 사이트</a>에서 확인 부탁드립니다.</li>
</ul>
<h2 id="4-결론">4. 결론</h2>
<p>DI 또는 DI 라이브러리를 사용하면 관심사를 분리 했으므로 객체를 생성하는 부분과 아닌 부분이 나뉘어지게 되며 클래스간의 결합도가 크게 줄어들어 의존성도 줄어들게 되니 리팩토링 및 유닛테스트가 쉬워집니다. 또한 주입되는 모듈 코드를 재사용할 수 있으니 보일러 플레이트 코드도 줄어들게 됩니다.
그래서 이래저래 장점이 더 많다보니 요즘은 앱 개발시 필수라고 할 수 있겠습니다.</p>
<p><strong>참고 내용</strong>
<a href="https://ko.wikipedia.org/wiki/%EC%9D%98%EC%A1%B4%EC%84%B1_%EC%A3%BC%EC%9E%85">https://ko.wikipedia.org/wiki/의존성_주입</a>
<a href="https://medium.com/@jang.wangsu/di-dependency-injection-%EC%9D%B4%EB%9E%80-1b12fdefec4f">https://medium.com/@jang.wangsu/di-dependency-injection-이란-1b12fdefec4f</a>
<a href="https://velog.io/@wlsdud2194/what-is-di">https://velog.io/@wlsdud2194/what-is-di</a>
<a href="https://www.charlezz.com/?p=1259">https://www.charlezz.com/?p=1259</a>
<a href="https://jungwoon.github.io/android/2019/08/21/Koin/">https://jungwoon.github.io/android/2019/08/21/Koin/</a></p>
<p><strong>도움이 많이 된 도서</strong>
아키텍처를 알아야 앱 개발이 보인다, 옥수환 저 | 비제이퍼블릭(BJ퍼블릭)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] RxKotlin, RxAndroid란? - Reactive Programing]]></title>
            <link>https://velog.io/@jojo_devstory/Android-RxKotlin-RxAndroid%EB%9E%80-Reactive-Programing</link>
            <guid>https://velog.io/@jojo_devstory/Android-RxKotlin-RxAndroid%EB%9E%80-Reactive-Programing</guid>
            <pubDate>Wed, 15 Apr 2020 09:55:07 GMT</pubDate>
            <description><![CDATA[<p>이번 포스팅은 Reactive Programing에 대하여 이야기 해보겠습니다.</p>
<p>그중에서도 안드로이드에서 제일 많이 쓰이는 RxKotlin, RxAndroid에 대해서 개념만 살짝 짚어보고자 합니다.</p>
<h2 id="1-rx-그게-뭐죠-먹는건가요---reactive-programing-🤨">1. RX? 그게 뭐죠? 먹는건가요? - Reactive Programing 🤨</h2>
<p>RxKotlin, RxAndroid을 알아보기전에 먼저 알아볼것이 있습니다.
바로 <strong>Reactive Programing</strong> 입니다.</p>
<p>컴퓨터 프로그램에는 세가지 종류가 있는데요.</p>
<ul>
<li>1.주어진 입력 값을 바탕으로 결과를 계산하는 변환 프로그램이며 일반적으로 컴파일러와 수치 계산 을 하는 프로그램입니다.</li>
<li>2.상호작용 프로그램으로 프로그램이 작업을 주도하며 사용자 혹은 다른 프로그램과 상호작용을 합니다. 사용자의 관점에서 볼때는 흔히 말하는 시분할 시스템은 상호작용 프로그램입니다.</li>
<li>3.리액티브 프로그램은 <strong>프로그램 자신의 주변 환경과 끊임없이 상호작용을 하는데 프로그램이 주도하는 것이 아니라 환경이 변하면 이벤트를 받아 동작합니다.</strong> </li>
</ul>
<p>즉, 근래에 떠오르고 있는 <strong>Reactive Programing는 데이터의 흐름과 전달에 관한 프로그래밍 패러다임</strong>이라고 볼 수 있겠습니다.</p>
<p><strong>(1) 그렇다면 왜 사용할까요?</strong>
자 한번 개발자적인 측면에서 생각해보면 간단합니다.
우리 개발자들은 사용자 경험(UX)을 향상시키고 싶어합니다. 사용자 경험(UX)이 좋은 앱을 만든다는것은 반응형 앱을 개발하고 싶은 것 입니다.
그래서 앱에서 메인스레드가 멈추거나 느려지지 않도록 해야하며 사용자들에게 부드러운 사용자 경험(UX)과 좋은 앱 성능을 제공하고 싶어 합니다.
하지만 메인 스레드를 자유롭게 핸들링 하면서 유지하려면 무겁고 시간이 오래 걸리는 작업은 백그라운드에서 해야 합니다. 그리고 백그라운드에서 조차 무겁고 복잡한 계산 작업이라면 서버에서 수행 하는 것이 Best 입니다. 그렇기 때문에 <strong>네트워크 운영을 위한 비동기 작업이 필요합니다.</strong></p>
<p><strong>(2) 비동기 작업은 AsyncTask로도 되지 않나요?</strong>
맞습니다.
하지만 <strong>2019년 11월 8일 개발자 Charles Munger에 의해 공식적으로 AsyncTask Deprecated되었습니다.</strong> 즉, 다른 비동기 처리 라이브러리를 써야한다는 것이죠.
그렇다면 왜 이런 상황이 되었나 하고 AsyncTask를 자세히 살펴볼 필요가 있습니다.</p>
<p>현재도 그렇고 과거에도 그랬지만 많은 애플리케이션이 대표적으로 가지는 문제는 서버로부터 데이터를 가져오는 길고 긴 백그라운드 작업입니다. 네트워크 작업은 시간이 짧다면 상관이 없지만 오래 걸리는 상황이 잦기 때문에 비동기적으로 서버에 요청하고 데이터를 받아서 UI 업데이트를 하는 것이 중요합니다. 하지만 네트워크 요청이 완료 될 때 UI와 관련 된 부분에 어떠한 문제가 있어 더 이상 존재하지 않거나 에러가 발생하여 충돌 또는 버그가 발생할 수 있는 근본적인 문제가 있습니다. 이건 일반적인 스레드 프로그래밍이 가지고 있는 위험성과 크게 다르지 않습니다. 
AsyncTask는 전체적인 프로세스를 단순화 하지만 <strong>안드로이드의 생명주기를 신경쓰지 않습니다.</strong> 그렇기 때문에 <strong>액티비티나 프레그먼트가 안드로이드 생명주기에 의해 재생성되거나 파괴되었을 때 마무리 작업에 대한 내용이 보호되지 않는 불편한 점이 있습니다.</strong>
이러한 단점 외에도 기타 단점이 여럿 존재합니다.</p>
<p><strong>(3) 명령형 프로그래밍과 다르다!</strong></p>
<ul>
<li><p>명령형 프로그래밍(Imperative programming) – 작성된 코드가 정해진 순서대로 실행됨.</p>
</li>
<li><p>리액티브 프로그래밍(Reactive Programing) – 데이터 흐름을 먼저 정의하고 데이터가 변경되었을 때 연관되는 함수나 메서드가 업데이트 되는 방식.</p>
<p><img src="https://images.velog.io/images/jojo_devstory/post/8d404c9f-123d-4ee9-9fd7-9b1f15af95cb/r_2250357_bGndJ.jpg" alt="FvsR"><strong><center>함수형 프로그래밍을 하다보면 비동기 처리가 아쉽기 때문에 리액티브에 절로 눈이가게 됩니다🤤</center></strong></p>
<br>

</li>
</ul>
<p><strong>(4) 그래서 ReactiveX가 나왔다!</strong>
<a href="http://reactivex.io/intro.html">ReactiveX</a>는 <strong>비동기 프로그래밍과 Observable 시퀀스를 이용해 이벤트를 처리하기위한 라이브러리</strong>입니다.</p>
<h2 id="2-아하-이제-알겠어요-rxkotlin-rxandroid도-같은-건가요-🙋🏻">2. 아하! 이제 알겠어요! RxKotlin, RxAndroid도 같은 건가요? 🙋🏻</h2>
<p>사실 현재 많은 리액티브 관련 라이브러리가 나와 있는데 대부분 ReactiveX를 사용하기 때문에 RxKotlin, RxJava, RxAndroid, RxSwift 등들은 서로 다른 것이 아니라 하나의 ReactiveX Extensions이라고 보면 되겠습니다.
간단히 정리하면 아래와 같습니다.</p>
<ul>
<li><strong>RxJava: Java(JVM)를 위한 ReactiveX Extensions</strong></li>
<li><em>Reactive programming(리액티브 프로그래밍) 패러다임을 자바에서 구현*</em>한 프로그래밍 라이브러리</li>
<li><strong>RxKotlin: Kotlin을 위한 ReactiveX Extensions</strong>
RxJava 라이브러리를 기반으로 포팅하여 코<strong>틀린을 위한 리액티브 프로그래밍의 특정 부분을 함수형 프로그래밍으로써 구현</strong>한 라이브러리</li>
<li><strong>RxAndroid: Android를 위한 ReactiveX Extensions</strong>
RxJava에 최소한의 클래스를 추가하여 <strong>안드로이드 앱에서 리액티브 구성요소를 쉽고 간편하게 사용</strong>하게 만드는 라이브러리</li>
<li><strong>RxSwift: Swift를 위한 ReactiveX Extensions</strong><br>

</li>
</ul>
<p>위의 ReactiveX Extensions에는 공통점이 있습니다.</p>
<ul>
<li>효율적으로 신속하게 비동기 처리를 도와줌</li>
<li>함수형 프로그래밍을 일부 지원함</li>
<li><strong>옵저버패턴(Observer pattern)을 사용함</strong></li>
<li>콜백(Callback)에서 또 콜백을 하는 콜백 지옥에서 벗어날 수 있다.</li>
</ul>
<p>하지만 단점이 제일 크게 다가오는데요... 바로 러닝 커브가 가파르기에 진입장벽이 높습니다...
솔직히 처음 혼자 배우게 되면 뭐가 뭔지 모릅니다...</p>
<h2 id="3-결론">3. 결론</h2>
<p>간단하게 요점만 리액티브 프로그래밍에 대해 알아보았는데요.
너무 축약한게 아닌가 싶습니다.😓😓😓
현재 리액티브 프로그래밍은 트렌드이자 대세이며 반드시 사용해야만 하니 필수로 알아둬야 합니다.
다양한 사용방법, 더 자세한 구조는 글보다는 실제로 사용해보지 않으면 알수가 없고 이는 실무에서 겪어봐야 할 것 같네요.
<img src="https://images.velog.io/images/jojo_devstory/post/ec631db6-d3fd-49fd-be43-353836643693/Unknown.png" alt="MasterYoda"><strong><center>리액티브 프로그래밍! 꼭 사용합시다!!</center></strong></p>
<p>더 자세한 내용을 원하시면 아래 참고사항에 사이트, 도서를 추천합니다.
특히 저는 책으로 도움을 많이 받았습니다.</p>
<br>
<br>
<br>

<p><strong>참고 내용</strong>
<a href="http://reactivex.io/intro.html">http://reactivex.io/intro.html</a>
<a href="https://medium.com/@kevalpatel2106/code-your-next-android-app-using-rxjava-d1db30ac9fcc">https://medium.com/@kevalpatel2106/code-your-next-android-app-using-rxjava-d1db30ac9fcc</a>
<a href="https://www.charlezz.com/?p=189">https://www.charlezz.com/?p=189</a>
<a href="https://namget.tistory.com/entry/Observable-Flowable-Single-Maybe-Completable-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0">https://namget.tistory.com/entry/Observable-Flowable-Single-Maybe-Completable-알아보기</a>
<a href="https://dev-daddy.tistory.com/25">https://dev-daddy.tistory.com/25</a>
<a href="https://jepark-diary.tistory.com/48">https://jepark-diary.tistory.com/48</a></p>
<p><strong>도서</strong>
RxJava 리액티브 프로그래밍, 스다 토모유키 저 / 이승룡 역
RxJava Essentials, 이반 모르질로 저 / 강경구 역
코틀린 리액티브 프로그래밍, 리부 차크라보티 저 / 조승진 역 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] Android 10 점유율..얼마나 될까?👀]]></title>
            <link>https://velog.io/@jojo_devstory/Android-Android-10-%EC%A0%90%EC%9C%A0%EC%9C%A8..%EC%96%BC%EB%A7%88%EB%82%98-%EB%90%A0%EA%B9%8C</link>
            <guid>https://velog.io/@jojo_devstory/Android-Android-10-%EC%A0%90%EC%9C%A0%EC%9C%A8..%EC%96%BC%EB%A7%88%EB%82%98-%EB%90%A0%EA%B9%8C</guid>
            <pubDate>Wed, 15 Apr 2020 05:33:04 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요!</p>
<p>오늘은 안드로이드 OS 버전별 점유율에 대해 내용 공유하려 합니다.</p>
<p>지난 세월을 돌아보면 참 안드로이드가 많이 발전되어 버전 업이 되었는데요.</p>
<p>제가 처음 공부할때만 해도 애플파이 버전이었으니 많이 나오긴 했네요 ^^;;</p>
<p>그리고 현재는 안드로이드 생태계는 10을 출시하였고 다음 버전인 11을 준비중에 있습니다.</p>
<h2 id="안드로이드-버전별-점유율-알려주세요📱">안드로이드 버전별 점유율 알려주세요!📱</h2>
<p><img src="https://images.velog.io/images/jojo_devstory/post/14b1a700-e416-4d4b-8655-c03235a326f0/dd746c82cea86f12472837468da13625.png" alt="스튜디오">
구글은 공식적으로 안드로이드 버전별 점유율을 작년 5월 이후로 공개하지 않고 있습니다.</p>
<p>하지만 이미 안드로이드 개발자분들은 잘 알고 계시겠지만 안드로이드 스튜디오에서 프로젝트 생성시 참고용으로 버전별 점유율을 볼 수 있는데요.</p>
<p>해당 레포트가 다시 새로 업데이트된 것이 확인되었고 이 자료를 기반으로 제공되는 누적 앱 배포율을 다시 정리한 자료 입니다.</p>
<p>4월 기준 버전별 점유율은 아래와 같습니다.
<img src="https://images.velog.io/images/jojo_devstory/post/3d94936a-8334-4da0-a889-0e21a97e1dab/503ea3b8361b56a3453bb8738fcc2636.png" alt="OS"></p>
<p>해당 자료를 보면 아이스크림 샌드위치가 0.2%, 젤리빈이 1.7%, 킷캣이 4.0%, 롤리팝은 9.2%, 마시멜로는 11.2%, 누가는 12.9%를 차지하고 있네요.</p>
<p>역시 아직까지는 상당수의 구버전이 많은 점유율을 차지하고 있다는 것을 알 수 있습니다.</p>
<p>그리고 비교적 최신 버전인 오레오부터는 점유율이 큰 폭으로 늘어나게 되는데 21.3%, 파이가 31.3%로 가장 많네요.</p>
<p>하지만 최신 버전인 안드로이드 10이 설치된 기기는 아직까지는 8.2%에 불과합니다.</p>
<p>참고로 말씀드리자면 작년 5월 중순에 자료가 공개 됬었을 당시에 최신 버전인 파이는 10.4%를 기록했었습니다.</p>
<h2 id="결론">결론</h2>
<p>저는 글 작성 시점인 현재 갤럭시 노트10Plus를 소유중이라 안드로이드 10을 사용 중 입니다.
그래서 안드로이드 10이 많이 올라온 줄 알았는데 아니네요 ^^;;
이전 글에서도 말씀드린적이 있는것 같은데 저는 최신 전자기기, 최신 소프트웨어 버전을 참 좋아해서 베타버전 또는 프리뷰 버전을 체험해보려고 무조건 올리고 봅니다만 그에따라 실험실 기니피그가 되서 먼저 버그나 에러도 같이 체험하다보니 피해를 자주 보기도 합니다..😂😂😂</p>
<p>그래프를 보면 참...아직까지도 많은 버전들이 존재하여 파편화 된 것을 알 수 있는데요.</p>
<p>안드로이드 개발자로써는 각 버전별로 대응을 해야하다보니 구버전이 계속 점유율을 차지하고 있으면 언제 사라지나 하고 생각이드네요.</p>
<p>그나마 국내는 해외보다 비교적 플래그쉽 스마트폰 비율이 높기 때문에 최신버전을 유지하고 있는 경우가 많습니다만 업계별로는 또 유저의들의 사용기기가 다르다보니 이 것 또한 다르게 적용되겠네요.
(ex. 특수 산업용 안드로이드 디바이스 같은 경우 킷캣(4.4) ~ 롤리팝(5.0)이 대부분 입니다.)</p>
<p>이제 슬슬 각 제조사들도 아직 안드로이드 10이 아닌 기기에 대하여 업데이트 검토 후 사후 지원을 통해 업데이트를 해야 할 시기가 아닌가 싶습니다.</p>
<p>출처 : (<a href="https://9to5google.com/2020/04/10/google-kills-android-distribution-numbers-web/">9to5google</a>), (<a href="https://developer.android.com/about/dashboards/index.html?hl=ko">Google Android Developer</a>)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] Android R(11)부터 업데이트 파티션이 생긴다?🤔]]></title>
            <link>https://velog.io/@jojo_devstory/Android-Android-R11%EB%B6%80%ED%84%B0-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8-%ED%8C%8C%ED%8B%B0%EC%85%98%EC%9D%B4-%EC%83%9D%EA%B8%B4%EB%8B%A4</link>
            <guid>https://velog.io/@jojo_devstory/Android-Android-R11%EB%B6%80%ED%84%B0-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8-%ED%8C%8C%ED%8B%B0%EC%85%98%EC%9D%B4-%EC%83%9D%EA%B8%B4%EB%8B%A4</guid>
            <pubDate>Mon, 13 Apr 2020 09:26:17 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요</p>
<p>오늘은 해외발 기사를 읽어보다 재밌는 기사가 있어 앱 개발과는 무관하지만...(관련이 있다면 정확하게는 안드로이드 기기 제조사쪽이네요) 내용 공유 해봅니다.</p>
<p>내용이 무엇인고 하니..</p>
<h2 id="1-업데이트-파티션-그게-뭔데요🧐">1. 업데이트 파티션?? 그게 뭔데요?🧐</h2>
<p><img src="https://images.velog.io/images/jojo_devstory/post/f191dde2-86e2-49a8-9faf-051780609d94/1f94236f6b8df90907bcd86bc4d352ea.jpg" alt="update">
<img src="https://images.velog.io/images/jojo_devstory/post/0af53846-ec33-4b7a-9a6a-12890d79be0e/3ff2705ceafe6b89d716de29212d1a83.jpg" alt="partition">
구글이 안드로이드R(11) 버전부터 업데이트 환경 개선을 위한 가상 파티션 탑재를 강제하도록 하고 있는데요.</p>
<p>물론 구글은 안드로이드 7.0 누가(Nougat)부터 소프트웨어 업데이트 속도를 높이기 위해서 많은 고민을 했고 잘 설계된 파티션 체계를 도입해왔습니다.</p>
<p>그래서 누가(Nougat) 버전부터는 비활성화된 파티션이 백그라운드에서 업데이트가 가능하도록 추가했으며 특정 파티션 또한 클론(복제) 기능에 대한 지원이 추가되어 있습니다.
그리고 업데이트가 완료 될 시 패스트부트(Fastboot) 로 활성 파티션으로 스와핑하도록 할 수 있습니다.</p>
<p>이러한 <strong>A/B 파티션</strong> 세팅을 통해 구글에서 만든 OS인 크롬 OS와 같이 안드로이드OS를 사용하는 기기에서도 <strong>심리스(Seamless) 업데이트</strong>가 가능하게 됩니다.</p>
<p>이 파티션 구조를 사용하는 심리스 업데이트를 지원하는 기기는 기기를 사용 중에도 임의의 여유 파티션에 업데이트를 백그라운드로 다운로드 받아 설치하고 재부팅 할 때 파티션을 바꿔(스와핑) 시간이 오래걸리는 업데이트 시간을 크게 줄일 수 있게 도와줍니다.</p>
<p><strong>또한 만약에 업데이트 실패시 다른 파티션이 있기 때문에 복구 또한 쉬워지는 장점이 있습니다.</strong></p>
<h2 id="2-어-만들어-놨더니-안쓰네-r11부터는-무조건-업데이트-파티션-만들어😎">2. 어? 만들어 놨더니 안쓰네? R(11)부터는 무조건 업데이트 파티션 만들어!😎</h2>
<p><img src="https://images.velog.io/images/jojo_devstory/post/bfb2d95d-6f7d-40fe-861b-751bf1f1ca37/%EA%B0%95%EC%A0%9C.png" alt="안해? 강제로 먹여주마"> <strong><center>Google : 어? 만들어 줬는데 안해? 입에다 들이 밀어 넣어주마!</center></strong>
<br></p>
<p>이런 좋은 기능이 있었지만 구글은 이러한 A/B 파티션을 사용을 의무화하지 않았다보니 거의 대다수 안드로이드 기기들이 심리스 업데이트를 지원하지 않았습니다.</p>
<p>그렇다보니 구글에서 잘만들어 놓은 심리스 업데이트 환경을 조성하고 싶은데 제조사들이 따라주지 않으니 이제 강제성을 두려고 하는것 같네요</p>
<p>물론 지금도 일부 기기는 지원합니다만 안드로이드R(11)부터는 이를 지원하지 않으면 구글 Play Services 인증을 받지 못하게 됩니다...(!!!!)</p>
<p>아무래도 가상 A/B 파티션을 강제성을 두며 의무화 하였기 때문에 안드로이드R(11)부터는 각 제조사들 상황이 달라지겠네요.</p>
<h2 id="3-그럼-이-좋은-기능을-기존-제조사들은-왜-안쓰고-있나요😲">3. 그럼 이 좋은 기능을 기존 제조사들은 왜 안쓰고 있나요?😲</h2>
<p><img src="https://images.velog.io/images/jojo_devstory/post/4a4f2772-cd21-4998-bfc7-ccfa57bfa7c0/i15175601419.jpg" alt="냥물음표"> <strong><center>아니 이렇게 유저들이 편한 기능을 기기에 왜 안넣어줌??</center></strong>
<br>
불행하게도 안드로이드 제조사들 중에서는 제일 큰 업체인 삼성과 같은 특정 제조사들 디바이스에는 해당 기능을 지원하지 않는 기기들이 많습니다.</p>
<p>보통 원인을 분석해보면 기기의 저장소(스토리지)로 지목되는데요.</p>
<p>최근 출시한 갤럭시 S20과 같은 스마트폰은 사전 설치된 소프트웨어가 매우 많습니다.
(다들 아시다시피 삼성 갤럭시 시스템 앱, 삼성 갤럭시 앱, 구글 앱, 통신사 앱 등등) </p>
<p>그래서 이러한 앱들이 설치된 /system, /product와 같은 녀석들을 다른 파티션을 복제한다면 엄청난 파일과 애플리케이션들이 복제될 수 있습니다.</p>
<p>이러한 작업자체도 시간이 소모되고 자원도 낭비가 되니 사용을 하지 않는것이죠.</p>
<p>또한 이런 기능 개발을 위한 비용 등이 문제가 되었을수도 있습니다.</p>
<p>물론 구글님들이 누굽니까? 그래서 구글은 SquashFS를 사용한다면 대용량 .odex 파일을 복사하지 않고도 해당 문제점을 해결이 가능하다고 제시하고 있습니다.</p>
<p>하지만 저런 가능한 방법이 있어도 의무도 아닐뿐더러 위에서 설명한 여러 기타 이유로 추가하지 않은거 같네요.</p>
<h2 id="결론">결론</h2>
<p>이제 구글은 안드로이드R(11)에서 A/B파티션, 심리스 업데이트 도입을 의무화했습니다.</p>
<p>그래서 기존에 하위 버전을 사용중에 안드로이드R(11)을 업데이트 하려는 기기 또한 의무적으로 도입해야 하며 각 제조사들은 2020년 후반부터 2021년에 출시되는 스마트폰은 심리스 업데이트를 반드시 제공해야 합니다.</p>
<p>원문 출처: <a href="https://www.gsmarena.com/google_will_require_all_new_android_11_devices_to_support_seamless_updates-news-42522.php">GSMArena</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Android Developer Roadmap]]></title>
            <link>https://velog.io/@jojo_devstory/Android-Developer-Roadmap</link>
            <guid>https://velog.io/@jojo_devstory/Android-Developer-Roadmap</guid>
            <pubDate>Thu, 09 Apr 2020 07:35:05 GMT</pubDate>
            <description><![CDATA[<p>오늘도 좋은 내용이 있어 공유합니다.</p>
<p>MindOrks에서 제작한 안드로이드 개발자 로드맵 입니다.</p>
<p>안드로이드 공부하면서 참고 하면 좋을 것 같습니다.</p>
<p>원문은 아래 깃허브 입니다.
<a href="https://github.com/MindorksOpenSource/android-developer-roadmap">https://github.com/MindorksOpenSource/android-developer-roadmap</a></p>
<p><img src="https://images.velog.io/images/jojo_devstory/post/014c9b66-d9c0-442a-a336-895216a58592/android_developer_roadmap.png" alt="로드맵"></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] MergeAdapter 이용하여 Adapter를 순차적으로 Merge하기!]]></title>
            <link>https://velog.io/@jojo_devstory/Android-MergeAdapter-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-Adapter%EB%A5%BC-%EC%88%9C%EC%B0%A8%EC%A0%81%EC%9C%BC%EB%A1%9C-Merge%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@jojo_devstory/Android-MergeAdapter-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-Adapter%EB%A5%BC-%EC%88%9C%EC%B0%A8%EC%A0%81%EC%9C%BC%EB%A1%9C-Merge%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 03 Apr 2020 07:49:59 GMT</pubDate>
            <description><![CDATA[<p>이전 포스팅 <a href="https://velog.io/@jojo_devstory/Android-Android-Studio-4.0-Layout-Inspector-%EC%86%8C%EA%B0%9C">Layout Inspector 소개</a> 글에 이어서 또 하나 좋은 내용이 있어 소개해드립니다.</p>
<p>바로 MergeAdapter인데요.👍</p>
<p>MergeAdapter는 단일 RecyclerView에 표시할 여러 어댑터를 순차적으로 결합하여 할 수 있는 새로운 클래스입니다. RecyclerView와 Adapter의 관계를 1:N으로 만들어 준다고 할 수 있습니다. MergeAdapter를 사용하게 되면 많은 데이터 소스를 단일 어댑터에 결합해서 포커스를 맞추어서 재사용할 수 있는 것보다 어댑터를 더 잘 캡슐화할 수 있습니다.
물론 사용성에 있어서도 편해지기 때문에 굉장히 유용하다고 할 수 있겠네요.</p>
<p>자세한 내용은 아래의 링크에서 참조 부탁드립니다.
해당 링크에서는 리스트에서 헤더와 푸터를 디스플레이할때의 예를 들어서 사용방법을 제시하고 있습니다.
<a href="https://medium.com/androiddevelopers/merge-adapters-sequentially-with-mergeadapter-294d2942127a">https://medium.com/androiddevelopers/merge-adapters-sequentially-with-mergeadapter-294d2942127a</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android] Android Studio 4.0 - Layout Inspector 소개]]></title>
            <link>https://velog.io/@jojo_devstory/Android-Android-Studio-4.0-Layout-Inspector-%EC%86%8C%EA%B0%9C</link>
            <guid>https://velog.io/@jojo_devstory/Android-Android-Studio-4.0-Layout-Inspector-%EC%86%8C%EA%B0%9C</guid>
            <pubDate>Fri, 03 Apr 2020 07:33:44 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요.</p>
<p>오늘은 몇가지 주제로 좋은 포스팅를 소개하고자 합니다.</p>
<p>요즘 Andoroid Studio 4.0 업데이트가 다가오면서 Andoroid Studio 4.0 Preview에 대해 여러 정보와 추가된 기능들이 소개되고 있습니다.</p>
<p>그중에서 Layout Inspector에 대해서 포스팅 하나 소개해드립니다.</p>
<p>새롭게 개선된 Layout Inspector에서는 UI를 3차원으로 표현하여 Layout 디버깅을 좀 더 쉽게 도와줍니다!</p>
<p>해당 정보는 아래 링크에 상세히 나와있습니다.</p>
<p>안드로이드OS도 OS지만 IDE 자체도 점점 사용성이 좋아지면서 예전 이클립스를 사용하던 시절에 비하면 정말 눈물이 나올정도네요....인텔리J 최고...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Android Studio 3.6.2 업데이트 배포 - Databinding 문제 해결👨🏻‍🔧]]></title>
            <link>https://velog.io/@jojo_devstory/Android-Studio-3.6.2-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8-%EB%B0%B0%ED%8F%AC-Databinding-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</link>
            <guid>https://velog.io/@jojo_devstory/Android-Studio-3.6.2-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8-%EB%B0%B0%ED%8F%AC-Databinding-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</guid>
            <pubDate>Wed, 01 Apr 2020 08:14:58 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요</p>
<p>미국 현지 시간 3월 31일 화요일 안드로이드 스튜디오 3.6.2가 배포 되면서 Databinding 이슈가 해결이 되었습니다!👨🏻‍🔧 짝짝짝!👏👏👏</p>
<p>해당 내용은 아래의 이전 포스팅을 참고 바랍니다.
<a href="https://velog.io/@jojo_devstory/%EC%99%80%EC%95%84-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%8A%A4%ED%8A%9C%EB%94%94%EC%98%A4-3.6-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8-%EA%B7%B8%EB%9F%B0%EB%8D%B0-DataBinding%EC%9D%B4-%EC%95%88%EB%90%9C%EB%8B%A4">https://velog.io/@jojo_devstory/와아-안드로이드-스튜디오-3.6-업데이트-그런데-DataBinding이-안된다</a></p>
<p>다행히도 빠르게 차기 fix 버전에 포함 되서 다행입니다...🤓</p>
<p>상세 업데이트 내역은 이쪽을 참고해주세요
<a href="https://androidstudio.googleblog.com/2020/03/android-studio-362-available.html">https://androidstudio.googleblog.com/2020/03/android-studio-362-available.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Android Jetpack - CameraX📸 좋은 글 소개]]></title>
            <link>https://velog.io/@jojo_devstory/Android-Jetpack-CameraX-%EC%A2%8B%EC%9D%80-%EA%B8%80-%EC%86%8C%EA%B0%9C</link>
            <guid>https://velog.io/@jojo_devstory/Android-Jetpack-CameraX-%EC%A2%8B%EC%9D%80-%EA%B8%80-%EC%86%8C%EA%B0%9C</guid>
            <pubDate>Sat, 28 Mar 2020 07:57:54 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/jojo_devstory/post/0f6c0555-cdd1-4cbd-a18b-70a3a2159f26/0*LK_RoDHQaheBgMPW.png" alt="CameraX">
Android Jetpack이 세상에 나온 이후 구글에서 꾸준이 업데이트를 하면서 여러 좋은 기능들이 많이 추가 되었습니다.</p>
<p>그중 최근에 추가된 CameraX에 대해 좋은 포스팅이 있어 링크 첨부 합니다.</p>
<p>새로운 Android Jetpack 라이브러리인 CameraX의 기능을 해당 글에서 확인해 보시고
여러분의 프로젝트 앱에 카메라 제어 기능을 추가하는 방법을 알아보시기 바랍니다.🧑🏻‍💻</p>
<p>🥳<a href="https://developers-kr.googleblog.com/2020/03/whats-new-in-camerax.html">https://developers-kr.googleblog.com/2020/03/whats-new-in-camerax.html</a></p>
]]></description>
        </item>
    </channel>
</rss>