<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>박상권의 삽질블로그</title>
    <link>https://gun0912.tistory.com/</link>
    <description>누구나 할 수 있는 일을 
누구도 할 수 없을 만큼 하는가</description>
    <language>ko</language>
    <pubDate>Sun, 12 Apr 2026 11:36:14 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>박상권</managingEditor>
    <image>
      <title>박상권의 삽질블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/1892959/attach/ff8d7d049ec248e18e9682b7eb1310b1</url>
      <link>https://gun0912.tistory.com</link>
    </image>
    <item>
      <title>[안드로이드]TedNaverMapClustering -네이버지도용 클러스터링 유틸리티 라이브러리</title>
      <link>https://gun0912.tistory.com/83</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;TedNaverMapClustering.png&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SkzUI/btqwLC1RtWV/CENcpSojec10APNgvNTpXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SkzUI/btqwLC1RtWV/CENcpSojec10APNgvNTpXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SkzUI/btqwLC1RtWV/CENcpSojec10APNgvNTpXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSkzUI%2FbtqwLC1RtWV%2FCENcpSojec10APNgvNTpXK%2Fimg.png&quot; data-filename=&quot;TedNaverMapClustering.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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;지금까지 우리는 지도관련 서비스를 만들면서 클러스터링을&amp;nbsp;사용하려면&amp;nbsp;Google지도를&amp;nbsp;사용해야&amp;nbsp;했습니다&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(Google지도에서만&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://developers.google.com/maps/documentation/android-sdk/utility/marker-clustering&quot;&gt;Clustering Utility&lt;/a&gt;&lt;span style=&quot;color: #333333;&quot;&gt;를 통해 클러스터링을 지원했으니까요)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;240&quot; height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0Ht73/btqwILMLAmb/TyMX4vDNPVDmpUwR2XmrQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0Ht73/btqwILMLAmb/TyMX4vDNPVDmpUwR2XmrQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0Ht73/btqwILMLAmb/TyMX4vDNPVDmpUwR2XmrQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0Ht73%2FbtqwILMLAmb%2FTyMX4vDNPVDmpUwR2XmrQ1%2Fimg.png&quot; width=&quot;240&quot; height=&quot;400&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;한국에서&amp;nbsp;앱을&amp;nbsp;서비스하기에는&amp;nbsp;네이버지도가&amp;nbsp;친숙하며&amp;nbsp;더&amp;nbsp;많은&amp;nbsp;정보들이&amp;nbsp;있지만&amp;nbsp;네이버지도용&amp;nbsp;클러스터링은&amp;nbsp;없었습니다&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;웹용 클러스터링은 지원하면서도 안드로이드용 클러스터링은 왜 지원하지 않는지 모르겠네요..&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;네이버지도&amp;nbsp;팀에서&amp;nbsp;클러스터링기능을&amp;nbsp;지원해주면&amp;nbsp;좋겠지만 '나오겠지...나오겠지..' 라는 생각만으로 그렇게&amp;nbsp;몇년이&amp;nbsp;지나도&amp;nbsp;클러스터링&amp;nbsp;기능은&amp;nbsp;나오지&amp;nbsp;않았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;s&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(일해라 네이버 지도팀)&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;br /&gt;&lt;b&gt;그래서 제가 직접 네이버지도용&amp;nbsp;클러스터링&amp;nbsp;라이브러리를&amp;nbsp;만들었습니다&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bimTDW/btqwKd2Mn1G/lkDnyxU8uRKHTMc4KbhKUK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bimTDW/btqwKd2Mn1G/lkDnyxU8uRKHTMc4KbhKUK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bimTDW/btqwKd2Mn1G/lkDnyxU8uRKHTMc4KbhKUK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bimTDW/btqwKd2Mn1G/lkDnyxU8uRKHTMc4KbhKUK/img.gif&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;지금 바로 적용해보고 싶으신 분들은 아래 링크로 접속해서 바로 테스트 해보세요&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedNaverMapClustering&quot;&gt;https://github.com/ParkSangGwon/TedNaverMapClustering&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1563004330633&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedNaverMapClustering&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-original-url=&quot;https://github.com/ParkSangGwon/TedNaverMapClustering&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/g0MlY/hyBYkOGpUE/4N0NAfNPT3zuKRcinZ04v1/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;ParkSangGwon/TedNaverMapClustering&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;네이버지도용 클러스터 유틸리티 라이브러리. Contribute to ParkSangGwon/TedNaverMapClustering development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3&gt;클러스터링 알고리즘&lt;/h3&gt;
&lt;p&gt;TedNaverMapClustering의&amp;nbsp;클러스터링&amp;nbsp;알고리즘은&amp;nbsp;GoogleMap의&amp;nbsp;클러스터링&amp;nbsp;알고리즘과&amp;nbsp;같은&amp;nbsp;방식으로&amp;nbsp;클러스터링&amp;nbsp;됩니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;자세한&amp;nbsp;구현방식이&amp;nbsp;궁금하시다면&amp;nbsp;&lt;a href=&quot;http://www.joams.com/uploadfile/2013/0426/20130426033622753.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Efficient&amp;nbsp;Filtering&amp;nbsp;and&amp;nbsp;Clustering&amp;nbsp;Mechanism&amp;nbsp;for&amp;nbsp;Google&amp;nbsp;Maps&lt;/a&gt;을&amp;nbsp;읽어보시면&amp;nbsp;도움이&amp;nbsp;되실겁니다.&lt;br /&gt;본인만의&amp;nbsp;알고리즘으로&amp;nbsp;클러스터링을&amp;nbsp;하길&amp;nbsp;원하는경우&amp;nbsp;&lt;a href=&quot;https://github.com/ParkSangGwon/TedNaverMapClustering/blob/8e709a1b6238962b4207d2e73db28d3d5941fb5e/tedclustering/src/main/java/ted/gun0912/clustering/clustering/algo/ScreenBasedAlgorithm.kt&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ScreenBasedAlgorithm&lt;/a&gt;를&amp;nbsp;상속받아&amp;nbsp;알고리즘을&amp;nbsp;구현하고&amp;nbsp;setAlgorithm()로&amp;nbsp;설정해주면&amp;nbsp;됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;여러 지도에 클러스터링 적용&lt;/h3&gt;
&lt;p&gt;TedNaverMapClustering은&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;a href=&quot;https://github.com/ParkSangGwon/TedNaverMapClustering/tree/master/tedclustering&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;tedclustering&lt;/a&gt;&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;&lt;a href=&quot;https://developers.google.com/maps/documentation/android-sdk/utility/marker-clustering&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Google지도&lt;/a&gt;와&amp;nbsp;&lt;a href=&quot;http://tmapapi.sktelecom.com/main.html#android/docs/androidDoc.TMapMarkerItem_setEnableClustering&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Tmap지도&lt;/a&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;예정입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;네이버지도팀에서 공식적으로 클러스터링을 지원하거나 이 라이브러리를 공식페이지에 소개해서 많은 개발자분들이 네이버 지도를 이용하도록 한다면 네이버에도 많은 도움이 될것이라고 생각합니다&lt;/p&gt;
&lt;p&gt;(연락 주세요 네이버 지도팀 관계자 여러분)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;앞으로도 공식 API에서 지원하지 않는것들이 있다면 직접 해당 기능을 구현하고 많은 개발자들이 사용할 수 있는 라이브러리로 배포하도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;감사합니다.&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/83</guid>
      <comments>https://gun0912.tistory.com/83#entry83comment</comments>
      <pubDate>Sat, 13 Jul 2019 16:49:03 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]TedKeyboardObserver (키보드 show/hide 감지)</title>
      <link>https://gun0912.tistory.com/82</link>
      <description>&lt;p&gt;화면을 개발하다보면 키보드의 상태를 알고 싶을때가 있습니다.&lt;/p&gt;
&lt;p&gt;(키보드가 올라왔을때 View를 올리거나 없애거나 하는 등)&lt;/p&gt;
&lt;p&gt;Android에서 키보드의 상태를 확인할 수있는 기능을 지원해주면 좋겠지만 그렇지 않았습니다.&lt;/p&gt;
&lt;p&gt;TedKeyboardObserver는 키보드의 상태를 감지하고 원하는 작업을 할 수 있도록 도와주는 라이브러리입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;TedKeyboardObserver.gif&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boUrij/btqweakOO1V/xH9EnOdMkCMkOeQf6LyGTk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boUrij/btqweakOO1V/xH9EnOdMkCMkOeQf6LyGTk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boUrij/btqweakOO1V/xH9EnOdMkCMkOeQf6LyGTk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/boUrij/btqweakOO1V/xH9EnOdMkCMkOeQf6LyGTk/img.gif&quot; data-filename=&quot;TedKeyboardObserver.gif&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedKeyboardObserver&quot;&gt;https://github.com/ParkSangGwon/TedKeyboardObserver&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1561040498697&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedKeyboardObserver&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-original-url=&quot;https://github.com/ParkSangGwon/TedKeyboardObserver&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bsi91E/hyBFChYQGQ/k8qC0nT4G30HzSRTqUxYnk/img.jpg?width=400&amp;amp;height=400&amp;amp;face=117_158_326_367');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;ParkSangGwon/TedKeyboardObserver&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;TedKeyboardObserver is keyboard's visibility observer - ParkSangGwon/TedKeyboardObserver&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;hr&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3&gt;설정&lt;/h3&gt;
&lt;pre id=&quot;code_1561040480608&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
    implementation 'gun0912.ted:tedkeyboardobserver:x.y.z'
    //implementation 'gun0912.ted:tedkeyboardobserver:1.0.0-alpha2'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;color: #333333;&quot;&gt;사용법&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;-&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;TedKeyboardObserver는&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코틀린으로&amp;nbsp;만들어진&amp;nbsp;라이브러리&amp;nbsp;입니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;-&amp;nbsp;Listener와&amp;nbsp;RxJava스타일&amp;nbsp;모두&amp;nbsp;지원합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;RxJava&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;-&amp;nbsp;라이브러리&amp;nbsp;내부에서&amp;nbsp;알아서&amp;nbsp;Lifecycle을&amp;nbsp;관리하기&amp;nbsp;때문에&amp;nbsp;별도의&amp;nbsp;removeObserve()나&amp;nbsp;RxJava의&amp;nbsp;dispose()를&amp;nbsp;해줄필요가&amp;nbsp;없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Java&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1561040599478&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;new TedRxKeyboardObserver(this)
         .listen()
         .subscribe(isShow -&amp;gt; {
                     // do something
                 }, Throwable::printStackTrace);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Kotlin&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1561040624397&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TedRxKeyboardObserver(this)
    .listen()
    .subscribe({ isShow -&amp;gt; // do something }
        , { throwable -&amp;gt; throwable.printStackTrace() })&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&lt;b&gt;Listener&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1561040644152&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;new TedKeyboardObserver(this)
                .listen(isShow -&amp;gt; {
                    // do something
                });&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Kotlin&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1561040661658&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TedKeyboardObserver(this)
         .listen { isShow -&amp;gt;
              // do something
         }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;어때요? 이 라이브러리와 함께라면 키보드의 움직임을 모두 관찰 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;유용하셨다면 GitHub의 star도&amp;nbsp;눌러주시면&amp;nbsp;감사하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;감사합니다.&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/82</guid>
      <comments>https://gun0912.tistory.com/82#entry82comment</comments>
      <pubDate>Thu, 20 Jun 2019 23:31:10 +0900</pubDate>
    </item>
    <item>
      <title>코틀린(Kotlin), 꼭 해야하나요?</title>
      <link>https://gun0912.tistory.com/81</link>
      <description>&lt;p&gt;이 글은 2019년4월5일 있었던 '드로이드나이츠 2019'행사에서 발표했었던 내용에 기반한 포스팅입니다.&lt;/p&gt;
&lt;p&gt;제 목소리와 함께 영상으로 시청하실분들은 아래 링크를 통해 영상으로 감상해보세요&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=e9O0wt-eY-E&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.youtube.com/watch?v=e9O0wt-eY-E&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignLeft&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=e9O0wt-eY-E&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/jWqxw/hyBaW8FJNz/xyDP40Hr6B466NzVwqdEeK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/e9O0wt-eY-E&quot; width=&quot;480&quot; height=&quot;270&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;hr&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zMCho/btqvmrz5WoG/ZfK9VLgk7oE9gP5ilUNkHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zMCho/btqvmrz5WoG/ZfK9VLgk7oE9gP5ilUNkHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zMCho/btqvmrz5WoG/ZfK9VLgk7oE9gP5ilUNkHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzMCho%2Fbtqvmrz5WoG%2FZfK9VLgk7oE9gP5ilUNkHk%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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&quot;코틀린, 꼭 해야하나요?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코틀린이 나온 이후 &lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;몇년전부터 여러 오픈 채팅방과 커뮤니티에 끊임없이 주기적으로 올라오는 질문들입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사실 저는 &amp;ldquo;코틀린&amp;nbsp;꼭&amp;nbsp;해야하나요?&amp;rdquo;&amp;nbsp;라는 질문을 &amp;ldquo;코틀린&amp;nbsp;하기&amp;nbsp;싫어요&amp;rdquo;&amp;nbsp;라고 읽습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미 할 사람이라면 이미 학습을 시작 했을것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이런 질문을 하시는분들은 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하기는 싫은데 하는사람은 많고 안할 이유를 찾고 싶은 답정너 느낌입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자매품으로는 아래와 같은 질문들이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &amp;ldquo;데이터바인딩&amp;nbsp;꼭&amp;nbsp;해야하나요?&amp;rdquo;&lt;br /&gt;- &amp;ldquo;RxJava&amp;nbsp;꼭&amp;nbsp;해야하나요?&amp;rdquo;&lt;br /&gt;- &amp;ldquo;MVP,&amp;nbsp;MVVM으로&amp;nbsp;꼭&amp;nbsp;해야하나요?&amp;rdquo;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;TL; DR ( Too Long; Didn&amp;rsquo;t Read)&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;네,&amp;nbsp;하세요&amp;nbsp;꼭&amp;nbsp;하세요&amp;nbsp;&lt;br /&gt;두번&amp;nbsp;하세요&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Google&amp;nbsp;&amp;hearts;&amp;nbsp;Kotlin&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;592px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVGjyB/btqvi4e4wZL/9xRnde2tzAIc3yaEaVwba0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVGjyB/btqvi4e4wZL/9xRnde2tzAIc3yaEaVwba0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVGjyB/btqvi4e4wZL/9xRnde2tzAIc3yaEaVwba0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVGjyB%2Fbtqvi4e4wZL%2F9xRnde2tzAIc3yaEaVwba0%2Fimg.jpg&quot; width=&quot;592px;&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;2017년&amp;nbsp;구글&amp;nbsp;I/O에서 코틀린은 공식언어로&amp;nbsp;지정되었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkKWOV/btqviHRVZPE/j4TxbBwWvHirGdP8yqWfw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkKWOV/btqviHRVZPE/j4TxbBwWvHirGdP8yqWfw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkKWOV/btqviHRVZPE/j4TxbBwWvHirGdP8yqWfw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkKWOV%2FbtqviHRVZPE%2Fj4TxbBwWvHirGdP8yqWfw0%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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;또한 2019년 구글 I/O에서도 다시한번 코틀린을 언급하면서 Kotlin First 시대를 알리고 구글에서 만드는 라이브러리들은 Kotlin으로 배포할것임을 알렸습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;556px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zyPtd/btqvjLM6W4r/pl71t1bxqr7ZCpCKokWuC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zyPtd/btqvjLM6W4r/pl71t1bxqr7ZCpCKokWuC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zyPtd/btqvjLM6W4r/pl71t1bxqr7ZCpCKokWuC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzyPtd%2FbtqvjLM6W4r%2Fpl71t1bxqr7ZCpCKokWuC1%2Fimg.png&quot; width=&quot;556px;&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;안드로이드&amp;nbsp;공식&amp;nbsp;문서를 보시면서 많이 느끼셨겠지만 예제코드의&amp;nbsp;메인&amp;nbsp;언어가&amp;nbsp;코틀린으로&amp;nbsp;짜여져 있습니다.&lt;/p&gt;
&lt;p&gt;예전에는&amp;nbsp;Java코드밖에&amp;nbsp;없었는데 어느날 Kotlin탭이&amp;nbsp;추가되더니 요즘에는&amp;nbsp;아예&amp;nbsp;Kotlin탭이&amp;nbsp;더&amp;nbsp;먼저&amp;nbsp;나오기&amp;nbsp;시작했습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참고로&amp;nbsp;안드로이드&amp;nbsp;공식문서는&amp;nbsp;무조건&amp;nbsp;영어로,&amp;nbsp;한글로&amp;nbsp;보면&amp;nbsp;안됩니다.&lt;/p&gt;
&lt;p&gt;한글번역이 많이 늦어서 영어로는 변경이 되었으나 한글로는 해당 내용이 보이지 않는 불상사가 발생합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Java&amp;nbsp;vs&amp;nbsp;Kotlin&lt;/h2&gt;
&lt;p&gt;코틀린을&amp;nbsp;사용했을때&amp;nbsp;자바언어와의&amp;nbsp;비교,&amp;nbsp;특히&amp;nbsp;코틀린으로&amp;nbsp;안드로이드로&amp;nbsp;개발했을때의&amp;nbsp;차이에&amp;nbsp;대해서&amp;nbsp;비교하면서&amp;nbsp;설명해보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;사전&amp;nbsp;지식&lt;/h2&gt;
&lt;p&gt;시작하기에&amp;nbsp;앞서&amp;nbsp;가장&amp;nbsp;기본적인&amp;nbsp;사전지식&amp;nbsp;몇가지를&amp;nbsp;소개해드리고&amp;nbsp;시작하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557922151266&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Nullable
private String address;
@NonNull
private String id;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Java에서의&amp;nbsp;Nullable과&amp;nbsp;NonNull&amp;nbsp;변수들을&amp;nbsp;코틀린으로&amp;nbsp;변환하면&amp;nbsp;다음과&amp;nbsp;같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(NonNull은&amp;nbsp;support&amp;nbsp;library&amp;nbsp;19.1&amp;nbsp;부터&amp;nbsp;추가된&amp;nbsp;어노테이션이며&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그외&amp;nbsp;@StringRes,&amp;nbsp;@ColorRes&amp;nbsp;등&amp;nbsp;유용한것들도&amp;nbsp;많습니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1557922284615&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var address: String? = null
var id: String = &amp;ldquo;ted&amp;rdquo;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nullable한&amp;nbsp;변수는&amp;nbsp;Type에&amp;nbsp;물음표를,&amp;nbsp;그렇지&amp;nbsp;않은&amp;nbsp;변수는&amp;nbsp;없이&amp;nbsp;선언해줍니다.&lt;br /&gt;또한&amp;nbsp;수정가능한&amp;nbsp;변수라면&amp;nbsp;var로&amp;nbsp;선언합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1557922309522&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val birthYear: Int = 1986&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Val 의 경우 한번 할당하면 변경 할 수 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1557922325091&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val birthYear = 1986&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;타입선언없이 바로 값 할당이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;헤이딜러&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;524px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pJTR4/btqvlTDCdxr/75zdhu2mBhs9t0fHG93fk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pJTR4/btqvlTDCdxr/75zdhu2mBhs9t0fHG93fk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pJTR4/btqvlTDCdxr/75zdhu2mBhs9t0fHG93fk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpJTR4%2FbtqvlTDCdxr%2F75zdhu2mBhs9t0fHG93fk0%2Fimg.png&quot; width=&quot;524px;&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;뜬금없이&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;들어보겠습니다.&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;서비스입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예시&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-filename=&quot;blob&quot; width=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k6Cwv/btqvkymrfQk/4QjtaKMR3tPF7kvS43rN10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k6Cwv/btqvkymrfQk/4QjtaKMR3tPF7kvS43rN10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k6Cwv/btqvkymrfQk/4QjtaKMR3tPF7kvS43rN10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk6Cwv%2FbtqvkymrfQk%2F4QjtaKMR3tPF7kvS43rN10%2Fimg.png&quot; data-filename=&quot;blob&quot; width=&quot;200&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&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;들어보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이&amp;nbsp;상황의&amp;nbsp;경우&amp;nbsp;이와같은&amp;nbsp;클래스들과&amp;nbsp;서로의&amp;nbsp;관계를&amp;nbsp;갖게&amp;nbsp;됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1557923231446&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;거래정보(Car) 
-&amp;gt; 경매결과(Auction)
-&amp;gt; 선택된 견적(Bid)
-&amp;gt; 해당 견적의 딜러(Dealer)
-&amp;gt; 딜러의 이름 가져오기(String)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Safe&amp;nbsp;call&lt;/h2&gt;
&lt;pre id=&quot;code_1557923277729&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private String getSelectedDealerName(@Nullable Car car) {
    if (car == null) {
        return null;
    }
    Auction auction = car.getAuction();
    if (auction == null) {
        return null;
    }
    Bid selectedBid = auction.getSelectedBid();
    if (selectedBid == null) {
        return null;
    }
    Dealer dealer = selectedBid.getDealer();
    if (dealer == null) {
        return null;
    }
    return dealer.getName();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&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;있을것입니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이때 값을 가져올때마다 if() null 체크를 항상 해주어야 합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대단히 번거롭습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코틀린을&amp;nbsp;사용한다면 아래와 같이&amp;nbsp;표현할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1557923348742&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private fun getSelectedDealerName(car: Car?): String? {
    return car?.auction?.selectedBid?.dealer?.name
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;어때요&amp;nbsp;참&amp;nbsp;쉽죠?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;물음표를&amp;nbsp;이용해서&amp;nbsp;null이&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;safe&amp;nbsp;call이라고&amp;nbsp;합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2&gt;Class&lt;/h2&gt;
&lt;pre id=&quot;code_1557923461727&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Dealer {
    @Nullable
    private String name;
    @Nullable
    private String address;

    public Dealer(@Nullable String name, @Nullable String address) {...}

    @Nullable
    public final String getName() {...}

    public final void setName(@Nullable String var1) {...}

    @Nullable
    public final String getAddress() {...}

    public final void setAddress(@Nullable String var1) {...}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;자바에서&amp;nbsp;딜러정보&amp;nbsp;클래스를&amp;nbsp;만든다면 위와&amp;nbsp;같이&amp;nbsp;만들게&amp;nbsp;될것입니다.&lt;br /&gt;물론&amp;nbsp;IDE의&amp;nbsp;도움을&amp;nbsp;받아서&amp;nbsp;필드만&amp;nbsp;선언해주고&amp;nbsp;setter(),&amp;nbsp;getter()를&amp;nbsp;만들어주면&amp;nbsp;되므로&amp;nbsp;나름대로의&amp;nbsp;개선이&amp;nbsp;있었습니다.&lt;br /&gt;하지만&amp;nbsp;여전히&amp;nbsp;코드량이&amp;nbsp;많고&amp;nbsp;불편한건&amp;nbsp;사실입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코틀린으로&amp;nbsp;만들경우&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;만들면&amp;nbsp;끝입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1557923558390&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data class Dealer(var name: String?, var address: String?)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;var를&amp;nbsp;선언해서&amp;nbsp;setter/getter가&amp;nbsp;자동생성되었고,&amp;nbsp;물음표를&amp;nbsp;통해서&amp;nbsp;Nullable한&amp;nbsp;필드임을&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;또한&amp;nbsp;생성자도&amp;nbsp;만들어&amp;nbsp;줍니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;심지어&amp;nbsp;toString(),&amp;nbsp;hashCode(),&amp;nbsp;equals(),&amp;nbsp;copy()까지&amp;nbsp;모두&amp;nbsp;알아서&amp;nbsp;만들어줍니다.(data&amp;nbsp;class&amp;nbsp;기준)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;String&amp;nbsp;template&lt;/h2&gt;
&lt;p&gt;만약&amp;nbsp;Log를&amp;nbsp;찍기&amp;nbsp;위함이거나&amp;nbsp;텍스트를&amp;nbsp;만들때&amp;nbsp;이와&amp;nbsp;같이&amp;nbsp;&amp;nbsp;a&amp;nbsp;+&amp;nbsp;b&amp;nbsp;+&amp;nbsp;c&amp;nbsp;와&amp;nbsp;같은&amp;nbsp;방식으로&amp;nbsp;String을&amp;nbsp;만들어줄것입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557923622651&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void logDealerInfo(@NonNull Dealer dealer) {
    String name = dealer.getName();
    String address = dealer.getAddress();
    Log.d(&quot;ted&quot;, &quot;딜러이름: &quot; + name + &quot; , 딜러주소: &quot; + address);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;혹은&amp;nbsp;조금은&amp;nbsp;더&amp;nbsp;개선된&amp;nbsp;방식으로&amp;nbsp;String&amp;nbsp;format을&amp;nbsp;이용해서&amp;nbsp;간결한&amp;nbsp;코드로&amp;nbsp;작성하기도&amp;nbsp;합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557923656873&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String.format(Locale.getDefault(), &quot;딜러이름: %1%s , 딜러주소: %2$s&quot;, name, address)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;코틀린을&amp;nbsp;사용하면&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;$&amp;nbsp;표시로&amp;nbsp;바로&amp;nbsp;변수를&amp;nbsp;넣어주면서&amp;nbsp;String을&amp;nbsp;만들어&amp;nbsp;줄&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557923678857&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private fun logDealerInfo(dealer: Dealer){
    val name = dealer.name
    val address = dealer.address
    Log.d(&quot;ted&quot;,&quot;딜러이름: $name , 딜러주소: $address&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Overload&lt;/h2&gt;
&lt;p&gt;오버로딩을&amp;nbsp;지원해서&amp;nbsp;생성자나&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;제공해야합니다.&lt;br /&gt;커스텀뷰를&amp;nbsp;만들때&amp;nbsp;거의&amp;nbsp;기계적으로&amp;nbsp;구현해주는&amp;nbsp;생성자들&amp;nbsp;입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557923749311&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class TedCustomView extends FrameLayout {
    public TedCustomView(@NonNull Context context) {...}

    public TedCustomView(@NonNull Context context, @Nullable AttributeSet attrs) 
{...}

    public TedCustomView(@NonNull Context context, @Nullable AttributeSet attrs,    
int defStyleAttr) {...}

    public TedCustomView(@NonNull Context context, @Nullable AttributeSet attrs, 
int defStyleAttr, int defStyleRes) {...}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하지만 코틀린을 사용한다면 간결한 코드로 만들 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1557923766062&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class TedCustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) :
    FrameLayout(context, attrs, defStyleAttr, defStyleRes) {
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;= null, = 0 과 같이 만약 해당값이 없다면 default로 이러한 값들이 들어가도록 지정하면 알아서 오버로딩 생성자가 만들어집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Lambda&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;버튼&amp;nbsp;클릭&amp;nbsp;리스너를&amp;nbsp;만들어줄때&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;정의하시게&amp;nbsp;될겁니다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1557923804189&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        // 할일하기
    }
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;물론&amp;nbsp;요즘&amp;nbsp;대부분&amp;nbsp;Java8을&amp;nbsp;사용하기때문에&amp;nbsp;이와&amp;nbsp;같이&amp;nbsp;람다식으로&amp;nbsp;선언해주는&amp;nbsp;경우가&amp;nbsp;더&amp;nbsp;많을것입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557923841169&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;button.setOnClickListener(view -&amp;gt; {
    // 할일하기
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그래도&amp;nbsp;여전히&amp;nbsp;거의&amp;nbsp;사실상&amp;nbsp;쓰이지않는&amp;nbsp;view를&amp;nbsp;인자로&amp;nbsp;받아야하고&amp;nbsp;__&amp;nbsp;과&amp;nbsp;같은&amp;nbsp;ignore이름으로&amp;nbsp;선언하곤&amp;nbsp;합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;하지만&amp;nbsp;코틀린을&amp;nbsp;사용하면&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;사용가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557923865412&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;button.setOnClickListener {
    // 할일하기
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;사용되지&amp;nbsp;않는&amp;nbsp;view마저도&amp;nbsp;없애버릴&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;let&lt;/h2&gt;
&lt;p&gt;딜러&amp;nbsp;정보를&amp;nbsp;파라미터로&amp;nbsp;받아서&amp;nbsp;null이&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;/p&gt;
&lt;pre id=&quot;code_1557923914352&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void setDealerName(@Nullable Dealer dealer) {
    if (dealer != null) {
        String name = dealer.getName();
        // 할일하기
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이때 코틀린에서는 let을 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아까 소개했었던 물음표로 null을 체크하면서 let을 함께 붙여주면 딜러가 null이 아닐때만 이 스코프로 들어오게 되고 그안에서 할일을 해주면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1557923938944&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private fun setDealerName(dealer: Dealer?) {
    dealer?.let { dealer -&amp;gt;
        val name = dealer.name
        // 할일하기
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자바에서의 코드보다 더 직관적이고 간결한 코드로 작성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;심지어&amp;nbsp;람다&amp;nbsp;인자까지도&amp;nbsp;없앨수&amp;nbsp;있고&amp;nbsp;그럴경우&amp;nbsp;들어오는&amp;nbsp;값은&amp;nbsp;암묵적으로&amp;nbsp;it으로&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;됩니다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1557923956630&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; dealer?.let { 
        val name = it.name
        // 할일하기
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;let + run&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;딜러정보로부터&amp;nbsp;이름을&amp;nbsp;가져와서&amp;nbsp;사용하는데&amp;nbsp;&lt;br /&gt;만약&amp;nbsp;딜러정보가&amp;nbsp;null이거나&amp;nbsp;이름이&amp;nbsp;null이면&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;있습니다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1557924073453&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void setDealer(@Nullable Dealer dealer) {
    if(dealer == null){
        // 문제발생
    }else {
        String name = dealer.getName();
        if(name == null){
            // 문제발생
        }else{
            // 할일하기
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이름 좀더 간결한 코드로 줄여보고자 한다면 다음과 같이 바꿀 수 있을것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1557924093556&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void setDealer(@Nullable Dealer dealer) {
    if (dealer != null &amp;amp;&amp;amp; dealer.getName() != null) {
        String name = dealer.getName();
        // 할일하기
    } else {
        // 문제발생
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이때&amp;nbsp;let과&amp;nbsp;elvis&amp;nbsp;오퍼레이터,&amp;nbsp;run으로&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;구성할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557924247628&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private fun setDealer(dealer: Dealer?) {
    dealer?.name?.let {
        // 할일하기
    } ?: run {
        // 문제발생
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(아시는분들은 아시겠지만 이 방식에는 구멍이 존재합니다.&lt;/p&gt;
&lt;p&gt;let의 마지막 코드의 결과가 null인경우 의도하지 않게 run의 block으로 빠지게되어 의도하지 않은 동작을 유발시킬수 있습니다.&lt;/p&gt;
&lt;p&gt;하지만 보통은 그런 케이스가 발생하지 않아서 문제없이 사용하곤 합니다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;apply&lt;/h2&gt;
&lt;p&gt;이번에는&amp;nbsp;딜러&amp;nbsp;정보를&amp;nbsp;설정하는&amp;nbsp;코드를&amp;nbsp;보겠습니다.&lt;br /&gt;딜러&amp;nbsp;인스턴스를&amp;nbsp;생성하고&amp;nbsp;딜러정보를&amp;nbsp;열심히&amp;nbsp;set&amp;nbsp;해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557924359118&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Dealer dealer = new Dealer();
dealer.setName(&quot;ted&quot;);
dealer.setAddress(&quot;서울시 강남구&quot;);
dealer.setId(&quot;gun0912&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이&amp;nbsp;코드를&amp;nbsp;코틀린으로&amp;nbsp;만든다면&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557924384363&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val dealer = Dealer().apply {
    name = &quot;ted&quot;
    address = &quot;서울시 강남구&quot;
    id = &quot;gun0912&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;apply&amp;nbsp;를&amp;nbsp;사용하면&amp;nbsp;scope안의&amp;nbsp;정보가&amp;nbsp;dealer&amp;nbsp;인스턴스&amp;nbsp;자체가&amp;nbsp;되고&amp;nbsp;바로&amp;nbsp;해당&amp;nbsp;인스턴스의&amp;nbsp;정보를&amp;nbsp;할당할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이&amp;nbsp;apply는&amp;nbsp;이런&amp;nbsp;경우에도&amp;nbsp;좋습니다.&lt;br /&gt;Activity를&amp;nbsp;실행하기위해&amp;nbsp;Intent를&amp;nbsp;만들고&amp;nbsp;거기에&amp;nbsp;여러&amp;nbsp;값들을&amp;nbsp;Extra로&amp;nbsp;넘겨주는&amp;nbsp;함수를&amp;nbsp;많이&amp;nbsp;작성해 보셨을겁니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557924412207&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private Intent getTedActivityIntent() {
    Intent intent = new Intent(this, TedActivity.class);
    intent.putExtra(EXTRA_AAA, aaa);
    intent.putExtra(EXTRA_BBB, bbb);
    intent.putExtra(EXTRA_CCC, ccc);
    return intent;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이러한&amp;nbsp;함수도&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;새로운&amp;nbsp;Intent를&amp;nbsp;만들고&amp;nbsp;scope안에서&amp;nbsp;바로&amp;nbsp;간결하게&amp;nbsp;작성&amp;nbsp;가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557924434876&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private fun getTedActivityIntent() =
    Intent(this, TedActivity::class.java).apply {
        putExtra(EXTRA_AAA, aaa)
        putExtra(EXTRA_BBB, bbb)
        putExtra(EXTRA_CCC, ccc)
    }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2&gt;run&lt;/h2&gt;
&lt;p&gt;아까&amp;nbsp;잠깐&amp;nbsp;언급되었던&amp;nbsp;run을&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;사용할&amp;nbsp;수도&amp;nbsp;있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557924455937&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private fun initRecyclerView() {
    binding.recyclerView.run {
        adapter = recyclerViewAdapter
        layoutManager = GridLayoutManager(context, SPAN_COUNT)
        addItemDecoration(DividerItemDecoration(context, LinearLayout.VERTICAL))
        isNestedScrollingEnabled = false
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;만약&amp;nbsp;run을&amp;nbsp;사용하지&amp;nbsp;않았다면&amp;nbsp;&lt;a href=&quot;binding.recyclerview.xxxx,&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;binding.recyclerview.xxxx,&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href=&quot;binding.recyclerview.xxxx를&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;binding.recyclerview.xxxx를&lt;/a&gt;&amp;nbsp;계속&amp;nbsp;타이핑해주어야&amp;nbsp;했을것입니다.&lt;br /&gt;run은&amp;nbsp;apply와&amp;nbsp;사용방식이&amp;nbsp;비슷하지만&amp;nbsp;또&amp;nbsp;다릅니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;apply&amp;nbsp;/&amp;nbsp;also&amp;nbsp;/&amp;nbsp;run&amp;nbsp;/&amp;nbsp;let&amp;nbsp;/&amp;nbsp;with&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Apply,&amp;nbsp;also&amp;nbsp;,run,&amp;nbsp;let,&amp;nbsp;with가&amp;nbsp;사용방식이&amp;nbsp;비슷하면서도&amp;nbsp;각자가&amp;nbsp;다른&amp;nbsp;구조를&amp;nbsp;갖고&amp;nbsp;있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;788px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nf1nj/btqviF0WrxB/Eq605A7Z8UJxIe3zqMeE5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nf1nj/btqviF0WrxB/Eq605A7Z8UJxIe3zqMeE5K/img.png&quot; data-alt=&quot;https://medium.com/androiddevelopers/kotlin-standard-functions-cheat-sheet-27f032dd4326&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nf1nj/btqviF0WrxB/Eq605A7Z8UJxIe3zqMeE5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnf1nj%2FbtqviF0WrxB%2FEq605A7Z8UJxIe3zqMeE5K%2Fimg.png&quot; width=&quot;788px;&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://medium.com/androiddevelopers/kotlin-standard-functions-cheat-sheet-27f032dd4326&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;미디엄글에서&amp;nbsp;각각을&amp;nbsp;활용하면&amp;nbsp;좋은&amp;nbsp;예시를&amp;nbsp;보여주는&amp;nbsp;이미집니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한 검색하시다보면 아래와 같이 정리되어 있는 이미지도 많이 만나시게 될겁니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;758px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oquKm/btqvlSxYb1Q/0cioJSk1YnP1lXd7DVZPK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oquKm/btqvlSxYb1Q/0cioJSk1YnP1lXd7DVZPK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oquKm/btqvlSxYb1Q/0cioJSk1YnP1lXd7DVZPK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoquKm%2FbtqvlSxYb1Q%2F0cioJSk1YnP1lXd7DVZPK0%2Fimg.png&quot; width=&quot;758px;&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;scope에 this가 들어오냐 vs it이 들어오냐, &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;scope의 결과로 자기자신이 return되느냐 vs 마지막 줄의 결과가 return되느냐 &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;등 서로가 비슷하지만 다른 개념들입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;저도&amp;nbsp;사용할때마다&amp;nbsp;헷갈릴때가&amp;nbsp;많아서&lt;br /&gt;아예&amp;nbsp;출력해서&amp;nbsp;책상위에&amp;nbsp;두고&amp;nbsp;왔다갔다하면서&amp;nbsp;머리속에&amp;nbsp;넣어두고&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;500px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNW4Gr/btqvmtxWizJ/aZdljP60F4kj93rCDpWCfk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNW4Gr/btqvmtxWizJ/aZdljP60F4kj93rCDpWCfk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNW4Gr/btqvmtxWizJ/aZdljP60F4kj93rCDpWCfk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNW4Gr%2FbtqvmtxWizJ%2FaZdljP60F4kj93rCDpWCfk%2Fimg.jpg&quot; width=&quot;500px;&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;&lt;span&gt;Java코드와의 호환&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;코틀린은&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;있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557924617309&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Kotlin에서 만들고
class ForJava(var name: String, val birth: Int, var isShow: Boolean)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1557924628334&quot; class=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Java에서 사용
String name = forJava.getName();
forJava.setName(&quot;ted&quot;);

int birth = forJava.getBirth();

boolean isShow = forJava.isShow();
forJava.setShow(true);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;당연히&amp;nbsp;반대로&amp;nbsp;자바파일도&amp;nbsp;코틀린에서&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;물론&amp;nbsp;자바에서&amp;nbsp;Nullable,&amp;nbsp;NonNull같은&amp;nbsp;어노테이션이&amp;nbsp;잘&amp;nbsp;붙어&amp;nbsp;있다면&amp;nbsp;거의&amp;nbsp;완벽하게&amp;nbsp;호환되서&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있을것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&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;있습니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;@JvmName,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;@JvmField,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;@JvmStatic,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;@JvmOverloads등의&lt;/span&gt;&amp;nbsp;어노테이션들과&amp;nbsp;&lt;span style=&quot;color: #333333;&quot;&gt;Companion이라는&amp;nbsp;개념이&amp;nbsp;있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&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;있을겁니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;Extension function&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Swift언어의&amp;nbsp;extension과&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;있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557924738509&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun Context.showToast(text: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
    Toast.makeText(this, text, duration).show()
}

fun Context.startCallActivity(callNumber: String) {
    val intent = Intent(Intent.ACTION_DIAL)
    val uri = &quot;tel:$callNumber&quot;
    intent.data = Uri.parse(uri)
    startActivity(intent)
}

showToast(&quot;안녕하세요&quot;)
startCallActivity(&quot;01012345678&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;물론, 이를 만들때 Extension의&amp;nbsp;파일을&amp;nbsp;어떤&amp;nbsp;패턴으로&amp;nbsp;정의할것이냐&amp;nbsp;규칙&amp;nbsp;결정&amp;nbsp;필요합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;그외&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;더&amp;nbsp;유용하고&amp;nbsp;좋은&amp;nbsp;키워드들을&amp;nbsp;검색해서&amp;nbsp;알아보세요&lt;br /&gt;- 함수형&amp;nbsp;프로그래밍(Functional&amp;nbsp;programming)&lt;br /&gt;- 다양한&amp;nbsp;Collection관련&amp;nbsp;함수들(kotlin.collections):&amp;nbsp;&amp;nbsp;예)&amp;nbsp;listOf(1,&amp;nbsp;2,&amp;nbsp;3)&lt;br /&gt;- Lazy&amp;nbsp;execution(Sequences)&lt;br /&gt;등등&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;코틀린&amp;nbsp;변환&lt;/h2&gt;
&lt;p&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;해봅니다.&lt;/p&gt;
&lt;p&gt;[Code]&amp;nbsp;-&amp;gt;&amp;nbsp;[Convert&amp;nbsp;Java&amp;nbsp;File&amp;nbsp;to&amp;nbsp;Kotlin&amp;nbsp;File]&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;204px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JrjvP/btqvicrbP3k/SJyPWFB5rjPLA3iDdhRCAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JrjvP/btqvicrbP3k/SJyPWFB5rjPLA3iDdhRCAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JrjvP/btqvicrbP3k/SJyPWFB5rjPLA3iDdhRCAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJrjvP%2FbtqvicrbP3k%2FSJyPWFB5rjPLA3iDdhRCAk%2Fimg.png&quot; width=&quot;204px;&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;물론&amp;nbsp;단순&amp;nbsp;기계적인&amp;nbsp;변환이기때문에&amp;nbsp;코틀린스럽지&amp;nbsp;않게&amp;nbsp;변환되는&amp;nbsp;문제는&amp;nbsp;있습니다.&lt;br /&gt;하지만&amp;nbsp;그래도&amp;nbsp;처음부터&amp;nbsp;코딩하는것보다는&amp;nbsp;좋은&amp;nbsp;결과물을&amp;nbsp;보여줍니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Java코드&amp;nbsp;보기&lt;/h2&gt;
&lt;p&gt;반대로&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;스튜디오에서&amp;nbsp;제공해줍니다.&lt;/p&gt;
&lt;p&gt;[Tools]&amp;nbsp;-&amp;gt;&amp;nbsp;[Kotlin]&amp;nbsp;-&amp;gt;&amp;nbsp;[Show&amp;nbsp;Kotlin&amp;nbsp;Bytecode]&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;442px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqmClc/btqvlTp5rwS/4D73abSBwTBMKe31aXCWk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqmClc/btqvlTp5rwS/4D73abSBwTBMKe31aXCWk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqmClc/btqvlTp5rwS/4D73abSBwTBMKe31aXCWk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqmClc%2FbtqvlTp5rwS%2F4D73abSBwTBMKe31aXCWk0%2Fimg.png&quot; width=&quot;442px;&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;아까&amp;nbsp;정의했던&amp;nbsp;딜러&amp;nbsp;클래스를&amp;nbsp;코틀린으로&amp;nbsp;짠뒤에&amp;nbsp;이를&amp;nbsp;자바코드로&amp;nbsp;변환해본다면&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1557924904731&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data class Dealer(var name: String?, var address: String?)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;바이트코드는 아래와&amp;nbsp;같이&amp;nbsp;나오게&amp;nbsp;됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;752px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZQNSf/btqvhuyNuzB/jmhPp5WoNPCKNUBA1DE4Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZQNSf/btqvhuyNuzB/jmhPp5WoNPCKNUBA1DE4Kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZQNSf/btqvhuyNuzB/jmhPp5WoNPCKNUBA1DE4Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZQNSf%2FbtqvhuyNuzB%2FjmhPp5WoNPCKNUBA1DE4Kk%2Fimg.png&quot; width=&quot;752px;&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;물론&amp;nbsp;뭐라는지&amp;nbsp;알아볼&amp;nbsp;수가&amp;nbsp;없겠죠&amp;hellip;&lt;br /&gt;여기서&amp;nbsp;Decompile버튼을&amp;nbsp;누릅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;692px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/de69tF/btqvkx192BI/WI4DiKEJJ1NJkbphTYnYrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/de69tF/btqvkx192BI/WI4DiKEJJ1NJkbphTYnYrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/de69tF/btqvkx192BI/WI4DiKEJJ1NJkbphTYnYrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fde69tF%2Fbtqvkx192BI%2FWI4DiKEJJ1NJkbphTYnYrk%2Fimg.png&quot; width=&quot;692px;&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;그럼 위와&amp;nbsp;같이&amp;nbsp;아까&amp;nbsp;정의했던&amp;nbsp;Dealer클래스가&amp;nbsp;자바로&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;쓰입니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;현업개발&lt;/h2&gt;
&lt;p&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;것입니다.&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;있습니다.&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;있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;현재&amp;nbsp;사내&amp;nbsp;안드로이드&amp;nbsp;팀&amp;nbsp;코틀린&amp;nbsp;코드&amp;nbsp;작성&amp;nbsp;규칙&lt;/b&gt;&lt;br /&gt;- 새로운&amp;nbsp;코드는&amp;nbsp;코틀린으로&amp;nbsp;작성&lt;br /&gt;- 피쳐개발로&amp;nbsp;인해&amp;nbsp;기존코드를&amp;nbsp;수정해야할경우,&amp;nbsp;간단한&amp;nbsp;코드면&amp;nbsp;함께&amp;nbsp;kotlin으로&amp;nbsp;변환&lt;br /&gt;- 여유가&amp;nbsp;될때마다&amp;nbsp;kotlin코드로&amp;nbsp;리팩토링&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;물론&amp;nbsp;제가&amp;nbsp;개인적으로&amp;nbsp;만드는&amp;nbsp;코드나&amp;nbsp;라이브러리들은&amp;nbsp;100%&amp;nbsp;코틀린으로&amp;nbsp;작성하고&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;864px;&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Y8lL4/btqvi5SyHlx/Wwgykq4tV0lVZKjTNLzJf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Y8lL4/btqvi5SyHlx/Wwgykq4tV0lVZKjTNLzJf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Y8lL4/btqvi5SyHlx/Wwgykq4tV0lVZKjTNLzJf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FY8lL4%2Fbtqvi5SyHlx%2FWwgykq4tV0lVZKjTNLzJf0%2Fimg.png&quot; width=&quot;864px;&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;코틀린을&amp;nbsp;자바처럼&amp;nbsp;코딩하지&amp;nbsp;말자&lt;/h2&gt;
&lt;p&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;봅니다.&lt;br /&gt;코틀린을&amp;nbsp;겉핥기로&amp;nbsp;공부한사람은&amp;nbsp;코틀린을&amp;nbsp;자바처럼&amp;nbsp;코딩합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;아래는 코틀린을 제대로 잘 활용하지 않은 사례의 코드들입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1557925037417&quot; class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val name = bid!!.dealer!!.name
val address = bid!!.dealer!!.address

val intent = Intent(this, TedActivity::class.java)
intent.putExtra(EXTRA_AAA, aaa);
intent.putExtra(EXTRA_BBB, bbb);
intent.putExtra(EXTRA_CCC, ccc);


Log.d(&quot;ted&quot;, &quot;딜러이름: &quot; + name + &quot; , 딜러주소:&quot; + address)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;물론&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;언급했던&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;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;물론&amp;nbsp;일부는&amp;nbsp;IDE에서&amp;nbsp;warning으로&amp;nbsp;알려주기때문에&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;될것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;내가&amp;nbsp;작성한&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;도움을&amp;nbsp;주면&amp;nbsp;좋을것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Kotlin&amp;nbsp;꼭&amp;nbsp;해야하나요?&lt;/h2&gt;
&lt;p&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;싶습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이상입니다.&lt;/p&gt;
&lt;p&gt;끝까지 읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/81</guid>
      <comments>https://gun0912.tistory.com/81#entry81comment</comments>
      <pubDate>Wed, 15 May 2019 22:03:31 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드]CLEARTEXT communication to XXXX not permitted by network security policy</title>
      <link>https://gun0912.tistory.com/80</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 350px; width: 350px; height: 205px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99EB2D3B5C0CFE5704&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99EB2D3B5C0CFE5704&quot; width=&quot;350&quot; height=&quot;205&quot; filename=&quot;HTTP-To-HTTPS.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 350px; height: 205px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&quot;CLEARTEXT communication to XXXX not permitted by network security policy&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;어느날 코드를 바꾼게 없는데도 위와 같은 오류가 발생하면서 앱이 실행이 안되는 일이 발생합니다.&lt;/p&gt;&lt;p&gt;그 이유는 여러분 혹은 사용자폰의 OS가&amp;nbsp;안드로이드 9.0 파이(Pie)이기 때문입니다.&lt;/p&gt;&lt;p&gt;그리고 &lt;b&gt;여러분이 사용하는 API주소, 이미지주소 등 네트워크 경로가&amp;nbsp;https가 아닌 http로 되어 있기 때문&lt;/b&gt;입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 9.0 파이에서는 https를 사용하도록 강제합니다.&lt;/p&gt;&lt;p&gt;주소가 http인경우 위와같은 에러메세지가 발생하게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://android-developers.googleblog.com/2018/04/protecting-users-with-tls-by-default-in.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Protecting users with TLS by default in Android P&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://developers-kr.googleblog.com/2018/08/introducing-android-9-pie.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;그외 안드로이드 9.0 파이에서 추가/변경된 내용 살펴보기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2018.12.09 기준으로 아직 안드로이드 9.0 파이버전이 정식배포되지 않아서 이 오류를 발견하신분들은 많지&amp;nbsp;않을것입니다.&lt;/p&gt;&lt;p&gt;지금까지 우리는 마시멜로우, 오레오 등으로 OS를 업데이트할때마다 여러 이슈들에 맞닥뜨린 경험이 많았습니다.&lt;/p&gt;&lt;p&gt;그래서 저는 파이버전이 미리 배포되기전에 직접 제 폰을 업데이트해서 앞으로 발생할 이슈가 없는지 체크해보았습니다.&lt;/p&gt;&lt;p&gt;(삼성 멤버스앱에서 베타 프로그램에 가입하면 파이버전으로 업데이트해서 테스트해볼 수 있습니다.)&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;해결방법1&lt;/h1&gt;&lt;p&gt;아주 간단합니다.&lt;/p&gt;&lt;p&gt;현재 앱안에서 사용중인 &lt;b&gt;네트워크 주소를 http -&amp;gt; https 로 변경&lt;/b&gt;하세요.&lt;/p&gt;&lt;p&gt;그럼 더이상 바꿀 코드가 없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;&lt;br /&gt;&lt;/h1&gt;&lt;h1&gt;해결방법2&lt;/h1&gt;&lt;p&gt;물론 1번 방법으로 간단하게 변경할 수 없는 경우가 있습니다.&lt;/p&gt;&lt;p&gt;서버에서 아직 https로 구성되어 있지 않은경우에는 어쩔수없이 http로 사용해야합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그럴때는 &lt;b&gt;해당 서버주소를 http여도 실행되도록 허용해주도록 설정&lt;/b&gt;해줍니다.&lt;/p&gt;&lt;p&gt;res/xml 에 아래와 같은 xml파일을 만들어 줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;res/xml/network_security_config.xml&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43); font-family: Menlo; font-size: 9pt;&quot;&gt;&lt;p style=&quot;&quot;&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186);&quot;&gt;xml version=&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;1.0&quot; &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186);&quot;&gt;encoding=&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;?&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;lt;network-security-config&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;    &amp;lt;domain-config &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186);&quot;&gt;cleartextTrafficPermitted=&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;        &amp;lt;domain &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186);&quot;&gt;includeSubdomains=&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;font color=&quot;#a9b7c6&quot;&gt;api.xxx.com&lt;/font&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;lt;/domain&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;    &amp;lt;/domain-config&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;lt;/network-security-config&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;그리고 Manifest에 이 xml파일을 config파일로 지정해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: Menlo; font-size: 9pt;&quot;&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;&amp;lt;application&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;...&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170);&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186);&quot;&gt;:networkSecurityConfig=&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;@xml/network_security_config&quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1&gt;&lt;br /&gt;&lt;/h1&gt;&lt;h1&gt;해결방법 2-1&lt;/h1&gt;&lt;div&gt;위의 방법은 특정 주소를 허용가능하도록 설정하지만 그렇지 않은 상황인 경우도 있습니다.&lt;/div&gt;&lt;div&gt;예를들면, 우리 서비스가 아닌 특정 사이트나 특정 이미지 경로를 외부를 통해서 가져오게 되는데 이는 우리가 컨트롤 할 수 없는 부분이기 때문에 어쩔수없이 http주소를 사용해야 하는 경우도 있습니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;그럴땐 위의 res/xml/network_security_config.xml에서 &lt;b&gt;모든 경로가 허용되도록 설정&lt;/b&gt;해줍니다.&lt;/div&gt;&lt;div&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xml version=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;1.0&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;encoding=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;?&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;network-security-config&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;base-config &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;cleartextTrafficPermitted=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;true&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/network-security-config&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1&gt;&lt;br /&gt;&lt;/h1&gt;&lt;h1&gt;해결방법3&lt;/h1&gt;&lt;p&gt;위의 방법보다 더 간단한 방법도 있습니다.&lt;/p&gt;&lt;p&gt;Android Manfest에서 &lt;b&gt;usesCleartextTraffic를 true로 설정&lt;/b&gt;합니다.&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43); font-family: Menlo; font-size: 9pt;&quot;&gt;&lt;p style=&quot;&quot;&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;lt;application&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;    &lt;/span&gt;&lt;font color=&quot;#9876aa&quot;&gt;...&lt;/font&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170);&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186);&quot;&gt;:usesCleartextTraffic=&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;이 방법이 2번의 방법보다 훨씬 간단한데 어떤점에서 안좋은게 있는것인지는 아직 알 수 없습니다.&lt;/p&gt;&lt;p&gt;혹시 3번의 방법의 단점을 아시는분은 댓글로 알려주시면 감사하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;구글님 저희가 잘못했습니다.. 어린양을 괴롭히지 말아주세요..&lt;/p&gt;&lt;p&gt;안드로이드 기기의 파편화만으로도 대응하기 너무 힘든데 API레벨 OS별로 대응을 하도록 하지 않도록 도와주세요.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;하지만 우린&amp;nbsp;답을 찾을것이다. 늘 그랬듯이&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 400px; width: 400px; height: 572px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/991DF63B5C0CFE260A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F991DF63B5C0CFE260A&quot; width=&quot;400&quot; height=&quot;572&quot; filename=&quot;d747477a73baabb5a96020d67825429f8345e680105da214f5c49dc56c5715ceecffd938868c27a1838bb5d3e24b339b4d8d724aa370ef33521598cf161c0c0bee7c637c0278788259c34ed34bf355a9.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 400px; height: 572px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;(&amp;nbsp;&lt;a href=&quot;http://gun0912.tistory.com/79&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드]Only fullscreen opaque activities can request orientation&lt;/a&gt;&amp;nbsp;과&amp;nbsp;중복주의)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그럼 모든 안드로이드 개발자분들의 정신건강을 응원합니다.&lt;/p&gt;&lt;p&gt;피쓰.&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/80</guid>
      <comments>https://gun0912.tistory.com/80#entry80comment</comments>
      <pubDate>Sun, 9 Dec 2018 20:39:49 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드]Only fullscreen opaque activities can request orientation</title>
      <link>https://gun0912.tistory.com/79</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 400px; width: 400px; height: 225px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/998875355B4DE0D238&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F998875355B4DE0D238&quot; width=&quot;400&quot; height=&quot;225&quot; filename=&quot;993D2D495A76E41A1E.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 400px; height: 225px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;&quot;Only fullscreen opaque activities can request orientation&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 오류 메세지는 갈길바쁜 저희를 힘들게 만듭니다.&lt;/p&gt;&lt;p&gt;이 문장으로 검색하신분들은 대부분 targetSdkVersion을 26이상으로 올리기위한 작업을 한뒤에 이 오류를 받아보셨을 것입니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;더 정확히는 targetSdkVersion를 27이상으로 설정했을경우 문제가 발생합니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 550px; width: 550px; height: 260px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/994D3C395B4E0F651B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F994D3C395B4E0F651B&quot; width=&quot;550&quot; height=&quot;260&quot; filename=&quot;Screenshot at 7월 18 00-20-26.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 550px; height: 260px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;이 오류는 왜 발생하는가&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;여러가지 이유로 투명한 Activity를 만들기위해서 style.xml에 android:windowIsTranslucent를 사용합니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;style &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;AppTheme.Transparent&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;parent=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@style/TransparentBase&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android:windowIsTranslucent&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;true&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;문제는 이&amp;nbsp;android:windowIsTranslucent로 인해서 발생합니다.&lt;/p&gt;&lt;p&gt;API 26(8.0) SDK에서 아래와 같은 코드가 추가되었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 782px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99B41E445B4DE7AF18&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99B41E445B4DE7AF18&quot; width=&quot;782&quot; height=&quot;387&quot; filename=&quot;Screenshot at 7월 17 21-54-36.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 내용은 아래 파일에서 직접 확인가능 합니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r36/core/java/android/app/Activity.java#986&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Activity.java&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;API26에서는 Translucent/Floating 으로 만든 투명한 Activity들은 화면 회전고정을 하지 못하게 의도한 것입니다.&lt;/p&gt;&lt;p&gt;아래 commit 메세지에서 위와같은 코드를 추가한 것입니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://android.googlesource.com/platform/frameworks/base/+/39791594560b2326625b663ed6796882900c220f&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://android.googlesource.com/platform/frameworks/base/+/39791594560b2326625b663ed6796882900c220f&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strike&gt;이 이슈덕분에 안드로이드 버전별 SDK코드도 다 까보고 commit 메세지까지 다 확인해보고 내가 구글 안드로이드 개발자가 된 기분은 개뿔&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;strike&gt;&lt;br /&gt;&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;이와 같은 히스토리로 인해서 우리는 에러를 만나게 되었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;병주고 약주고&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Google 개발자들도 이건 아니다 싶었는지 API 27(8.1)에서는 이 코드를 삭제해 버렸습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99097F3F5B4DE98203&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99097F3F5B4DE98203&quot; width=&quot;820&quot; height=&quot;355&quot; filename=&quot;Screenshot at 7월 17 22-04-55.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://android.googlesource.com/platform/frameworks/base/+/d4ecffae67fa0dea03c581ca26f76b87a14be763%5E%21/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://android.googlesource.com/platform/frameworks/base/+/d4ecffae67fa0dea03c581ca26f76b87a14be763%5E%21/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;API 27(8.1)기기 이후부터는 windowIsTranslucent을 사용해도 오류를 발생시키지 않게 됩니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;즉,&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt; 이 오류 메세지는 API 26(8.0) 기기에서만 발생합니다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;대처하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;1. targetSdkVersion 26미만으로 내리기&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;build.gradle에서 targetSdkVersion을 26으로 내려버리면 이 문제는 발생하지 않습니다.&lt;/p&gt;&lt;p&gt;(참고로 targetSdkVersion를 올렸다가 내리는건 23-&amp;gt;22만 불가능하고 다른경우에는 가능합니다.)&lt;/p&gt;&lt;p&gt;하지만 이방법은 임시방편일뿐 올해안에 언젠가 다시 또 그이상으로 올리도록 대응을 해야하기 때문에 &lt;b&gt;추천하지 않습니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;2.&amp;nbsp;Orientation 주지 않기&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;1) xml&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Manifest파일에 스크린을 고정하기위해&amp;nbsp;android:screenOrientation=&quot;portrait&quot; 을 넣으셨을겁니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;activity &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;.MainActivity&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:screenOrientation=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;portrait&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:theme=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@style/AppTheme.Transparent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;여기에서 android:screenOrientation=&quot;unspecified&quot; 로 설정해주시면 가로/세로 고정을 지정하지 않기때문에 에러가 발생하지 않습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:screenOrientation=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;unspecified&quot;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;2) Java&lt;/span&gt;&lt;/p&gt;&lt;p&gt;만약 가로/세로 고정을 Java코드에서 BaseActivity에서 아래와 같이 항상 고정을 하도록 구현하신분들도 계실겁니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;setRequestedOrientation(ActivityInfo.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;SCREEN_ORIENTATION_PORTRAIT&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;이러한 경우에는 투명Activity로 구현해야하는 부분에서 setRequestedOrientation() 함수를 override해서 no-op 처리해주면 됩니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setRequestedOrientation&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;requestedOrientation) {&lt;br /&gt;   &lt;span style=&quot;color:#808080;&quot;&gt;/*&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        // no-op&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    }else{&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        super.setRequestedOrientation(requestedOrientation);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    */&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(Build.VERSION.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;SDK_INT &lt;/span&gt;!= Build.VERSION_CODES.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;O&lt;/span&gt;) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.setRequestedOrientation(requestedOrientation)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;대부분의 개발자들이 이 방법으로 해결하셨을겁니다.&lt;/p&gt;&lt;p&gt;제가 만든 오픈소스 라이브러리들에서 Proxy Activity개념으로 동작하는 투명한 액티비티들에도 이 방법으로 해결했습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedRxOnActivityResult/pull/6&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedRxOnActivityResult/pull/6&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission/pull/74&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedPermission/pull/74&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;단, 화면회전에 대한 고정을 하지 않았기 때문에 사용자가 기기를 회전하는 것에 대해 이슈가 없는지 꼭 테스트를 해보아야 합니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;3. try/catch&lt;/span&gt;&lt;/p&gt;&lt;p&gt;만약 2번에서 2번째 방법인 BaseActivity에서&amp;nbsp;setRequestedOrientation()로 고정해주고 있다면 해당 코드만 try/catch로 처리해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;try &lt;/span&gt;{&lt;br /&gt;    setRequestedOrientation(ActivityInfo.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;SCREEN_ORIENTATION_PORTRAIT&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;catch &lt;/span&gt;(IllegalStateException ignore) {&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;이렇게 처리해주면 투명한 Activity에서 에러가 발생하더라도 이를 무시하고 투명한 화면을 보여줄 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;4. API 26에서만 windowIsTranslucent 안쓰기&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위에서 말씀드렸던것처럼 이 이슈는 오직 API 26(8.0)기기에서만 문제가 발생한다는것을 기억하실 겁니다.&lt;/p&gt;&lt;p&gt;이를 이용해서 style.xml을 API 버전별로 다른 동작을 하도록 분기시켜줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 242px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/994D80375B4E0AE307&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F994D80375B4E0AE307&quot; width=&quot;242&quot; height=&quot;304&quot; filename=&quot;Screenshot at 7월 18 00-27-20.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위와 같이 style.xml 파일을 values, values-v26, values-v27 폴더에 각각 만들어줍니다.&lt;/p&gt;&lt;p&gt;여기서 values-v26에 있는 style.xml에만 windowIsTranslucent을 구현해주지 않으면 해결할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;values/style.xml&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;style &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;TransparentBase&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;parent=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@style/AppTheme&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android:windowBackground&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;@android:color/transparent&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;style &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;AppTheme.Transparent&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;parent=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@style/TransparentBase&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android:windowIsTranslucent&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;true&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;values-v26/style.xml&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;style &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;AppTheme.Transparent&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;parent=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@style/TransparentBase&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;values-v27/style.xml&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;style &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;AppTheme.Transparent&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;parent=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@style/TransparentBase&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android:windowIsTranslucent&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;true&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;위의 코드에서 확인하실 수 있듯이 values-v26/style.xml에서는 아무 태그를 넣어주지 않게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;단, 이 방법으로 구현할경우 API 26(8.0)기기에서는 투명한 화면으로 나타나지 않기 때문에 이에 대한 처리를 해줘야 합니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;(Activity를 시작하기전에 현재화면의 내용을 캡쳐해서 ImageView에 그려서 background로 지정하는 등의 방법)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ProxyActivity개념으로 사용하는 코드라면 이 방법은 맞지 않습니다.&lt;/p&gt;&lt;p&gt;만약 투명액티비티를 fade-in의 효과를 내면서 나타나게 하기위한 용도로 사용했다면 이 방법을 사용하시면 좋습니다.&lt;/p&gt;&lt;p&gt;API 26(8.0) 기기에서만 fade-in 없이 바로 나오는 정도가 될것이기때문에 큰 이슈가 되지는 않을것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 350px; width: 350px; height: 176px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/995CE93F5B4E0E962A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F995CE93F5B4E0E962A&quot; width=&quot;350&quot; height=&quot;176&quot; filename=&quot;afflict.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 350px; height: 176px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;구글님 저희가 잘못했습니다.. 어린양을 괴롭히지 말아주세요..&lt;/p&gt;&lt;p&gt;안드로이드 기기의 파편화만으로도 대응하기 너무 힘든데 API레벨 OS별로 대응을 하도록 하지 않도록 도와주세요.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;하지만 우린&amp;nbsp;답을 찾을것이다. 늘 그랬듯이&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 350px; width: 350px; height: 500px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99DFE1405B4E0F2C12&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99DFE1405B4E0F2C12&quot; width=&quot;350&quot; height=&quot;500&quot; filename=&quot;d747477a73baabb5a96020d67825429f8345e680105da214f5c49dc56c5715ceecffd938868c27a1838bb5d3e24b339b4d8d724aa370ef33521598cf161c0c0bee7c637c0278788259c34ed34bf355a9.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 350px; height: 500px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;피쓰~&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/79</guid>
      <comments>https://gun0912.tistory.com/79#entry79comment</comments>
      <pubDate>Wed, 18 Jul 2018 00:54:13 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드]Firebase Dynamic Link로  사용자 유입시키기</title>
      <link>https://gun0912.tistory.com/78</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 200px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/991644345B0D32D921&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F991644345B0D32D921&quot; width=&quot;200&quot; height=&quot;200&quot; filename=&quot;firebase-dynamic-links-logo.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 200px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 포스팅과 같은 내용의 동영상 강의를 확인하시려면 아래 영상을 시청해주세요&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://goo.gl/dbPCaA&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://goo.gl/dbPCaA&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(68, 68, 68); font-family: Roboto, Helvetica, Arial, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;어플리케이션 서비스들의 홈페이지를 들어가보면 아래와 같은 화면들을 만나볼 수 있습니다.&lt;/p&gt;&lt;p&gt;이런 서비스들은 서비스에 관심있는사람이 앱을 설치할 수 있도록 설치버튼을 보여줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span id=&quot;docs-internal-guid-ad3ee4a9-ab8f-9e1d-9a1a-02975da4765d&quot;&gt;&lt;img src=&quot;https://lh6.googleusercontent.com/QAaaYnEIL1TjJzG_2BE9GZpJmfBv4ihFzb7wNB1b5xwfJPBEVmIzX9Fut60Tp2qgBSUIY1D0JlsEaQH4gixdij5xRQHU_gd1CFl50rQVYu_WUvXkbZqPVdaknLbiyJ3aTy38dwCWHV4&quot; width=&quot;212px;&quot; height=&quot;376px;&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;img src=&quot;https://lh4.googleusercontent.com/f6jYXVondQktgcu3KwqT09KR0loxu8AgltIULz51BOe2qVRyCFTJ826_5NP6ioRZsefspncIT0xVn1TUpvIFm_eOMokXFb2tkeucTEFXt4fk5RCVCUMjHOc628xjIAH3W53L9AxMDN8&quot; width=&quot;212px;&quot; height=&quot;376px;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img src=&quot;https://lh5.googleusercontent.com/Lq2Ae4-miZPUFR7xBg_JeBNSQ6hw5B3guStvf8j6Pki3FWph3dveb5cKaNninv1XGWhkyKBh86VMfhpoQPp_1H_10hCgIjamARAEQIV2cVOCyMB4aFK4W7s6au_-kKXyq9AS51P4D1A&quot; width=&quot;212px;&quot; height=&quot;376px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;(참고로 저는 이 서비스들을 정말 좋아합니다. 기술력도 좋아합니다. 깎아 내리려는 의도는 없습니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 사용자는 구글플레이 이미지를 누르면 해당 마켓으로 이동될것이고, 아이폰 사용자는 앱스토어 이미지를 누르면 해당 마켓으로 이동될 것입니다.&lt;/p&gt;&lt;p&gt;하지만 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;안드로이드 사용자든 아이폰 사용자든 상관없이 설치버튼을 누르면 알아서 해당 사용자의 마켓에 맞게 이동시켜주는 방식이 더 좋은 화면UI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또한 만약 이미 해당 서비스가 설치되어 있는사용자라고 하더라도 무조건 설치페이지로 보내버립니다.&lt;/p&gt;&lt;p&gt;그래서 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;이미 설치된 사용자라면 해당 버튼을 눌렀을때 앱을 실행시키도록 하는것이 더 좋은 방식&lt;/b&gt;&lt;/span&gt;이라고 생각합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span id=&quot;docs-internal-guid-6acd803a-ab94-a37b-628d-dd7016da0d01&quot;&gt;&lt;img src=&quot;https://lh3.googleusercontent.com/7C2EqLlT2EHSnDJw8wjQe_sLYFYnUbtheQpic29I2UIW14zJ2gxCbhrYuZZtcO0wBZ-i9WAARlfMM0Djnx0hGt2fWJWV6zgS4Bd0RrgSoLAwe7JDjyRjKw44nmMQaFOJ7Uy5ySYcGCY&quot; width=&quot;383px;&quot; height=&quot;401px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;그래서 기획자는 아래와 같은 개발을 요구하게 됩니다.&lt;/p&gt;&lt;p&gt;- 사용자가 안드로이드인지 아이폰인지 구분해서 해당 마켓으로 보내주세요&lt;/p&gt;&lt;p&gt;- 이미 앱을 설치한 사용자라면 앱을 실행하게 해주세요&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;- 전 기획자니까 이 기능은 개발자님이 만들어 주셔야죠&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;대부분의 개발자분들은 딥링크를 활용해서 아래와 같이 구현하셨을겁니다.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://lh5.googleusercontent.com/fZtWfXBg2wcp3mM7ehuXYRZgsFh6yodeqnVG-z4Cnk1HILQOY0aN-E3OLBNtp2LAKnBsdhDsGj54OKtTm2Adg0h7qIw7JxKCsKM3H9xWdI5tSXsUPgA8zOm0-wJxuWhluOo1bCjo8pU&quot; width=&quot;605px;&quot; height=&quot;177px;&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;span id=&quot;docs-internal-guid-70ce55f0-abb0-1401-e602-b2e70c6e49c7&quot;&gt;&lt;img src=&quot;https://lh4.googleusercontent.com/tTjVw44EgmcFpaQK4vZbn4BWVNgg2FiQAjBiBch-bk4QUxkYkmj5oGz2TR1O67zK34TouQp__AAWOwQgE3oYmR6595Fzo_OBF-PB6siaWOzeAFfrzAHPMCtwlXQGX-c6tB3Po3YTJt8&quot; width=&quot;289px;&quot; height=&quot;376px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;주로 카드결제나 외부앱을 실행해야하는 경우 딥링크와 타임아웃으로 앱설치여부를 판단하는경우가 많습니다.&lt;/p&gt;&lt;p&gt;이런방식으로 어느정도 해결할 수 있긴하지만 기획자나 마케터가 이런 기능을 요청할때마다 개발자가 이런 형태의 html을 매번 만들어주어야 하는 번거로움이 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이럴때 Firebase의 Dynamic link를 사용해주면 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span id=&quot;docs-internal-guid-562eced4-abb1-65b0-769a-d702da7d77d4&quot;&gt;&lt;img src=&quot;https://lh3.googleusercontent.com/9MxI96Ee-eqaMYFhd0Z9kiMbOJ4IFdhRacH_NHX6KOyANOt504vfYmepqnHB2gU4pqvzGQmunN21TrEkT-NgKGV42p2CqUaEePYeKPcjG4oBm-VQb9hESE_yny9mMPwPEPkHk7fmt0E&quot; width=&quot;960px;&quot; height=&quot;540px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Firebase Dynamic link는 위에서 매번 만들어주었던 기능을 간단하게 만들 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;Console에서 직접 링크 만들기&lt;/h1&gt;&lt;p&gt;기획자나 마케터는 코드를 몰라도 개발자 없이 콘솔에서 직접 위와 같은 기능을 하는 링크를 생성할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Firebase의 콘솔에서 Dynamic link페이지를 들어갑니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px; width: 500px; height: 512px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99EC81435B0D3E2A12&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99EC81435B0D3E2A12&quot; width=&quot;500&quot; height=&quot;512&quot; filename=&quot;Screenshot at 5월 29 20-47-39.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 500px; height: 512px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;앱이 설치되어있을경우 실행시킬 딥링크와 이름을 설정해줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;딥링크를 받아서 해당 기능을 실행시키는 방법은 아래 샘플 코드에서 구현되어 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px; width: 500px; height: 586px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9911B3435B0D3E2A26&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9911B3435B0D3E2A26&quot; width=&quot;500&quot; height=&quot;586&quot; filename=&quot;Screenshot at 5월 29 20-47-58.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 500px; height: 586px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;앱이 설치되어있지 않은 사용자의 경우 해당 패키지의 구글플레이 설치화면으로 보내줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;꼭 구글플레이 설치화면이 아니라 원하는 URL로 안드로이드 사용자를 연결 시킬 수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px; width: 500px; height: 570px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9925D2435B0D3E2B23&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9925D2435B0D3E2B23&quot; width=&quot;500&quot; height=&quot;570&quot; filename=&quot;Screenshot at 5월 29 20-48-32.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 500px; height: 570px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Dynamic link에 캠페인 추적을 위한 utm_xxx 들을 넣어줄수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px; width: 500px; height: 372px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99F9F8395B0D3FDB2A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99F9F8395B0D3FDB2A&quot; width=&quot;500&quot; height=&quot;372&quot; filename=&quot;Screenshot at 5월 29 20-55-17.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 500px; height: 372px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;생성된 dynamic link는 실제로는 아래와 같은 url을 갖습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;dynamic link생성에 익숙해진다면 그이후로는 콘솔에서 작업없이도 url에서 필요한 파라미터들만 바꿔서 바로 원하는 url을 만들어 줄 수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;각 파라미터의 역할과 좀더 다양한 다른 파라미터들에 대해서 살펴보시려면 아래 문서를 참고하세요&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://firebase.google.com/docs/dynamic-links/create-manually?hl=ko&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://firebase.google.com/docs/dynamic-links/create-manually?hl=ko&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;사실 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;Dynamic Link의 정말 좋은 기능은 이제부터 소개시켜드릴 기능&lt;/b&gt;&lt;/span&gt;입니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;중고차 판매 시세 공유하기&lt;/h1&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;저는 현재 PRND컴퍼니에서 헤이딜러라는 중고차 판매 가격비교 서비스를 개발하고 있습니다.&lt;/p&gt;&lt;p&gt;헤이딜러 서비스는 딜러에게 차량을 판매할때 경매시스템의 형태로 최고가 혹은 원하는 딜러에게 판매할 수 있는 서비스입니다.&lt;/p&gt;&lt;p&gt;최근에 추가된 시세조회 기능을 통해 각 차량별 딜러판매 시세를 미리 파악해볼 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span id=&quot;docs-internal-guid-144c0228-abc5-d34a-ccaa-0dd585bfffe9&quot;&gt;&lt;img src=&quot;https://lh6.googleusercontent.com/ObgKLyCpD6yKSpzti8SUkfwSfNfeLdnIeP1o7MCZerzU8zdpKkgBAaswlBY46vW7PutHRbUN1ca0-V6SjgBQtP4p8RJgBji3cn6uXLF2uFzHZa0qsA2UDbr4j8Oy_0cB3wVPtD4WxN0&quot; width=&quot;182px;&quot; height=&quot;375px;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img src=&quot;https://lh4.googleusercontent.com/PTHMOqocUca0V76cOnkTJWoDGEU-3dmVkXA-kYqVjDW6Gd7rvoTzb1X4JMc8CBgmaZPUirqhBVWvpBfTbzKgI6AKeWwliJBmaQ_qXQ7QTXAfNl95MbP6sWc8Ic4jWf-OKI9THHWkAgo&quot; width=&quot;182px;&quot; height=&quot;375px;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img src=&quot;https://lh5.googleusercontent.com/_stru3if3JYLZakzl30f4I7A23R4yZAcR2syZ1DPpWQ8xtCMKdKt-NftZyCESOQusqCObGnN4hv4fEGSqYqjZgyQK2R1r4qUiiVmF57TjB0vKv9fTMKOR5a3NeNxEQIFMP_X1PRSOMY&quot; width=&quot;182px;&quot; height=&quot;375px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h1&gt;&lt;span&gt;공유하기&lt;/span&gt;&lt;/h1&gt;&lt;p&gt;만약 아반떼AD의 판매 시세를 친구에게 알려주기 위해 공유를 한다면 아래와 같은 과정을 거칠것입니다.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px; text-align: center;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99E8BE4B5B0D452B10&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99E8BE4B5B0D452B10&quot; width=&quot;820&quot; height=&quot;355&quot; filename=&quot;Screenshot at 5월 29 21-18-02.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;text-align: center;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;1. 친구에게 해당 차량의 시세정보와 서비스를 알려줌&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;2. 친구는 해당 서비스를 마켓에서 검색&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;3. 앱 설치&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;4. 메인화면 실행&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/995F4A4B5B0D453D36&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F995F4A4B5B0D453D36&quot; width=&quot;820&quot; height=&quot;355&quot; filename=&quot;Screenshot at 5월 29 21-18-10.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;5. 시세조회 기능 선택&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;6....&lt;/span&gt;7.....8....9....&lt;/p&gt;&lt;p&gt;10. 기타 등등의 과정을 거쳐서 친구가 공유해줬던 해당차량의 시세조회 기능에 도달하여 알게됨&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 350px; width: 350px; height: 197px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9986A84B5B0D4E131C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9986A84B5B0D4E131C&quot; width=&quot;350&quot; height=&quot;197&quot; filename=&quot;hate.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 350px; height: 197px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;수많은 단계를 거치다보면 어쩌면 그 친구는 해당 화면까지 도달하지 못했을수도 있습니다...&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;Dynamic Link로 공유하기&lt;/h1&gt;&lt;p&gt;Dynamic Link를 사용한다면 단 3단계면 충분합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 611px; width: 611px; height: 355px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99D43C4D5B0D45A026&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99D43C4D5B0D45A026&quot; width=&quot;611&quot; height=&quot;355&quot; filename=&quot;Screenshot at 5월 29 21-18-18.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 611px; height: 355px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;1. 친구에게 공유할때 알아서 해당 정보의 Dynamic link가 함께 공유&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2. 링크를 누르면 해당 마켓의 설치화면 이동&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;3. 설치후 실행시 해당 차량의 시세조회 기능에 바로 도달&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;이전 vs 이후&lt;/h1&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/994D3B485B0D45F807&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F994D3B485B0D45F807&quot; width=&quot;820&quot; height=&quot;341&quot; filename=&quot;Screenshot at 5월 29 21-18-27.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Dynamic Link를 적용하기 전과 후의 사용자가 거쳐야할 단계 차이를 명확하게 확인할 수 있습니다.&lt;/p&gt;&lt;p&gt;화면 단계단계마다 사용자가 이탈할 확률이 높아지기 때문에 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;서비스를 운영하는 입장에서는 최대한 이 단계를 줄여서 사용자가 원하는 정보에 도달시켜주는것이 중요&lt;/b&gt;&lt;/span&gt;합니다.&lt;/p&gt;&lt;p&gt;그렇기 때문에 Dynamic Link가 사용자를 유입시키는데 굉장히 효과적인 역할을 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;활용할만한 사례들&lt;/h1&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Dynamic Link를 활용하기 좋은 사례들은 아래와 같습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;광고/판매페이지 -&amp;gt; 앱안에서의 해당 화면&lt;/h2&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 622px; width: 622px; height: 355px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/994E624D5B0D46AA08&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F994E624D5B0D46AA08&quot; width=&quot;622&quot; height=&quot;355&quot; filename=&quot;Screenshot at 5월 29 21-24-05.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 622px; height: 355px;&quot; original=&quot;yes&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;항공권 예약서비스 혹은 쇼핑몰 등에서 친구에게 해당 상품을 알려주고 그 친구가 서비스에 진입했을때 바로 해당 상품의 화면으로 이동시킬 수 있을 것입니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2&gt;숙박/게임 서비스 추천인코드 입력&lt;/h2&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 610px; width: 610px; height: 355px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/992E564D5B0D46AA0B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F992E564D5B0D46AA0B&quot; width=&quot;610&quot; height=&quot;355&quot; filename=&quot;Screenshot at 5월 29 21-24-14.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 610px; height: 355px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;호텔이나 기타 서비스에서 지인에게 추천을 해주고 추천인코드를 넣었을때 혜택을 주는 서비스의 경우도 좋을 것입니다.&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;&lt;br /&gt;&lt;/h2&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2&gt;QR코드를 활용한 오프라인 프로모션&lt;/h2&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span id=&quot;docs-internal-guid-c29606c1-abdf-d07a-4b41-279ce4204d60&quot;&gt;&lt;img src=&quot;https://lh4.googleusercontent.com/vH-mWU_YLApIhmoscnuiMUGIkJJk1GZASXITaVEsgm06YAo-kbZjRIC_-y3D4esQMFQuXIsASjngw1DZ5cEZ_It_RnjolAQ2zerO_JH94pXG29iHxlIHfgj1qW0huC4gY9wgljvLDNk&quot; width=&quot;669px;&quot; height=&quot;376px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;오프라인으로 서비스를 홍보하거나 특정 이벤트를 진행하는 경우 QR코드 자체에 dynamic link를 넣어두어 어떤경로로 사용자가 유입되었는지 파악할 수 있고 해당 고객들에게 맞춤형 혜택을 줄 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;&lt;br /&gt;&lt;/h1&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1&gt;샘플 만들기&lt;/h1&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Dynamic Link를 활용한 샘플코드를 만들어 보겠습니다.&lt;/p&gt;&lt;p&gt;이 샘플에서는 추천코드를 생성하고, 이를 공유해서 해당 url을 눌렀을때 생성된 추천코드를 인식해서 다이어로그로 띄워주는 기능을 만들것입니다.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 708px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9934C63D5B0D483D03&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9934C63D5B0D483D03&quot; width=&quot;708&quot; height=&quot;450&quot; filename=&quot;Screenshot at 5월 29 21-31-46.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;바로 코드를 확인하고 돌려보고 싶으신분은 아래 Github주소에서 직접 실행해보시기 바랍니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedDynamicLinkSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedDynamicLinkSample&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;Dynamic Link 만들기&lt;/h1&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;Deep Link 생성&lt;/h2&gt;&lt;p&gt;먼저 사용자가 앱을 실행했을때 실행시켜줄 딥링크를 정의해줍니다.&lt;/p&gt;&lt;p&gt;이 샘플에서는 아래와 같은 방식으로 딥링크를 만들어서 설정해 주었습니다.&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: Menlo; font-size: 9pt;&quot;&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;private &lt;/span&gt;Uri &lt;span style=&quot;color: rgb(255, 198, 109);&quot;&gt;getPromotionDeepLink&lt;/span&gt;() {&lt;br /&gt;    &lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;// Generate promotion code&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;    &lt;/span&gt;String promotionCode = &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;DF3DY1&quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;// https://ted.com/promotion?code=DF3DY1&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;return &lt;/span&gt;Uri.&lt;span style=&quot;font-style: italic;&quot;&gt;parse&lt;/span&gt;(&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;https://ted.com/&quot; &lt;/span&gt;+ &lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic;&quot;&gt;SEGMENT_PROMOTION &lt;/span&gt;+ &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;?&quot; &lt;/span&gt;+ &lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic;&quot;&gt;KEY_CODE &lt;/span&gt;+ &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;=&quot; &lt;/span&gt;+ promotionCode)&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2&gt;Dynamic Link 생성&lt;/h2&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onDynamicLinkClick&lt;/span&gt;() {&lt;br /&gt;    FirebaseDynamicLinks.&lt;span style=&quot;font-style:italic;&quot;&gt;getInstance&lt;/span&gt;().createDynamicLink()&lt;br /&gt;            .setLink(getPromotionDeepLink())&lt;br /&gt;            .setDynamicLinkDomain(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;n3a95.app.goo.gl&quot;&lt;/span&gt;)&lt;br /&gt;            .setAndroidParameters(&lt;br /&gt;                    &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;DynamicLink.AndroidParameters.Builder(getPackageName())&lt;br /&gt;                            .setMinimumVersion(&lt;span style=&quot;color:#6897bb;&quot;&gt;125&lt;/span&gt;)&lt;br /&gt;                            .build())&lt;br /&gt;            .setGoogleAnalyticsParameters(&lt;br /&gt;                    &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;DynamicLink.GoogleAnalyticsParameters.Builder()&lt;br /&gt;                            .setSource(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;orkut&quot;&lt;/span&gt;)&lt;br /&gt;                            .setMedium(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;social&quot;&lt;/span&gt;)&lt;br /&gt;                            .setCampaign(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;example-promo&quot;&lt;/span&gt;)&lt;br /&gt;                            .build())&lt;br /&gt;            .buildShortDynamicLink()&lt;br /&gt;            .addOnCompleteListener(&lt;span style=&quot;color:#cc7832;&quot;&gt;this, new &lt;/span&gt;OnCompleteListener&amp;lt;ShortDynamicLink&amp;gt;() {&lt;br /&gt;                &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onComplete&lt;/span&gt;(&lt;span style=&quot;color:#bbb529;&quot;&gt;@NonNull &lt;/span&gt;Task&amp;lt;ShortDynamicLink&amp;gt; task) {&lt;br /&gt;                    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(task.isSuccessful()) {&lt;br /&gt;                        Uri shortLink = task.getResult().getShortLink()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                        try &lt;/span&gt;{&lt;br /&gt;                            Intent sendIntent = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Intent()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                            &lt;/span&gt;sendIntent.setAction(Intent.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ACTION_SEND&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                            &lt;/span&gt;sendIntent.putExtra(Intent.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTRA_TEXT&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;shortLink.toString())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                            &lt;/span&gt;sendIntent.setType(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;text/plain&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                            &lt;/span&gt;startActivity(Intent.&lt;span style=&quot;font-style:italic;&quot;&gt;createChooser&lt;/span&gt;(sendIntent&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;Share&quot;&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                        &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;catch &lt;/span&gt;(ActivityNotFoundException ignored) {&lt;br /&gt;                        }&lt;br /&gt;                    } &lt;span style=&quot;color:#cc7832;&quot;&gt;else &lt;/span&gt;{&lt;br /&gt;                        Log.&lt;span style=&quot;font-style:italic;&quot;&gt;w&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TAG&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;task.toString())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;}&lt;br /&gt;                }&lt;br /&gt;            })&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;- setLink(): 위에서 만들어준 Depp Link를 세팅해줍니다.&lt;/p&gt;&lt;p&gt;- setDynamicLinkDomain(): 각 Firebase 프로젝트마다 가진 고유값개념입니다. 콘솔에서 확인할 수 있습니다.&lt;/p&gt;&lt;p&gt;- setAndroidParameters(): 안드로이드앱에 대한 설정을 넣어줄수 있습니다. 여기서는 125 버전아래의 앱을 사용중이라면 앱이 설치되어 있어도 앱을 실행시키지 않고 설치페이지로 보내도록 설정되어 있습니다.&lt;/p&gt;&lt;p&gt;- setGoogleAnalyticsParameters(): 마케터, 기획자들이 주로 사용하는 utm_source, utm_xxx 등의 정보들을 설정해줄 수 있습니다.&lt;/p&gt;&lt;p&gt;- buildShortDynamicLink(): 이 함수를 사용해서 긴 url이 아닌 단축url을 생성할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;링크 생성과 관련된 좀더 상세한 내용은 아래 문서에서 확인하시면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://firebase.google.com/docs/dynamic-links/android/create?hl=ko&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://firebase.google.com/docs/dynamic-links/android/create&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;Dynamic Link 처리하기&lt;/h1&gt;&lt;h2&gt;Manifest 설정&lt;/h2&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;activity &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;.MainActivity&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;intent-filter&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;action &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.intent.action.MAIN&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;category &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.intent.category.LAUNCHER&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;/intent-filter&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;intent-filter&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;action &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.intent.action.VIEW&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;category &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.intent.category.DEFAULT&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;category &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.intent.category.BROWSABLE&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;data&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:host=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;ted.com&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:scheme=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;http&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;data&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:host=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;ted.com&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:scheme=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;https&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;/intent-filter&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/activity&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Manifest에서 위에서 만든 딥링크를 처리해줄 수 있도록 scheme/host를 정의해줍니다.&lt;/p&gt;&lt;p&gt;여기서는 https://ted.com, http://ted.com 으로 실행되는 url에 대해서 MainActivity가 잡아서 실행되도록 정의되어 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;Deep Link 처리&lt;/h2&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;handleDeepLink&lt;/span&gt;() {&lt;br /&gt;    FirebaseDynamicLinks.&lt;span style=&quot;font-style:italic;&quot;&gt;getInstance&lt;/span&gt;()&lt;br /&gt;            .getDynamicLink(getIntent())&lt;br /&gt;            .addOnSuccessListener(&lt;span style=&quot;color:#cc7832;&quot;&gt;this, new &lt;/span&gt;OnSuccessListener&amp;lt;PendingDynamicLinkData&amp;gt;() {&lt;br /&gt;                &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onSuccess&lt;/span&gt;(PendingDynamicLinkData pendingDynamicLinkData) {&lt;br /&gt;                    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(pendingDynamicLinkData == &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;                        Log.&lt;span style=&quot;font-style:italic;&quot;&gt;d&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TAG&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;No have dynamic link&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                        return;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;}&lt;br /&gt;                    Uri deepLink = pendingDynamicLinkData.getLink()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;Log.&lt;span style=&quot;font-style:italic;&quot;&gt;d&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TAG&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;deepLink: &quot; &lt;/span&gt;+ deepLink)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;String segment = deepLink.getLastPathSegment()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    switch &lt;/span&gt;(segment) {&lt;br /&gt;                        &lt;span style=&quot;color:#cc7832;&quot;&gt;case &lt;/span&gt;&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;SEGMENT_PROMOTION&lt;/span&gt;:&lt;br /&gt;                            String code = deepLink.getQueryParameter(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;KEY_CODE&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                            &lt;/span&gt;showPromotionDialog(code)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                            break;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;}&lt;br /&gt;                }&lt;br /&gt;            })&lt;br /&gt;            .addOnFailureListener(&lt;span style=&quot;color:#cc7832;&quot;&gt;this, new &lt;/span&gt;OnFailureListener() {&lt;br /&gt;                &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onFailure&lt;/span&gt;(&lt;span style=&quot;color:#bbb529;&quot;&gt;@NonNull &lt;/span&gt;Exception e) {&lt;br /&gt;                    Log.&lt;span style=&quot;font-style:italic;&quot;&gt;w&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TAG&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;getDynamicLink:onFailure&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;e)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;}&lt;br /&gt;            })&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;- getDynamicLink(): Intent로부터 deep link가 존재하는지 알아옵니다.&lt;/p&gt;&lt;p&gt;만약 처리해야하는 deep link가 존재한다면&amp;nbsp;PendingDynamicLinkData 값이 null이 아니라 존재할것입니다.&lt;/p&gt;&lt;p&gt;PendingDynamicLinkData로부터 deep link를 가져와서 각 유형에 맞게 처리를 해줍니다.&lt;/p&gt;&lt;p&gt;여기에서는&amp;nbsp;https://ted.com/promotion?code=DF3DY1 라는 패턴의 유형을 찾아서 그에 해당하는 프로모션 코드를 추출하고 다이어로그로 해당 코드를 띄워주고 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 코드는 아래 Github에서 확인해보실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedDynamicLinkSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedDynamicLinkSample&lt;/a&gt;&lt;/p&gt;&lt;p&gt;이 샘플코드가 유용하셨다면 Github에서 Star를 눌러주세요&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;h1&gt;&lt;br /&gt;&lt;/h1&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1&gt;디버깅&lt;/h1&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Dynamic Link가 의도한대로 잘 동작하도록 만들어져있는지 확인해볼 수 있습니다.&lt;/p&gt;&lt;p&gt;Dynamic Link의 맨 뒤에 ?d=1 을 붙여주기만하면 아래와 같은 경우의 수에 따른 플로우차트를 확인 할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://n3a95.app.goo.gl/iE7WLQnL5mjsuJ7F2?d=1&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://n3a95.app.goo.gl/iE7WLQnL5mjsuJ7F2?d=1&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 764px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9984DC435B0D4CCB25&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9984DC435B0D4CCB25&quot; width=&quot;764&quot; height=&quot;691&quot; filename=&quot;Screenshot at 5월 29 21-51-09.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Firebase Dynamic Link로 효율적으로&amp;nbsp;사용자를 유입시키고 성공적인 앱서비스를 하시기 바랍니다.&lt;/p&gt;&lt;p&gt;더이상 기획자, 마케터로부터 이런 형태의 url을 만들어 달라는 말도 듣지 않으셨으면 좋겠습니다.&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 포스팅과 같은 내용의 동영상 강의를 확인하시려면 아래 영상을 시청해주세요&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://goo.gl/dbPCaA&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://goo.gl/dbPCaA&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/78</guid>
      <comments>https://gun0912.tistory.com/78#entry78comment</comments>
      <pubDate>Tue, 29 May 2018 22:09:56 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]8.0 오레오 알림채널(Notification Channel) 대응하기</title>
      <link>https://gun0912.tistory.com/77</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 400px; width: 400px; height: 225px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/993D2D495A76E41A1E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F993D2D495A76E41A1E&quot; width=&quot;400&quot; height=&quot;225&quot; filename=&quot;AndroidPIT-android-O-Oreo-2059.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 400px; height: 225px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지난 2017년 8월, 구글은 안드로이드 8.0 오레오를 공개했습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://developer.android.com/about/versions/oreo/android-8.0-changes.html?hl=ko&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;여러가지 동작 변경사항&lt;/a&gt; 중 우리는&amp;nbsp;알림(Notification)에 대한 변경사항에 대해 꼭&amp;nbsp;대응을 해주어야 합니다.&lt;/p&gt;&lt;p&gt;우리는 지난 마시멜로우 6.0에서 권한을 대응하면서 느꼈듯이 OS의 업데이트때마다 무엇을 대응해주어야 하는지 눈여겨 보아야 합니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/55&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드/Android]6.0 마시멜로우 권한체크하고 최적화하기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2018년 1월 기준으로 오레오이상 기기의 점유율은 0.7% 밖에 되지 않습니다.&lt;a href=&quot;https://developer.android.com/about/dashboards/index.html?hl=ko&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;(안드로이드 OS점유율)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;현재는 구글의 레퍼런스폰인 넥서스기기에서만 8.0 오레오를 사용할 수 있지만 곧 삼성,LG의 제조사에서도 업데이트를 지원할것이기 때문에 우리는 대응을 해주어야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;TL;DR(Too long; didn't read)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;이 포스팅을 다 읽으실 시간이 없으시거나&amp;nbsp;&lt;strike&gt;귀찮으신분&lt;/strike&gt;들은 아래 샘플을 다운받아보시고 바로 테스트해보실 수 있습니다.&lt;br /&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/NotificationChannelSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/NotificationChannelSample&lt;/a&gt;&lt;/p&gt;&lt;p&gt;(여러분의 Github의 Star 눌러주시는 센스도 기대합니다!)&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-3&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line06.gif?v=2) repeat-x scroll left; height: 15px; border:0&quot;&gt;&lt;p&gt;&lt;b style=&quot;font-size: 24pt;&quot;&gt;알림채널(Notification Channel)&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99F931465A76EB3313&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99F931465A76EB3313&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_1517742885.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;앱에서 알림(Notification)은 채팅, 새게시글, 댓글, 공지사항등의 다양한 용도로 쓰입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;저는 페이스북 운영자입니다.&lt;strike&gt;(사실 아닙니다)&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;페이스북에서는 사용자에게 여러가지 알림을 보냅니다.&lt;/p&gt;&lt;p&gt;채팅, 친구의 새 게시글 알림, 사용자의 게시글에 대한 댓글, 사용자가 참여한 게시글에 대한 댓글, 친구추천, 기타 공지사항등&lt;/p&gt;&lt;p&gt;하지만 알림의 종류가 많아서 그만큼 알림이 많이 가기때문에 페이스북 사용자들은 불만이 많았습니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;별로 중요하지 않은 알림은 소리나 진동없이 왔으면 좋겠고 중요하다고 생각하는 알림은 잠금화면에서도 알려주기를 바랬습니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이럴때 유용한게 알림채널(Notification Channel)입니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Notification Channel을 통해 Notification을 여러가지 용도로 나누어서 관리할 수 있게 만들어 줍니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/993A784A5A76EA5533&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F993A784A5A76EA5533&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_1517742567.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그리고 사용자가 직접&amp;nbsp;각 채널별로 알림중요도나 기타 설정을 변경할 수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99ECDE435A76EAAE3E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99ECDE435A76EAAE3E&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_1517742745.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;오레오에서부터는 이 Notification Channel을 필수로 만들어 주어야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 18pt;&quot;&gt;오레오에서 &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 18pt;&quot;&gt;Notification Channel&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 18pt;&quot;&gt;을 만들어 주지 않으면 알림이 오지 않습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;아직 오레오에 대응할 마음의 준비가 안되셨나요?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 350px; width: 350px; height: 147px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/993670445A76EA3128&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F993670445A76EA3128&quot; width=&quot;350&quot; height=&quot;147&quot; filename=&quot;not_ready.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 350px; height: 147px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금 오레오폰에서 플레이스토어에 있는 내앱을 설치하면 알림이 안올까요?&lt;/p&gt;&lt;p&gt;그렇지 않습니다.&lt;/p&gt;&lt;p&gt;안드로이드에서 targetSdkVersion이 26버전보다 아래라면 문제없이&amp;nbsp;알림이 옵니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;아직 마음의 준비가 안되셨거나 &lt;/span&gt;&lt;strike&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;귀찮다면&lt;/span&gt;&lt;/strike&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt; targetSdkVersion을 25로 두고 개발하세요.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;이미 26으로 올리셨다면 25로 내릴 수 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;안될것 같다구요? 됩니다! 제가 해봤거든요!&lt;/p&gt;&lt;p&gt;당연히 내리는게 안된다고 생각하고있었는데 가능한 작업이었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;알림채널(Notification Channel) 만들기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Notification Channel을 만드는 방법은 간단합니다.&lt;/p&gt;&lt;p&gt;해당 기기의 OS버전이 오레오이상일때 Notification Channel을 만들어주고 필요한 설정을 해준뒤 NotificationManager의 createNotificationChannel()을 호출해주면 됩니다.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/3fd55511de2b9f192ed58a227b08507e.js?file=NotificationChannelCreate.java&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(36, 41, 46); font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 12px; white-space: pre;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(36, 41, 46); font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 12px; white-space: pre;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Notification Channel의 다른 함수에 대해서는 아래에서 자세하게 살펴보실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://developer.android.com/reference/android/app/NotificationChannel.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://developer.android.com/reference/android/app/NotificationChannel.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;채널은 한번만 만들면 되기때문에 Notification이 올때마다 만들어줄 필요가 없습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Application Class에서 만들어 줘&amp;nbsp;되고 SharedPreference를 이용해서 한번 만든적이 있다면 그다음부터는 만들지 않도록 해주어도 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;알림(Notification)에 채널 지정하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;알림에 채널을 지정하는 방법은 간단합니다.&lt;/p&gt;&lt;p&gt;기존에 Notificatioin Builder에서 하던 작업에 어느채널에 포함시킬지 채널ID만 함께 추가해주면 됩니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;background-color:#344134;&quot;&gt;Notification&lt;/span&gt;.Builder builder = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;&lt;span style=&quot;background-color:#344134;&quot;&gt;Notification&lt;/span&gt;.Builder(context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;channel)&lt;br /&gt;        .setContentTitle(title)&lt;br /&gt;        .setContentText(body)&lt;br /&gt;        .setSmallIcon(&lt;span style=&quot;font-style:italic;&quot;&gt;getSmallIcon&lt;/span&gt;())&lt;br /&gt;        .setAutoCancel(&lt;span style=&quot;color:#cc7832;&quot;&gt;true&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;생성자에서 채널ID를 넣어줄수도 있고 .setChannel() 함수를 이용해서 채널ID를 지정해줄 수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b style=&quot;font-size: 32px;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b style=&quot;font-size: 32px;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b style=&quot;font-size: 32px;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b style=&quot;font-size: 32px;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b style=&quot;font-size: 32px;&quot;&gt;알림채널(Notification Channel) 관리&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;알림채널(Notification Channel)을 만들고나서 수정, 삭제가 가능합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;NotificationManager의 getNotificationChannel(), createNotificationChannel()을 활용해서 해당 채널ID에 대해서 수정해주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;수정은 채널이름, 채널설명에 대해서만 가능합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;알림 중요도나 진동패턴, 소리, 불빛 등에 대해서는 변경해줄 수 없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;삭제는 채널ID를 넘겨주면 삭제할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;그렇기때문에 수정으로 불가능한것들을 변경해주고 싶은경우 채널을 삭제하고 원하는 설정으로 새로 만들어 주면 됩니다.&lt;/p&gt;&lt;p&gt;하지만 삭제후 재생성을 남용하면 안됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래의 스크린샷처럼 특정 채널이 삭제됐음을 사용자가 알수 있음은 물론이고 만약 사용자가 해당 채널의 설정을 변경해서 자신이 원하는대로 쓰고 있었다면 그런 설정들은 모두 날아가고 새로운 설정으로 다시 만들어져버려서 사용자가 화가날수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99B67E3C5A78442C03&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99B67E3C5A78442C03&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_1517830850.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;알림채널 그룹(Notification Channel Group)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;알림채널뿐만 아니라 알림채널 그룹이라는 개념도 추가되었습니다.&lt;/p&gt;&lt;p&gt;트위터처럼 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;여러 계정을 로그인하게 해주는 앱이거나 개인용도/업무용도로 앱을 나누어서 사용할 수 있는경우 Notification Channel Group을 활용&lt;/span&gt;하면 좋습니다.&lt;/p&gt;&lt;p&gt;그룹ID와 이름을 지정해서&amp;nbsp;NotificationChannelGroup을 만들어주고 NotificationManager의&amp;nbsp;createNotificationChannelGroup()를 호출해주면 됩니다.&lt;/p&gt;&lt;p&gt;또한 채널을 만들때&amp;nbsp;setGroup()으로 해당 채널을 어느 그룹에 포함시킬지 지정해주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/3fd55511de2b9f192ed58a227b08507e.js?file=NotificationChannelGroup.java&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;트위터의 경우, 사용자의 계정이름을 Notification Channel Group 이름으로 사용하여 각 사용자별로 알림을 지정할 수 있도록 지원합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99A3843D5A76F19C24&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99A3843D5A76F19C24&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_1517660124.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;기타: 삽질하면서 알게된것들&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;알림채널을 대응하기위해서 여러가지 앱들을 설치해서 테스트 해보던중에 특이한것을 발견하였습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99A9263D5A78404D25&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99A9263D5A78404D25&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_1517830053.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9909873F5A78403501&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9909873F5A78403501&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_1517830188.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;채널처럼 생겼지만 다른채널과는 다른 &lt;b&gt;'Uncategorized'&lt;/b&gt; 라는걸 발견하게 되었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;심지어 알림에대해서 설정할수도 없으며 'Let the app decide'라고 다른 채널의 설정과는 다르게 쓰여져 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;뭔가 채널이 지정되지 않은 알림은 이 채널에 속할것 같은 느낌적인 느낌이 있었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 어떻게 저걸 만들어 내는지 알지 못했습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;공식 문서를 뒤져봐도 관련된 언급이 없었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그러던중 재현하는 방법을 알게되었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;이러한 현상은 라이브러리를 사용하고 있을때 앱의 targetSdkVersion은 25이하이지만, 라이브러리의 targetSdkVersion이 26이상인경우에서 발생합니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;물론 위와같은 상황에서도 채널을 1개도 만들지 않는다면 상관없지만 채널을 1개라도 만들경우&amp;nbsp;&lt;b&gt;'Uncategorized' &lt;/b&gt;가 생성됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Notification을 만들때 channel id를 지정하지 않으면 이 Notification은&amp;nbsp;&lt;b&gt;'Uncategorized'&lt;/b&gt;에 속하는것을 확인했습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-3&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line06.gif?v=2) repeat-x scroll left; height: 15px; border:0&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금까지 구현사항에 대해서 샘플을 만들어두었으니 아직 감이 안오시는분들은 참고하시기 바랍니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/NotificationChannelSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/NotificationChannelSample&lt;/a&gt;&lt;/p&gt;&lt;p&gt;(여러분의 Github의 Star 눌러주시는 센스!)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 공식페이지에서도 Notification Channel에 대해서 확인해보실 수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://developer.android.com/guide/topics/ui/notifiers/notifications.html#ManageChannels&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://developer.android.com/guide/topics/ui/notifiers/notifications.html#ManageChannels&lt;/a&gt;&lt;/p&gt;&lt;p&gt;(한국어로 설정하시면 보이지 않습니다. 언어를 영어로 선택하셔야 보여집니다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금까지 안드로이드 8.0 오레오에서 추가된 알림채널(Notification Channel)에 대해 포스팅 해보았습니다.&lt;/p&gt;&lt;p&gt;어때요 참 쉽죠?&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 150px; width: 150px; height: 149px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/992BDE365A76F55B0D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F992BDE365A76F55B0D&quot; width=&quot;150&quot; height=&quot;149&quot; filename=&quot;agree.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 150px; height: 149px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;알림채널(Notification Channel)에 대해서 이해하고 나서&amp;nbsp;유용한 알림관리 방식이라는걸 느끼게 되었습니다.&lt;/p&gt;&lt;p&gt;잘 알려진 여러 앱들을 다운받아봐서 확인했을대 아직 알림채널에 대해서 대응한 앱은 많이 보이지 않았습니다.&lt;/p&gt;&lt;p&gt;하지만 마시멜로우 권한대응때처럼 점점 이 기능에 대한 대응이 필요하게 될것입니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;여러분 모두 오레오 기기의 점유율이 늘어나기전에 새로운 &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;변화에 대응해서 좋은 앱서비스 품질을 유지하셨으면 좋겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 개발자끼리 소통하기위한 오픈채팅방을 만들었습니다.&lt;/p&gt;&lt;p&gt;안드로이드 관련 Q&amp;amp;A및 팁을 공유하는 곳입니다.&lt;/p&gt;&lt;p&gt;관심있으신분들은 참여해보세요.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://open.kakao.com/o/g8rSGB&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://open.kakao.com/o/g8rSGB&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/77</guid>
      <comments>https://gun0912.tistory.com/77#entry77comment</comments>
      <pubDate>Sun, 4 Feb 2018 21:12:18 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]빌드시간 최적화하기(빌드시간 70%감소)</title>
      <link>https://gun0912.tistory.com/76</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 200px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/998F693359CBB60F1A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F998F693359CBB60F1A&quot; width=&quot;200&quot; height=&quot;200&quot; filename=&quot;build time.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 200px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;안드로이드 개발을 마치고 에뮬레이터나 실제 기기에서 테스트해보려면 우리는 빌드를 하고 설치해야만 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이때 빌드시간이 어떤상황이냐에 따라서 몇십분이 될수도 있고 단 몇십초가 될 수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Eclipse에서 Android Studio로 넘어오신분들은 아시겠지만 제일 처음에 넘어왔을때 불만이 빌드속도가 너무 느리다는것이었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그래서 빌드속도를 빠르게 하기위하여 'android studio speed up', 'android build time' 등으로 각종 팁을 찾아보고 적용해 보았습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;daemon을 활성화하거나 병렬로 실행하거나 기타 등등의 여러 방법이 있었지만 실제로는 빌드시간이&amp;nbsp;감소하는 효과를 보지 못했습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 아래 소개할 &lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;이 방법은 확실하게 빌드시간을&amp;nbsp;줄일 수 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;저는 70%의 빌드시간&amp;nbsp;감소를 경험했습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;안드로이드 빌드시간이 감소하면 안좋을 수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;빌드를 기다리는 시간동안 개발자들은 밀린 카카오톡 메세지를 확인하거나 화장실을 가거나 볼일을 보곤 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그런데 빌드시간이 줄어들면 이런 시간이 줄어들어서 줄인시간만큼 우린 더 많이 일해야할지도 모릅니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;strike&gt;이 글을 대표님은 좋아하지만 직원들은 싫어합니다.&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;제가 적용한 방법은 Google I/O 17에서 소개된 내용을 참고해서 적용했습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=7ll-rkLCtyk&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://www.youtube.com/watch?v=7ll-rkLCtyk&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그 세션에서 소개한 모든 방법을 적용하지는 않았고 제게 맞는 방법으로 맞추어서 적용했습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;각 항목별로 빌드시간을 줄이는법에 대해 알아보겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;바쁘신분(&lt;strike&gt;읽기 귀찮으신분&lt;/strike&gt;)들은 Sample 프로젝트를 다운받아서 확인해보셔도 좋습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/BuildTimeSpeedUpSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/BuildTimeSpeedUpSample&lt;/a&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1&gt;&lt;br /&gt;&lt;/h1&gt;&lt;h1&gt;1.&amp;nbsp;Avoid legacy multidex&lt;/h1&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;65,536개 이상의 함수를 사용하게되면 우리는 &lt;a href=&quot;https://developer.android.com/studio/build/multidex.html?hl=ko&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Multidex&lt;/a&gt;를 사용합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;예전에는 Multidex가 생소했지만 요즘에는 라이브러리들을 많이 사용하면서 65,536개 이상은 훌쩍 넘기게되고 Multidex를 자주 사용합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;여기서 Android 5.0(API 레벨 21)이상이냐 미만이냐에 따라서 Multidex를 다루는 방법이 달라집니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Android 5.0(API 레벨 21) 미만의 플랫폼 버전에서는 앱 코드 실행을 위해 Dalvik 런타임을 사용합니다. 기본적으로, Dalvik에서는 APK당 하나의 classes.dex 바이트코드 파일로 앱을 제한합니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Android 5.0(API 레벨 21) 이상에서는 ART라는 런타임을 사용합니다. 기본적으로 이 런타임은 APK 파일로부터 여러 개의 DEX 파일을 로드하는 것을 지원합니다.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;즉, Android 5.0(API 레벨 21) 이상에서는 Multidex가 훨씬 빠릅니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그래서&amp;nbsp;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;minSdkVersion를 21로 설정해주면 아주 빠른 빌드속도를 경험할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 대부분 minSdkVersion를 14나 16으로 설정해주기때문에 함부로 minSdkVersion을 21로 설정할 수 없습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그럴때 Flavor를 활용해줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://gun0912.tistory.com/74&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드]Flavors로 같은 소스코드 다른앱 만들기&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;dev/prd로 Flavor를 나누어서 개발할때만 minSdkVersion를 21로 설정하고 배포할때는 원래의 minSdkVersion를 적용하도록 설정해주면 됩니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;dev {&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;dimension &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;stage&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;minSdkVersion &lt;span style=&quot;color:#6897bb;&quot;&gt;21&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;prd {&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;dimension &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;stage&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;versionCode &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Date().format(&lt;span style=&quot;color:#6a8759;&quot;&gt;'yyMMddHHmm'&lt;/span&gt;).toInteger()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;free {&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;dimension &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;mode&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;applicationIdSuffix &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;.free&quot;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;paid {&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;dimension &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;mode&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;applicationIdSuffix &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;.paid&quot;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;여기서는 기존에 flavor로 무료앱과 유료앱을 나누어서 운영하고 있다가 dev/prd를 추가한 예시입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;dimension을 stage/mode로 나누면 각각 dev/prd - free/paid 중에 선택되서 결정되게 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;여기에 원래의 debug/release까지 있으니 build할수있는 variant는 아래와 같습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;devFreeDebug&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;devFreeRelease&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;devPaidDebug&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;devPaidRelease&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;prdFreeDebug&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;prdFreeRelease&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;prdPaidDebug&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;prdPaidRelease&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;실제 개발할때는 devFreeDebug, devPaidDebug를 사용할 것이고 스토어에 올릴때는 prdFreeRelease, prdPaidRelease를 사용할 것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;사실상 나머지 다른 build variant들은 만들어졌지만 쓸모없는것들입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그럴때 ignore를 사용해주면 좋습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;android.variantFilter { variant -&amp;gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;buildName = variant.buildType.name;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;flavorName = variant.getFlavors().get(&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;).name;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(flavorName == &lt;span style=&quot;color:#6a8759;&quot;&gt;'dev' &lt;/span&gt;&amp;amp;&amp;amp; buildName == &lt;span style=&quot;color:#6a8759;&quot;&gt;'release'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;|| flavorName == &lt;span style=&quot;color:#6a8759;&quot;&gt;'prd' &lt;/span&gt;&amp;amp;&amp;amp; buildName == &lt;span style=&quot;color:#6a8759;&quot;&gt;'debug'&lt;/span&gt;) {&lt;br /&gt;        variant.setIgnore(&lt;span style=&quot;color:#cc7832;&quot;&gt;true&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;사용하지 않을것 같은 variant들은 없애주면 실제로 사용하게될 4개의 variant들만 남습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 313px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9995ED3359CBBC7F10&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9995ED3359CBBC7F10&quot; width=&quot;313&quot; height=&quot;200&quot; filename=&quot;KakaoTalk_2017-09-21-23-49-37_Photo_36.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Google I/O 발표내용에 따르면이 방법을 적용하면 아래와 같은 빌드시간 감소를 줄일 수 있다고 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99B3443359CBBCC32D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99B3443359CBBCC32D&quot; width=&quot;820&quot; height=&quot;461&quot; filename=&quot;Speeding Up Your Android Gradle Builds (Google I_O '17).mp4 - 00.07.30.049.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;2. Disable multi-APK&lt;/h1&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;APK파일의 크기가 클때 abi별/density별로 APK파일을 나누어서 용량을 줄일 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://developer.android.com/studio/build/configure-apk-splits.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://developer.android.com/studio/build/configure-apk-splits.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;실제로 많은 서비스에서 x86용, x86_64용, armeabi-v7a용, arm64-v8a용으로 APK를 분할해서 제공하고 있습니다.&lt;/p&gt;&lt;p&gt;아래와 같은 방식으로 split을 할 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;splits {&lt;br /&gt;    abi {&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;enable &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;true&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;reset()&lt;br /&gt;        include &lt;span style=&quot;color:#6a8759;&quot;&gt;'x86'&lt;/span&gt;, &lt;span style=&quot;color:#6a8759;&quot;&gt;'x86_64'&lt;/span&gt;, &lt;span style=&quot;color:#6a8759;&quot;&gt;'armeabi-v7a'&lt;/span&gt;, &lt;span style=&quot;color:#6a8759;&quot;&gt;'arm64-v8a'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;universalApk &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;false&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;그런데 이런 split작업은 빌드시간을 증가시키는 원인이 됩니다.&lt;/p&gt;&lt;p&gt;그러므로 우리는 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;개발단계에서는 abi별로 split하는 작업을 하지 않게 만들어주어야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;1번의 방법에서 우리는 dev/prd&amp;nbsp;flavor를 만들었습니다.&lt;/p&gt;&lt;p&gt;그러므로 prd일때만 split해주도록 설정하면 개발에서는 split하지않고 배포할때만 split하도록 설정할 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;android.variantFilter { variant -&amp;gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;flavorName = variant.getFlavors().get(&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;).name;&lt;br /&gt;    splits.abi.enable = (flavorName == &lt;span style=&quot;color:#6a8759;&quot;&gt;'prd'&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99CB603359CBBE0C11&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99CB603359CBBE0C11&quot; width=&quot;820&quot; height=&quot;461&quot; filename=&quot;Speeding Up Your Android Gradle Builds (Google I_O '17).mp4 - 00.09.35.241.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;3. Minimize included resources / Disable PNG Crunching&lt;/h1&gt;&lt;p&gt;개발을 하면서 우리는 보통 1개의 테스트폰만을 사용합니다.&lt;/p&gt;&lt;p&gt;한국어이면서 xxxhdpi이거나 특정 해상도인 테스트폰을 사용할것입니다.&lt;/p&gt;&lt;p&gt;그럴때 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;resource를 특정 언어와 해상도로 고정해두면 빌드시간을 줄일 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또한 안드로이드에서 기본으로 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;PNG를 최적화하는 기능을 끄면 빌드시간을 줄일 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;dev flavor에서 아래와 같이 선언해주면 간단히 적용할 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;dev {&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;dimension &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;stage&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;minSdkVersion &lt;span style=&quot;color:#6897bb;&quot;&gt;21&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;    &lt;/span&gt;aaptOptions.cruncherEnabled = &lt;span style=&quot;color:#cc7832;&quot;&gt;false&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;resConfigs &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;ko&quot;&lt;/span&gt;, &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;xxxhdpi&quot;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9960C03359CBBF1213&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9960C03359CBBF1213&quot; width=&quot;820&quot; height=&quot;461&quot; filename=&quot;Speeding Up Your Android Gradle Builds (Google I_O '17).mp4 - 00.10.37.169.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/995E113359CBBF2032&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F995E113359CBBF2032&quot; width=&quot;820&quot; height=&quot;461&quot; filename=&quot;Speeding Up Your Android Gradle Builds (Google I_O '17).mp4 - 00.12.35.421.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;4.&amp;nbsp;Avoid inadvertent changes&lt;/h1&gt;&lt;p&gt;앱을 개발하면서 불필요하게 증가시키는 요소들을 줄일 수 있습니다.&lt;/p&gt;&lt;p&gt;앱의 versionCode를 빌드시간으로 정의해서 사용하는 경우도 많이 볼 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;buildDateTime = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Date().format(&lt;span style=&quot;color:#6a8759;&quot;&gt;'yyMMddHHmm'&lt;/span&gt;).toInteger()&lt;br /&gt;android {&lt;br /&gt;    defaultConfig {&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;versionCode &lt;/span&gt;buildDateTime&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;하지만 계속 새로 갱신이 되면서 Manifest가 변경되고 이는 빌드시간을 증가시키는 원인이 됩니다.&lt;/p&gt;&lt;p&gt;이러한 방법도 빌드시간을 줄일 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;개발할때&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;는 versionCode를 특정값으로 fix하고 release할때만 실제로 적용시키면 됩니다.&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;dev {&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;dimension &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;stage&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;versionCode &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;100&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;prd {&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;dimension &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;stage&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;versionCode &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Date().format(&lt;span style=&quot;color:#6a8759;&quot;&gt;'yyMMddHHmm'&lt;/span&gt;).toInteger()&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9934F53359CBC01F05&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9934F53359CBC01F05&quot; width=&quot;820&quot; height=&quot;461&quot; filename=&quot;Speeding Up Your Android Gradle Builds (Google I_O '17).mp4 - 00.16.37.796.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;5. Fabric&lt;/h1&gt;&lt;p&gt;요즘에는 Fabric을 활용하여 사용자분석이나 오류로그를 분석하는 경우가 많습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/53&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드]오류 리포팅 서비스 비교(Google Analytics, URQA, Userhabit, Fabric)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;개발단계에서는 fabric이 사실 필요 없습니다.&lt;/p&gt;&lt;p&gt;그럴때 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;fabric을 사용하지 않는것만으로도 빌드시간을&amp;nbsp;줄일 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;buildTypes {&lt;br /&gt;&lt;br /&gt;    debug {&lt;/p&gt;&lt;p&gt;        ...&lt;br /&gt;        ext.enableCrashlytics = &lt;span style=&quot;color:#cc7832;&quot;&gt;false&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;혹은 개발에서도 Fabric을 사용해야하는경우는 Build id를 update해주는 기능을 꺼주어도 됩니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;buildTypes {&lt;br /&gt;&lt;br /&gt;    debug {&lt;br /&gt;        ext.alwaysUpdateBuildId = &lt;span style=&quot;color:#cc7832;&quot;&gt;false&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;&lt;br /&gt;&lt;/h1&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1&gt;6. 라이브러리 버전&lt;/h1&gt;&lt;p&gt;라이브러리를 사용할때 버전을 끝까지 명시해주는것이 좋습니다.&lt;/p&gt;&lt;p&gt;x.x.+ 로 사용할 경우 24시간마다 최신버전을 알아오기때문에 이는 빌드시간이 늘어나는 원인이 됩니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;dependencies {&lt;br /&gt;    compile &lt;span style=&quot;color:#6a8759;&quot;&gt;'com.android.support:appcompat-v7:26.0.0-alpha1'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;compile 'com.android.support:appcompat-v7:26.+'&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1&gt;결과&lt;/h1&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;실제 프로젝트에 적용했을때 73%의 빌드시간 감소효과를 경험 했습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;측정방법은 Android Studio에서 [Build]-&amp;gt;[Clean Project]후 [Build]-&amp;gt;[Build APK]의 방식으로 수행했습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;table class=&quot;txc-table&quot; width=&quot;784&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-top:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;평균&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-top:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;110초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-top:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;30초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-top:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;72.99% 감소&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;1회&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;112초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;26초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;2회&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;103초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;25초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;3회&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;116초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;33초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;4회&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;110초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;34초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;5회&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;107초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;30초&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:196;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: right;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 빌드시간은 프로젝트의 크기에 따라 다르고 측정하는 PC에 따라 다릅니다.&lt;/p&gt;&lt;p&gt;각자의 프로젝트와 PC환경에서 위와 같은 방법을 적용하기 전/후의 시간을 측정해서 비교해봐야 할것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이미 구현되어있는 Sample프로젝트를 참고하시기 바랍니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/BuildTimeSpeedUpSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/BuildTimeSpeedUpSample&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;style type=&quot;text/css&quot;&gt;
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px NanumBarunGothic}
span.s1 {text-decoration: underline}
&lt;/style&gt;&lt;p&gt;이 Sample프로젝트가 유용하셨다면 오른쪽 상단에 Star버튼도 꾹 눌러주시면 감사하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;어때요?&amp;nbsp;&lt;/p&gt;&lt;p&gt;이제 빌드시간 70%줄이고 아낀시간으로 그만큼 더 불꽃코딩 할 수 있겠죠?&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 144px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99ABDA3359CBC4511F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99ABDA3359CBC4511F&quot; width=&quot;250&quot; height=&quot;144&quot; filename=&quot;work.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 250px; height: 144px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;모두 행복한 코딩하시기 바랍니다.&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;style type=&quot;text/css&quot;&gt;
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px NanumBarunGothic}
span.s1 {text-decoration: underline}
&lt;/style&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/76</guid>
      <comments>https://gun0912.tistory.com/76#entry76comment</comments>
      <pubDate>Thu, 28 Sep 2017 00:35:05 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]유용한 라이브러리 - TedRxOnActivityResult(RxJava를 활용한 startActivityForResult())</title>
      <link>https://gun0912.tistory.com/75</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 200px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99BD5B3359A8A06A01&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99BD5B3359A8A06A01&quot; width=&quot;200&quot; height=&quot;200&quot; filename=&quot;스크린샷 2017-09-01 오전 8.47.51.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 200px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Activity를 실행하고 해당 결과를 가져오거나 결과값을 알고 싶을때 우리는 startActivityForResult()를 사용합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;startActivityForResult()의 결과는 onActivityResult()에서 받아서 처리합니다.&lt;/p&gt;&lt;p&gt;만약 소스코드를 작성한다면 아래와 같이 작성할 수 있을것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;box-sizing: border-box; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; font-stretch: normal; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; color: rgb(36, 41, 46);&quot;&gt; &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;@Override&lt;/span&gt;
  &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;void&lt;/span&gt; onCreate(&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;@Nullable&lt;/span&gt; &lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;Bundle&lt;/span&gt; savedInstanceState) {
    &lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;onCreate(savedInstanceState);
    &lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;...&lt;/span&gt;
    
    startActivityForResult(intent,&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;REQ_CODE_AAA&lt;/span&gt;);
    
  }

  &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;@Override&lt;/span&gt;
  &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;void&lt;/span&gt; onActivityResult(&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;int&lt;/span&gt; requestCode, &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;int&lt;/span&gt; resultCode, &lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;Intent&lt;/span&gt; data) {
    &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;switch&lt;/span&gt; (requestCode){
      &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;REQ_CODE_AAA&lt;/span&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;if&lt;/span&gt;(resultCode&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;RESULT_OK&lt;/span&gt;){
          doSomething();
        }
        &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;break&lt;/span&gt;;
      &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;onActivityResult(requestCode, resultCode, data);    
    }
    
  }
&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;하지만 이 작업은 은근 귀찮은 일입니다.&lt;/p&gt;&lt;p&gt;호출한곳에서 결과값을 받아야 하는데 다른곳에서 처리 하다보면 처리가 누락되는 문제가 생길 수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;특히 RxJava를 사용하고 있는경우 Chaining방식이 아니라 연속성을 해치게됩니다.&lt;/p&gt;&lt;p&gt;RxJava에서는 아래와 같은 방식으로 사용하고 있을겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;box-sizing: border-box; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; font-stretch: normal; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; color: rgb(36, 41, 46);&quot;&gt;  &lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;AA&lt;/span&gt;()
  .filter(&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;...&lt;/span&gt;)
  .subscribeOn(&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;...&lt;/span&gt;)
  .observeOn(&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;...&lt;/span&gt;)
  .subscribe(&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;...&lt;/span&gt;);&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;저는 startActivityForResult()와 결과값을 받아오는 방식도 위와같은 방식으로 사용하고 싶었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그래서 &lt;strike&gt;답답해서&lt;/strike&gt; &lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;제가&amp;nbsp;TedRxOnActivityResult를&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;만들었습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;TedRxOnActivityResult는 Chaining방식으로 startActivityForResult()를 수행하고 결과값을 받아올 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedRxOnActivityResult&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedRxOnActivityResult&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;설정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;현재 사용중인 RxJava의 버전에 따라서 선택할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;RxJava1&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;box-sizing: border-box; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; font-stretch: normal; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; color: rgb(36, 41, 46);&quot;&gt;&lt;p&gt;dependencies {
    compile &lt;span class=&quot;pl-s&quot; style=&quot;box-sizing: border-box; color: rgb(3, 47, 98);&quot;&gt;&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;'&lt;/span&gt;gun0912.ted:tedonactivityresult-rx1:1.0.2&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;RxJava2&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;box-sizing: border-box; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; font-stretch: normal; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; color: rgb(36, 41, 46);&quot;&gt;&lt;p&gt;dependencies {
    compile &lt;span class=&quot;pl-s&quot; style=&quot;box-sizing: border-box; color: rgb(3, 47, 98);&quot;&gt;&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;'&lt;/span&gt;gun0912.ted:tedonactivityresult-rx2:1.0.2&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;Normal&lt;/span&gt;&lt;/p&gt;&lt;p&gt;RxJava를 사용하고 있지 않아도 사용할 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;padding: 16px; background-color: rgb(246, 248, 250); box-sizing: border-box; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; font-stretch: normal; line-height: 1.45; word-wrap: normal; overflow: auto; border-radius: 3px; word-break: normal; color: rgb(36, 41, 46);&quot;&gt;&lt;p&gt;dependencies {
    compile &lt;span class=&quot;pl-s&quot; style=&quot;box-sizing: border-box; color: rgb(3, 47, 98);&quot;&gt;&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;'&lt;/span&gt;gun0912.ted:tedonactivityresult:1.0.2&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;사용 방법&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;RxJava1/RxJava2 모두 사용방법은 같습니다.&lt;/p&gt;&lt;pre style=&quot;box-sizing: border-box; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; font-stretch: normal; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; color: rgb(36, 41, 46);&quot;&gt;&lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;TedRxOnActivityResult&lt;/span&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;with(&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;this&lt;/span&gt;)
    .startActivityForResult(intent)
    .subscribeOn(&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;...&lt;/span&gt;)
    .observeOn(&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;...&lt;/span&gt;)
    .subscribe(activityResult &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;&amp;gt;&lt;/span&gt; {

      &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;if&lt;/span&gt; (activityResult&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;getResultCode() &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;RESULT_OK&lt;/span&gt;) {
        &lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;Intent&lt;/span&gt; data &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;=&lt;/span&gt; activityResult&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;getData();
        &lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;String&lt;/span&gt; name &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;getStringExtra(&lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;SampleActivity&lt;/span&gt;&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;EXTRA_NAME&lt;/span&gt;);
        &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;int&lt;/span&gt; age &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;getIntExtra(&lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;SampleActivity&lt;/span&gt;&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;EXTRA_AGE&lt;/span&gt;, &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;1&lt;/span&gt;);
      }

    });&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;RxJava를 사용하고 있지않거나 chaining방식을 원하지 않는다면,&amp;nbsp;Listener를 활용하는 방식으로 사용할 수도 있습니다.&lt;/p&gt;&lt;pre style=&quot;box-sizing: border-box; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; font-stretch: normal; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; color: rgb(36, 41, 46);&quot;&gt;&lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;TedOnActivityResult&lt;/span&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;with(&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;this&lt;/span&gt;)
    .setIntent(intent)
    .setListener((resultCode, data) &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;&amp;gt;&lt;/span&gt; {
       &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;if&lt;/span&gt; (resultCode &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;RESULT_OK&lt;/span&gt;) {
        &lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;String&lt;/span&gt; name &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;getStringExtra(&lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;SampleActivity&lt;/span&gt;&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;EXTRA_NAME&lt;/span&gt;);
        &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;int&lt;/span&gt; age &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;getIntExtra(&lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;SampleActivity&lt;/span&gt;&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;.&lt;/span&gt;EXTRA_AGE&lt;/span&gt;, &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: rgb(215, 58, 73);&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: rgb(0, 92, 197);&quot;&gt;1&lt;/span&gt;);
      }

    })
    .startActivityForResult();&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Github에서 샘플프로젝트를 다운받아보시고 테스트해보시면 이해하시는데 좀더 수월합니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedRxOnActivityResult&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedRxOnActivityResult&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 라이브러리가 유용하셨다면 오른쪽 상단에 Star버튼도 꾹 눌러주시면 감사하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;TedRxOnActivityResult를 활용하셔서 좀더 효율적인 코드를 작성하시고 코딩시간을 줄이시길 바랍니다.&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 164px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/993E9C3359A89F3408&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F993E9C3359A89F3408&quot; width=&quot;300&quot; height=&quot;164&quot; filename=&quot;party.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 300px; height: 164px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/75</guid>
      <comments>https://gun0912.tistory.com/75#entry75comment</comments>
      <pubDate>Fri, 1 Sep 2017 10:17:13 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]Flavors로 같은 소스코드 다른앱 만들기</title>
      <link>https://gun0912.tistory.com/74</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 250px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/270CDA3D591579EB01&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F270CDA3D591579EB01&quot; width=&quot;250&quot; height=&quot;250&quot; filename=&quot;ProductFlavor.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 250px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;저는 개인앱을 여러개 운영하고 있습니다.&lt;/p&gt;&lt;p&gt;앗! 이 포스팅을 통해 제 개인앱중 몇가지를 소개해 드리겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;#특가특공대&lt;/b&gt;&lt;/p&gt;&lt;p&gt;- 특가항공권&amp;nbsp;프로모션/이벤트 정보 알림&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.gun0912.promotion&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://play.google.com/store/apps/details?id=com.gun0912.promotion&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2226AC4659157AF234&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2226AC4659157AF234&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;Screenshot1.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 445px;&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 444px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2127F54659157AF628&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2127F54659157AF628&quot; width=&quot;250&quot; height=&quot;444&quot; filename=&quot;Screenshot2.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 444px;&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/271DB64659157AF409&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F271DB64659157AF409&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;Screenshot3.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 445px;&quot; original=&quot;yes&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;#이번에내려요&lt;/b&gt;&lt;/p&gt;&lt;p&gt;-&amp;nbsp;목적지 도착 알림(도착지 알림)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.gun0912.Nmap&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://play.google.com/store/apps/details?id=com.gun0912.Nmap&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/26234E5059157C0908&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F26234E5059157C0908&quot; width=&quot;250&quot; height=&quot;444&quot; filename=&quot;ko_Screenshot2.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; text-align: center;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/233BD74059157B9C14&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F233BD74059157B9C14&quot; width=&quot;250&quot; height=&quot;443&quot; filename=&quot;ko_Screenshot3.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;text-align: center;&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; text-align: center;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/237FE14059157B9C2E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F237FE14059157B9C2E&quot; width=&quot;250&quot; height=&quot;443&quot; filename=&quot;ko_Screenshot4.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;text-align: center;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이런 개인앱을 운영하면서 그안에 광고를 넣고 수익을 내고 있습니다.&lt;/p&gt;&lt;p&gt;하지만 이런 광고를 싫어하는 사용자들도 있습니다.&lt;/p&gt;&lt;p&gt;돈주고 살테니 유료앱을 만들어서 제공해달라고 하는 사용자들도 있었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그래서 저는 무료앱뿐만 아니라 유료앱을 만들기로 하였습니다.&lt;/p&gt;&lt;p&gt;무료앱과 유료앱의 소스코드상에서 차이는 딱 1가지일것입니다.&lt;/p&gt;&lt;p&gt;'광고를 표시하느냐 마느냐'&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그냥 아무생각 없이 만들었다면 프로젝트를 복사해서 2개의 프로젝트로 나누고 한군데에서는 광고를 표시하고 나머지 다른데에서는 광고를 표시하지 않게 했을 것입니다.&lt;/p&gt;&lt;p&gt;만약 수정사항이 발생하거나 추가적인 기능이 필요하다면 각각 2개의 프로젝트에 소스코드를 넣어주는 번거롭고 오류를 발생시킬만한 여지가 있는 상황에 놓이게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이럴때 Flavor를 이용한다면 유용합니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Flavor는 대부분의 소스코드는&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&amp;nbsp;똑같고 일부 값에 의해서 동작을 달리 해야하거나, 앱이름/아이콘을 달리해야하거나 등등의 상황일경우에 유용하게 쓰일 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이런 경우가 유용하게 쓰일것입니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. 유료앱/무료앱에 따라서 광고를 보여주거나 기타 설정을 다르게 하고 싶은 경우&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. 플레이스토어, 원스토어, 바이두, 텐센트등 배포하는 마켓에 따라서 표시하는 내용이나 값을 다르게 하고 싶은 경우&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;3. 고객용/관리자용 혹은 고객용/업체용 등으로 버전을 나누어야 하는 경우&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;4. 기획자가 개발,스테이징,운영 환경에 따른 각각의 앱동작을 확인하고 싶은 경우&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;5. 국가별/언어별로 앱의 내용을 달리 해서 보여주고 싶은 경우&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;저는 유료앱과 무료앱에 따라서 광고를 보여주고 안보여주고 앱아이콘과 앱이름을 다르게 표시해주는 샘플앱을 만들어 보겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;productFlavors 선언&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;app의 build.gradle에 아래와 같이 productFlavors 내용을 선언해 줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;android {&lt;br /&gt;    &lt;/p&gt;&lt;p&gt;    productFlavors {&lt;br /&gt;        free {&lt;br /&gt;            &lt;span style=&quot;color:#9876aa;&quot;&gt;applicationIdSuffix &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;.free&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;versionCode &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;versionName &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;1.0.0&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        paid {&lt;br /&gt;            &lt;span style=&quot;color:#9876aa;&quot;&gt;applicationIdSuffix &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;.paid&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;versionCode &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;2&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;versionName &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;1.0.1&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;applicationIdSuffix를 이용하면 원래의 applicationId 뒤에 각각 free/paid앱의 아이디가 추가로 붙게됩니다.&lt;/p&gt;&lt;p&gt;예를들어 기본 application id가&amp;nbsp;'com.gun0912'였다면&lt;/p&gt;&lt;p&gt;free는 'com.gun0912.free'가 되고 paid는 'com.gun0912.paid'의 application id가 됩니다.&lt;/p&gt;&lt;p&gt;versionCode, versionName을 각각 설정해서 버전관리를 해주도록 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이렇게 flavor로 앱을 나누고 나면 BuildVariant에서 2개의 앱이 각각 나누어서 생기는것을 확인해 보실 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 332px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/25203B34591580CB18&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F25203B34591580CB18&quot; width=&quot;332&quot; height=&quot;421&quot; filename=&quot;Screenshot at 5월 12 18-30-33.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;앱을 실행할때 각각의 free/paid로&amp;nbsp;나누어서 실행할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;변수 활용하기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;무료앱/유료앱에 따라서 광고를 보여주고 보여주지 않기위해서 buildConfigField를 활용합니다.&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: Menlo; font-size: 9pt;&quot;&gt;&lt;p&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;android {&lt;br /&gt;    &lt;/p&gt;&lt;p&gt;    productFlavors {&lt;br /&gt;        free {&lt;br /&gt;            ...&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;            &lt;/span&gt;buildConfigField &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;'boolean'&lt;/span&gt;, &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;'IS_FREE'&lt;/span&gt;, &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;true&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;      &lt;/span&gt;  }&lt;br /&gt;&lt;br /&gt;        paid {&lt;br /&gt;            ...&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;            &lt;/span&gt;buildConfigField &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;'boolean'&lt;/span&gt;, &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;'IS_FREE'&lt;/span&gt;, &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;false&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;       &lt;/span&gt; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;위와 같이 선언하면 소스코드에서 아래와 같이 사용할 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;if&lt;/span&gt;(BuildConfig.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;IS_FREE&lt;/span&gt;){&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 무료앱&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    // 광고 보여주기&lt;br /&gt;&lt;/span&gt;}&lt;span style=&quot;color:#cc7832;&quot;&gt;else&lt;/span&gt;{&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 유료앱&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    // 광고 보여주지 않기&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;이뿐만 아니라 flavor를 사용하는 목적에 맞게 여러 변수들을 만들고 소스코드상에서 이를 구분해서 활용할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(255, 0, 0);&quot;&gt;앱 이름 달리하기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;각각의 앱의 이름을 다르게 정해줄 수도 있습니다.&lt;/p&gt;&lt;p&gt;이럴때 manifestPlaceholders를 이용합니다.&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43); font-family: Menlo; font-size: 9pt;&quot;&gt;&lt;p style=&quot;color: rgb(169, 183, 198);&quot;&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;android {&lt;br /&gt;    &lt;/p&gt;&lt;p style=&quot;color: rgb(169, 183, 198);&quot;&gt;    productFlavors {&lt;br /&gt;        free {&lt;br /&gt;           &lt;span style=&quot;font-size: 9pt;&quot;&gt; ...&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;color: rgb(169, 183, 198);&quot;&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170);&quot;&gt;manifestPlaceholders &lt;/span&gt;= [ &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;appLabel&lt;/span&gt;: &lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;Flavor(Free)&quot; &lt;/span&gt;]&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        paid {&lt;br /&gt;           &lt;span style=&quot;font-size: 9pt;&quot;&gt; ...&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;&lt;font color=&quot;#6a8759&quot;&gt;            &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-size: 9pt;&quot;&gt;manifestPlaceholders &lt;/span&gt;&lt;span style=&quot;color: rgb(169, 183, 198); font-size: 9pt;&quot;&gt;= [ &lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89); font-size: 9pt;&quot;&gt;appLabel&lt;/span&gt;&lt;span style=&quot;color: rgb(169, 183, 198); font-size: 9pt;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89); font-size: 9pt;&quot;&gt;&quot;Flavor(&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89); font-size: 9pt;&quot;&gt;Paid&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(106, 135, 89);&quot;&gt;)&quot; &lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(169, 183, 198);&quot;&gt;]&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;color: rgb(169, 183, 198);&quot;&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;appLabel을 각각 원하는 이름을 정해두고 이를 아래의 Manifest에 변수로 넣어주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;application&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:allowBackup=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;true&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:icon=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@mipmap/ic_launcher&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:label=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;${appLabel}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:supportsRtl=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;true&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:theme=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@style/AppTheme&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;activity &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;.MainActivity&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;intent-filter&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &amp;lt;action &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.intent.action.MAIN&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &amp;lt;category &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.intent.category.LAUNCHER&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;/intent-filter&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;/activity&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/application&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;앱 아이콘 달리하기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;각각 앱에 따라서 이름을 다르게 한것처럼 아이콘도 다르게 할 수 있습니다.&lt;/p&gt;&lt;p&gt;Flavor를 사용하느냐 사용하지 않느냐에 따라서 폴더의 구조가 아래와 같이 나뉘게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;box-sizing: inherit; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; margin-top: 0px; margin-bottom: 0px; padding: 0.6em 1.2em; border: 0px; border-radius: 3px; background-color: rgb(247, 247, 247); color: rgb(51, 51, 51); word-wrap: normal; word-break: break-all; line-height: 1.2; overflow-x: auto;&quot;&gt;&lt;p style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&amp;lt;Flavor 미사용&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&amp;gt;                  &lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&amp;lt;Flavor 사용&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;
  ┗━app                         ┗━app
          ┗━src                         ┗━src
                 ┗━main                       ┣━free&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;
                          ┣━java               &lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;┃  ┣━java
  &lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;         ┗━res   &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;       &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;┃  ┗━res&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;
                      &lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;            ┣━main
                                     &lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt; ┃  ┣━java
                    &lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;              ┃  ┗━res
                  &lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;                ┗━paid&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-size: 0.8em;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;                 &lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;                 ┃  ┣━java
 (노가다...)    &lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;       &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;       ┃  ┗━res&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;각각 free, paid의 res폴더에 같은 이름의 아이콘을 넣어주면 앱은 build 환경에 따라서 그에맞는 앱아이콘을 표시해줄것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 326px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/245C6D415915865306&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F245C6D415915865306&quot; width=&quot;326&quot; height=&quot;421&quot; filename=&quot;Screenshot at 5월 12 18-53-31.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이미지 뿐만 아니라 dimens.xml, string.xml 등 각자 원하는 방법에 따라서 이 폴더구조를 활용하면 됩니다.&lt;/p&gt;&lt;p&gt;위에서 살펴보았던 앱의 이름을 달리 하는 방법도&amp;nbsp;manifestPlaceholders를 사용하지 않고 각각 free, paid폴더에 string.xml에 앱이름을 넣는 방법으로도 가능합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위와같이 앱을 만들어서 각각 설치를 해주면 소스코드는 똑같지만 내용은 다른 2개의 앱이 설치되어 있는것을 확인할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 364px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/26649B425915875429&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F26649B425915875429&quot; width=&quot;364&quot; height=&quot;364&quot; filename=&quot;ProductFlavor.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;백문이불여일견이죠&lt;/p&gt;&lt;p&gt;위의 샘플 예제는 Github에서 다운받아서 테스트 해보실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/ProductFlavorSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/ProductFlavorSample&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Github을 들어가셨다면 꼭 Star 눌러주시면 감사하겠습니다!&lt;/p&gt;&lt;p&gt;저에게는 별풍선 주시는 효과가 있어요!&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 150px; width: 150px; height: 76px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2625B4395917C42F09&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2625B4395917C42F09&quot; width=&quot;150&quot; height=&quot;76&quot; filename=&quot;68747470733a2f2f7068617365722e696f2f636f6e74656e742f6e6577732f323031352f30392f31303030302d73746172732e706e67.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 150px; height: 76px;&quot; original=&quot;yes&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;좀더 자세한 내용이 궁금하시다면 &lt;a href=&quot;https://developer.android.com/studio/build/build-variants.html?hl=ko#sourceset-build&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;구글 공식 문서&lt;/a&gt;를 살펴보셔도 좋습니다.&lt;/p&gt;&lt;p&gt;소스코드는 비슷하지만 일부분만 다른 앱을 만들고 싶으시다면 flavor를 활용해서 효율적인 코딩을 하시기 바랍니다.&lt;/p&gt;&lt;p&gt;감사합니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2528024E591589A303&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2528024E591589A303&quot; width=&quot;250&quot; height=&quot;103&quot; filename=&quot;giphy-downsized.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/74</guid>
      <comments>https://gun0912.tistory.com/74#entry74comment</comments>
      <pubDate>Fri, 12 May 2017 19:11:44 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]tools attribute 유용하게 활용하기(xmlns:tools=&amp;quot;http://schemas.android.com/tools&amp;quot;)</title>
      <link>https://gun0912.tistory.com/73</link>
      <description>&lt;p&gt;안드로이드를 개발하면서 프로젝트를 새로 만들거나 xml파일에서 우리가 자주 만나는 녀석이 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;xmlns:tools=&quot;http://schemas.android.com/tools&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 244px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2227A84858DFBE4B09&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2227A84858DFBE4B09&quot; width=&quot;244&quot; height=&quot;244&quot; filename=&quot;Screenshot at 4월 01 23-50-12.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;xml에 tools:context=&quot;xxx&quot; 라는 걸 수도 없이 보아 왔지만&lt;/p&gt;&lt;p&gt;사실 저는 지금까지 그냥 아무생각없이 지워주거나 무시하고 넘어가곤 했었습니다.&lt;/p&gt;&lt;p&gt;&lt;strike&gt;저만 그랬던게 아니라고 말해주세요&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그러던 어느날 tools에 대해서 궁금해졌습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 208px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/231C5A3E58DF9A8109&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F231C5A3E58DF9A8109&quot; width=&quot;300&quot; height=&quot;208&quot; filename=&quot;다운로드 (1).jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 208px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;tools는 뭐하는 녀석일까요?&lt;/p&gt;&lt;p&gt;알고보면 tools는 그동안 우리가 필요로 했던 기능들을 제공해주는 녀석이었습니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;유용한 tools의 attribute들을 하나하나씩 소개해드리겠습니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;tools:text&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;TextView를 만들고나서 이 TextView에 내용이 어떻게 나오는지 확인을 하고 싶은 경우가 있습니다.&lt;/p&gt;&lt;p&gt;그래서 android:text=&quot;어쩌고저쩌고&quot; 처럼 값을 넣어보고 '아 이렇게 나오는구나' 확인을 한뒤 값을 다시 지우곤 합니다.&lt;/p&gt;&lt;p&gt;혹시 이 테스트값을 지우지 않으면 앱에서 실제로 테스트 텍스트값이 나와버려서 곤란한 경우가 있습니다.&lt;/p&gt;&lt;p&gt;이러한 작업은 여간 귀찮은게 아니었지만 다른방법이 없기때문에 항상 이런식으로 TextView가 어떻게 나오는지 테스트를 해왔죠.&lt;/p&gt;&lt;p&gt;하지만 tools:text를 이용한다면 위의 귀찮음이 필요 없습니다.&lt;/p&gt;&lt;p&gt;tools:text에 값을 넣어주면 xml의 layout preview에서 어떻게 나오는지 확인할수 있고 실제 앱에서는 표시되지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2272323658DF9C4A36&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2272323658DF9C4A36&quot; width=&quot;820&quot; height=&quot;186&quot; filename=&quot;tools-attribute-text_2x.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위 그림의 경우 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;preview에서는 오른쪽처럼 모두 값들이 표시되지만 실제 실행할때는&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&amp;nbsp;나오지 않습니다&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그외에 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;tools:src, tools:background등도 위의 기능처럼 똑같이 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;테스트해본결과 android:xxx 로 실행하는 거의 모든 기능을 tools:xxx 로 대체하면 preview에서는 반영되고 실제로는 나오지 않는 기능인걸 확인 할 수 있습니다&lt;/p&gt;&lt;p&gt;(예)&amp;nbsp;tools:layout_marginTop=&quot;16dp&quot; 등&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;tools:visibility&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2개의 View가&amp;nbsp;겹쳐 있을경우 위의 View때문에 아래의 View가&amp;nbsp;가려지게 됩니다.&lt;/p&gt;&lt;p&gt;그래서 아래에 있는 View를 꾸밀때 어떻게 나오는지 잘 안보여서 위의 View 코드를 없애거나 android:visibilty=&quot;invisible&quot; 로 가려놓고 작업을 하곤 하는데 이것 또한 위의View를 보여지는걸로 코드를 돌려놓지 않으면 의도하지 않은 결과가 나옵니다.&lt;/p&gt;&lt;p&gt;하지만 이또한 tools:visibilty를 이용하면 해결할 수 있습니다.&lt;/p&gt;&lt;p&gt;단순히 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;preview에서만 안보일뿐 실제 실행할때는 원래대로&lt;/span&gt; View의 구조대로 나오게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;prettyprint&quot; style=&quot;margin-top: 0px; margin-bottom: 1em; color: rgb(0, 102, 0); font-stretch: normal; line-height: 18px; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Monaco, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 1em; overflow: auto; border: 1px solid rgb(221, 221, 221); background: rgb(247, 247, 247);&quot;&gt;&lt;span class=&quot;tag&quot; style=&quot;color: rgb(0, 0, 136);&quot;&gt;&amp;lt;Button&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;android:id&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;@+id/button&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;android:layout_width&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;wrap_content&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;android:layout_height&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;wrap_content&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;android:text&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;First&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;tag&quot; style=&quot;color: rgb(0, 0, 136);&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;tag&quot; style=&quot;color: rgb(0, 0, 136);&quot;&gt;&amp;lt;Button&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;android:id&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;@+id/button2&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;android:layout_width&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;wrap_content&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;android:layout_height&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;wrap_content&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;android:text&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;Second&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;b style=&quot;color: inherit;&quot;&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;tools:visibility&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;invisible&quot;&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;span class=&quot;tag&quot; style=&quot;color: rgb(0, 0, 136);&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;tools:listitem&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;RecyclerView나 ListView를 이용하는경우, 우리는 &amp;lt;RecyclerView&amp;gt; 혹은 &amp;lt;ListView&amp;gt;를 만들고 그에 해당하는 row item 의 xml을 만듭니다.&lt;/p&gt;&lt;p&gt;그럼 아래 스크린샷처럼 해당 RecyclerView/ListView에 해당하는 영역에 Item0, Item1, Item2, Item3 ... 으로 내용이 표시됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 499px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/275DAF4758DF9EC41D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F275DAF4758DF9EC41D&quot; width=&quot;300&quot; height=&quot;499&quot; filename=&quot;Screenshot at 4월 01 21-35-36.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 499px;&quot;/&gt;&lt;/span&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;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;tools:listitem을 이용하면 이 영역에 우리가 보여주고자 하는 row item 을 미리 넣어 볼수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;android.support.v7.widget.RecyclerView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/rc_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:clipToPadding=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;false&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:paddingLeft=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/default_padding_small&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:paddingRight=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/default_padding_small&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tools&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:listitem=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@layout/content_item&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 498px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2443B04D58DF9FB240&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2443B04D58DF9FB240&quot; width=&quot;300&quot; height=&quot;498&quot; filename=&quot;Screenshot at 4월 01 21-40-07.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 498px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그냥 단순히 텍스트가 있는것보다는 RecyclerView/ListView에 내가 넣으려고하는 row들이 어떻게 보여질지 미리 확인할 수 있기때문에 훨씬 유용합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이 방법은 GridView,ExpandableListView에서도 먹힙니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;또한 자매품으로 tools:listheader , tools:listfooter도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;tools:layout&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;xml에서 fragment를 사용하는 경우 preview에서는 회색화면으로 fragment의 영역을 보여줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 819px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/26783F4858DFA1601F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F26783F4858DFA1601F&quot; width=&quot;819&quot; height=&quot;637&quot; filename=&quot;Screenshot at 4월 01 21-47-07.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 여기서 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;tools:layout으로 fragment에 보여주려는 layout을 지정하면 어떻게 보여지는지 미리 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 801px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/236C1C4E58DFA1DB23&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F236C1C4E58DFA1DB23&quot; width=&quot;801&quot; height=&quot;646&quot; filename=&quot;Screenshot at 4월 01 21-49-21.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;tools:showIn&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;tools:showIn은 tools:layout의 반대개념&lt;/span&gt;이라고 생각하면 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;row item입장에서도 '내가 이렇게 만들어지면 나를 쓰는애들하고는 어떻게 조화되서 보이지?' 라고 궁금해할 수 있는데요&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이때 showIn을 사용합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;activity_main.xml에서 textview1.xml을 &amp;lt;include&amp;gt;태그를 이용하여 넣어주는경우가 있다고 가정해보겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/276A094358DFA82E2B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F276A094358DFA82E2B&quot; width=&quot;820&quot; height=&quot;318&quot; filename=&quot;Screenshot at 4월 01 22-16-16.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;textview1.xml입장에서도 내가 activity_main에서 쓰일때 어떻게 보여질지 궁금할수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;tools:showIn을 사용하면 내가 어떻게 어울려서 보여질지 미리 알 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/21205D4258DFA85037&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F21205D4258DFA85037&quot; width=&quot;820&quot; height=&quot;316&quot; filename=&quot;Screenshot at 4월 01 22-16-53.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;tools:locale&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Android Studio의 기본언어는 영어입니다.&lt;/p&gt;&lt;p&gt;프랑스어나 스페인어 등 영어가 아닌 언어를 써주면 Android Studio는 우리에게 스펠링이 틀렸다고 안내가 나옵니다.&lt;/p&gt;&lt;p&gt;&lt;strike&gt;응안틀렸어&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 438px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2623413E58DFA49428&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2623413E58DFA49428&quot; width=&quot;438&quot; height=&quot;158&quot; filename=&quot;Screenshot at 4월 01 22-00-56.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;영어의 오타를 잡아주는 이 기능은 유용한경우가 많지만 때로는&amp;nbsp;영어가 아니어서 잘못 표시되는 경우도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이럴때 tools:locale을 이용해서 이 언어가 영어가 아닌 특정국가의 string임을 알려줄수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 520px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/242E504458DFA4D222&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F242E504458DFA4D222&quot; width=&quot;520&quot; height=&quot;204&quot; filename=&quot;Screenshot at 4월 01 22-02-00.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 언어가 프랑스 언어인것을 알려주자 더이상 스펠링이 틀렸다고 알려주지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;tools:context&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 포스팅의 영감을 주었던 tools:context입니다.&lt;/p&gt;&lt;p&gt;이 xml이 어떤 액티비티와 연관이 있는지를 알려주는 기능입니다.&lt;/p&gt;&lt;p&gt;tools:context=&quot;.MainActivity&quot;라고 만들어 두었다면 이 xml은 MainActivity와 연결되어있구나를 미리 알수있고 이와관련된 작업들에 대해서 작업을 도와줄수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 400px; width: 400px; height: 235px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/230BD23D58DFA9DC19&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F230BD23D58DFA9DC19&quot; width=&quot;400&quot; height=&quot;235&quot; filename=&quot;tools-attribute-context_2x.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 400px; height: 235px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위처럼 onButtonClicked라는 없는 함수이름을 지정해줄경우 새로 onButtonClicked()라는 함수를 만들어주어야 하는데 이 xml이 MainActivity와 연결되어있음을 알기때문에 MainActivity에 함수를 만들건지 도와주는 창을 띄워줄수 있습니다.&lt;/p&gt;&lt;p&gt;만약 context를 지정해주지 않으면 어디서 쓰이는지를 모르기때문에 어떤 추천창도 띄워줄수가 없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;tools:ignore&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;예를들어 다국적 언어를 지원하는 앱을 만들경우 아래와 같이 string.xml을 만들면 Lint오류가 납니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;string.xml(en)&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;string &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;open&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;Open&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/string&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;string &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;close&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;Close&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;string.xml(ko)&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43); font-family: Menlo; font-size: 9pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;lt;string &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186);&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;open&quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;font color=&quot;#a9b7c6&quot;&gt;열기&lt;/font&gt;&lt;span style=&quot;color: rgb(232, 191, 106);&quot;&gt;&amp;lt;/string&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;'close'에 대한 한글번역값이 없기때문에 MissingTranslation Lint 에러가&amp;nbsp;발생할것입니다.&lt;/p&gt;&lt;p&gt;Lint오류는 사실 우리에게 매우 유용한 경고입니다.&lt;/p&gt;&lt;p&gt;하지만 가끔은 Lint를 꺼주고 싶은경우가 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래처럼 앱이름은 언어와 상관없이 같은 앱이름으로 쓰고 싶은데 한글용 'app_name'이 없다며 오류를 발생시킬것입니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;string &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;app_name&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;DestinationAlarm&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;이럴때 tools:ignore를 이용해서 MissingTranslation을 잠시 꺼두셔도 좋습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;string &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;app_name&quot;  &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tools&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:ignore=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;MissingTranslation&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;DestinationAlarm&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;MssingTranslation뿐만 아니라&amp;nbsp;IconMissingDensityFolder등 무시하고싶은 Lint관련 오류에 대해서 ignore해주실수 있으며 tools:ignore=&quot;all&quot; 도 사용하실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;하지만 특별한 상황이 아닌이상 Lint는 무시하지 말고 꼭 지켜주시는 것이 정신건강에 &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;좋습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;tools:targetApi&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;@TargetApi annotaion과 같은역할을 해줍니다.&lt;/p&gt;&lt;p&gt;만약 GridLayout을 사용하려는경우 API레벨 14이상이어야 사용할수있고 그 아래에서는 사용할 수 없습니다.&lt;/p&gt;&lt;p&gt;minsdkVersion이 14보다 아래일경우 문제가 발생합니다.&lt;/p&gt;&lt;p&gt;그래서 targetapi는 14임을 명시해주어서 14이상에서만 앱이 동작할 수 있도록 유도할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;prettyprint&quot; style=&quot;margin-top: 0px; margin-bottom: 1em; color: rgb(0, 102, 0); font-stretch: normal; line-height: 18px; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Monaco, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 1em; overflow: auto; border: 1px solid rgb(221, 221, 221); background: rgb(247, 247, 247);&quot;&gt;&lt;code style=&quot;font-stretch: normal; line-height: 18px; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Monaco, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased;&quot;&gt;&lt;span class=&quot;tag&quot; style=&quot;color: rgb(0, 0, 136);&quot;&gt;&amp;lt;GridLayout&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;xmlns:android&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;xmlns:tools&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;http://schemas.android.com/tools&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;tools:targetApi&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;14&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;tag&quot; style=&quot;color: rgb(0, 0, 136);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;tools:shrinkMode / tools:keep / tools:discard&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 외에도 shrink와 관련된&amp;nbsp;tools:keep, tools:shrinkMode, tools:discard등이 있습니다.&lt;/p&gt;&lt;p&gt;shrink는 사용하지않는 코드및 리소스들을 축소시킬때 유용합니다.&lt;/p&gt;&lt;p&gt;자세한 내용은 아래 링크를 통해서 확인하실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://developer.android.com/studio/build/shrink-code.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://developer.android.com/studio/build/shrink-code.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;shrink를 이용하고 있고 리소스를 축소하고 싶지만 특정 리소스를 유지하거나 없애버리고 싶은경우에 keep과 discard를 이용해주면됩니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;prettyprint&quot; style=&quot;margin-top: 0px; margin-bottom: 1em; color: rgb(0, 102, 0); font-stretch: normal; line-height: 18px; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Monaco, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 1em; overflow: auto; border: 1px solid rgb(221, 221, 221); background: rgb(247, 247, 247);&quot;&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;xml version&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;str&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt; encoding&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;str&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;tag&quot; style=&quot;color: rgb(0, 0, 136);&quot;&gt;&amp;lt;resources&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;xmlns:tools&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;http://schemas.android.com/tools&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;tools:keep&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;atn&quot; style=&quot;color: rgb(136, 34, 136);&quot;&gt;tools:discard&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;color: rgb(102, 102, 0);&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;atv&quot; style=&quot;color: rgb(136, 0, 0);&quot;&gt;&quot;@layout/unused2&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;span class=&quot;tag&quot; style=&quot;color: rgb(0, 0, 136);&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;위와같이 선언해주는 경우 keep한 리소스들은 없어지지 않으며 discard한 리소스들은 없어지게 되는것을 확인할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;어때요&amp;nbsp;몰랐던 유용한 tools관련 attribute를 발견하셨나요?&lt;/p&gt;&lt;p&gt;저는 tools:text, tools:layout, tools:listitem을 정말 유용하게 사용하고 있답니다.&lt;/p&gt;&lt;p&gt;여러분들에게도 많은 도움이 되었으면 좋겠습니다.&lt;/p&gt;&lt;p&gt;tools attribute와 함께 행복한 코딩하시기 바랍니다.&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 230px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2370B13658DFBB9F2D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2370B13658DFBB9F2D&quot; width=&quot;230&quot; height=&quot;187&quot; filename=&quot;happy.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/73</guid>
      <comments>https://gun0912.tistory.com/73#entry73comment</comments>
      <pubDate>Sat, 1 Apr 2017 23:47:29 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]GIF로 '로딩중' Dialog 띄우는 방법</title>
      <link>https://gun0912.tistory.com/72</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;서버와 통신을 하거나 기타 작업을 할때 결과를 받을때까지 사용자가 기다려야 하는 경우가 있습니다.&lt;/p&gt;&lt;p&gt;그럴때 우리는 Progress를 보여주면서 작업이 뭔가 진행되고 있음을 알리곤 합니다.&lt;/p&gt;&lt;p&gt;작업이 진행중임을 나타내는 방법은 여러가지 입니다.&lt;/p&gt;&lt;p&gt;그중에서 GIF이미지를 활용해서 작업이 진행중임을 알리는 방법을 소개해 드리겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저 완성된 결과부터 보여드리겠습니다.&lt;/p&gt;&lt;p&gt;어떤 작업을 시작하는 경우 사용자에게 아래와 같은 화면을 보여줄수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 271px; width: 271px; height: 480px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2206084558CCD56111&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2206084558CCD56111&quot; width=&quot;271&quot; height=&quot;480&quot; filename=&quot;KakaoTalk_Photo_2017-03-18-15-35-18_35.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 271px; height: 480px;&quot;/&gt;&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 270px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2452344B58CCC90B23&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2452344B58CCC90B23&quot; width=&quot;270&quot; height=&quot;480&quot; filename=&quot;progress_screenshot.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;원리는 간단합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;1. Dialog를 띄운다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2. Dialog의 레이아웃에서 GIF이미지와 텍스트를 보여준다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그럼 소스코드와 함께 구현방법에 대해서 소개하겠습니다.&lt;/p&gt;&lt;p&gt;바로 테스트 해보고 싶으신분은 Github을 통해 테스트 해보실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/GifProgressSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/GifProgressSample&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;1. GIF준비&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저 사용할 gif파일을 준비해야 합니다.&lt;/p&gt;&lt;p&gt;직접 만드셔도 되고 어디서 구하시거나 디자이너가 있다면 디자이너로부터 gif를 받으면 됩니다.&lt;/p&gt;&lt;p&gt;gif는 여러 이미지파일들이 연속적으로 보여지는 것이기 때문에 당연히 gif로부터 각각의 frame에 해당하는 이미지파일도 얻을 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;샘플에서 사용된 아래의 GIF는 총 21개의 이미지들이 모여서 만들어진것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 120px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2563B24358CCCBA633&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2563B24358CCCBA633&quot; width=&quot;120&quot; height=&quot;120&quot; filename=&quot;selphone_progress.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 301px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/247F774258CCCBB40E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F247F774258CCCBB40E&quot; width=&quot;300&quot; height=&quot;301&quot; filename=&quot;Screenshot at 3월 18 14-54-09.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 301px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;2. AnimationDrawable&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이미지를 모두 확보했다면 drawable폴더에 각각의 이미지들을 모두 넣어줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 263px; width: 263px; height: 400px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/277A335058CCCC3313&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F277A335058CCCC3313&quot; width=&quot;263&quot; height=&quot;400&quot; filename=&quot;Screenshot at 3월 18 14-56-01.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 263px; height: 400px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그리고 이 이미지들을 모두 담는 &amp;lt;animation-list&amp;gt;를 만들어줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/4b5c8c581eb74a6c82ac07395d72e656.js?file=frame_loading.xml&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;3. Dialog layout&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;다이어로그가 새로 뜰때 보여줄 레이아웃을 만듭니다.&lt;/p&gt;&lt;p&gt;이 레이아웃은 샘플일뿐이므로 나중에 원하시는대로 변경하시면 됩니다.&lt;/p&gt;&lt;p&gt;저는 이미지 + 메세지 가 표시되는 방법으로 레이아웃을 구성하였습니다.&lt;/p&gt;&lt;p&gt;위에서 만든 drawable을 ImageView의 background로 넣어줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/4b5c8c581eb74a6c82ac07395d72e656.js?file=progress_loading.xml&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;4. Dialog loading&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;프로그레스 다이어로그를 띄워야 하는 시점에 Dialog를 만들고 위에서 만든 layout을 customview로 설정 해주면됩니다.&lt;/p&gt;&lt;p&gt;progressON()이라는 함수를 만들었다면 아래와 같은 소스를 만들 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;progressON&lt;/span&gt;(Activity activity&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;String message) {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(activity == &lt;span style=&quot;color:#cc7832;&quot;&gt;null &lt;/span&gt;|| activity.isFinishing()) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog &lt;/span&gt;!= &lt;span style=&quot;color:#cc7832;&quot;&gt;null &lt;/span&gt;&amp;amp;&amp;amp; &lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.isShowing()) {&lt;br /&gt;        progressSET(message)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;else &lt;/span&gt;{&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;AppCompatDialog(activity)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.setCancelable(&lt;span style=&quot;color:#cc7832;&quot;&gt;false&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.getWindow().setBackgroundDrawable(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ColorDrawable(android.graphics.Color.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TRANSPARENT&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.setContentView(R.layout.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;progress_loading&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.show()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;final &lt;/span&gt;ImageView img_loading_frame = (ImageView) &lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;iv_frame_loading&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    final &lt;/span&gt;AnimationDrawable frameAnimation = (AnimationDrawable) img_loading_frame.getBackground()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;img_loading_frame.post(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Runnable() {&lt;br /&gt;        &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;run&lt;/span&gt;() {&lt;br /&gt;            &lt;span style=&quot;color:#b389c5;&quot;&gt;frameAnimation&lt;/span&gt;.start()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;    })&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;TextView tv_progress_message = (TextView) &lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tv_progress_message&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    if &lt;/span&gt;(!TextUtils.&lt;span style=&quot;font-style:italic;&quot;&gt;isEmpty&lt;/span&gt;(message)) {&lt;br /&gt;        tv_progress_message.setText(message)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;프로그레스 다이어로그가 이미 띄워져 있는경우라면 메세지만 바꿔주면 되므로 progressSET()이라는 함수를 만들고 여기서는 메세지 내용만 바꿔줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;progressSET&lt;/span&gt;(String message) {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog &lt;/span&gt;== &lt;span style=&quot;color:#cc7832;&quot;&gt;null &lt;/span&gt;|| !&lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.isShowing()) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    TextView tv_progress_message = (TextView) &lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tv_progress_message&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    if &lt;/span&gt;(!TextUtils.&lt;span style=&quot;font-style:italic;&quot;&gt;isEmpty&lt;/span&gt;(message)) {&lt;br /&gt;        tv_progress_message.setText(message)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;프로그레스를 종료해야하는 시점에는 progressOFF()를 호출합니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;progressOFF&lt;/span&gt;() {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog &lt;/span&gt;!= &lt;span style=&quot;color:#cc7832;&quot;&gt;null &lt;/span&gt;&amp;amp;&amp;amp; &lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.isShowing()) {&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;progressDialog&lt;/span&gt;.dismiss()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;추가 팁&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 262px; width: 262px; height: 200px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/237F114C58CCD22C0A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F237F114C58CCD22C0A&quot; width=&quot;262&quot; height=&quot;200&quot; filename=&quot;justamoment.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 262px; height: 200px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;저는 이 함수들을 Application 클래스에 두었습니다.&lt;/p&gt;&lt;p&gt;Application을 singleton으로 만들고 BaseActivity,BaseFragment를 만든뒤 거기서 이 함수들을 활용합니다.&lt;/p&gt;&lt;p&gt;모든 Activity,Fragment는 이 BaseActivity,BaseFragment를 상속받습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그렇게하는경우 단순히 Activity에서 progressON()이라는 함수만 실행해주어도 바로 다이어로그를 띄워줄수가 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/4b5c8c581eb74a6c82ac07395d72e656.js?file=BaseApplication.java&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/4b5c8c581eb74a6c82ac07395d72e656.js?file=BaseActivity.java&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;글만 읽어서는 어떠한 구조인지 잘 이해가 가지 않으실 수 있기때문에 Github에서 샘플프로젝트를 다운받고 돌려보시길 추천드립니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/GifProgressSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/GifProgressSample&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Github을 들어가셨다면 꼭 Star 눌러주시면 감사하겠습니다!&lt;/p&gt;&lt;p&gt;저에게는 별풍선 주시는 효과가 있어요!&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;600&quot; width=&quot;600&quot; exif=&quot;{}&quot; id=&quot;tx_entry_51030_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/2625B4395917C42F09&quot; height=&quot;304&quot; title=&quot;더블클릭을 하시면 이미지를 수정할 수 있습니다&quot; style=&quot;width: 150px; height: 76px;&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;어때요 참 쉽죠?&lt;/p&gt;&lt;p&gt;한문장으로 정리해보자면 GIF이미지들을 확보한뒤 이를 AnimationDrawable형태로 만든뒤에 Dialog를 새로띄우면서 해당 이미지의&amp;nbsp;애니메이션을 시작해주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;프로그레스를 어떻게 띄워야할지 고민하셨던 분들에게 도움이 되었으면 합니다.&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/72</guid>
      <comments>https://gun0912.tistory.com/72#entry72comment</comments>
      <pubDate>Sat, 18 Mar 2017 15:30:58 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]DataBinding - Goodbye 버터나이프 Hello 데이터바인딩</title>
      <link>https://gun0912.tistory.com/71</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;줄 요약&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;1. 데이터바인딩을&amp;nbsp;사용하면 findViewById() 안해도 자동으로 xml에 만든 View들을 만들어 준다.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2. RecyclerView에서 각각의 item을 set해주는 작업도 xml에서 다 써주면 알아서 값이 들어간다.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;3. 값이 바뀌면 알아서 바뀐값으로 View를 변경하게 할수도 있고 기타 등등 유용하게 활용 할만한게 많다.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;4.&amp;nbsp;&lt;a href=&quot;https://github.com/ParkSangGwon/TedDataBindingSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;샘플프로젝트&lt;/a&gt;&amp;nbsp;를 실행해보고 소스코드 보면 직접 느낄수 있다&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;/div&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;자 여러분 눈을 감고 상상해보세요&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;strike&gt;아, 눈을 감으면 이글을 못읽으니 눈은 뜨고 상상해보세요&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;새로운 화면을 추가해야 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;안드로이드 스튜디오를 켭니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그다음에 무엇을 해야할까요?&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;네 맞습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;xml을 만들고 화면 레이아웃을 구성해야합니다.&lt;strike&gt;(답정너)&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아래와 같은 레이아웃을 만들었다고 예를 들어보겠습니다.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;- TextView 5개&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;- Button 1개&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;- RecyclerView 1개&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xml version=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;1.0&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;encoding=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;?&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;LinearLayout &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xmlns:&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;              &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;              &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;              &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:orientation=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;vertical&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;LinearLayout&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:orientation=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;horizontal&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/tvText1&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/tvText2&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/tvText3&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/tvText4&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/tvText5&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;Button&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/btnSample&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;button&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;/LinearLayout&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;android.support.v7.widget.RecyclerView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/rcContent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/LinearLayout&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;xml을 만들었으니 이제 Activity에서 View를 이어주어야 겠죠?&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvText1&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvText2&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvText3&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvText4&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvText5&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;Button &lt;span style=&quot;color:#9876aa;&quot;&gt;btnSample&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;RecyclerView &lt;span style=&quot;color:#9876aa;&quot;&gt;rcContent&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;protected void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onCreate&lt;/span&gt;(&lt;span style=&quot;color:#bbb529;&quot;&gt;@Nullable &lt;/span&gt;Bundle savedInstanceState) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.onCreate(savedInstanceState)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;setContentView(R.layout.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;basic_activity&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tvText1 &lt;/span&gt;= (TextView) findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvText1&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tvText2 &lt;/span&gt;= (TextView) findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvText2&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tvText3 &lt;/span&gt;= (TextView) findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvText3&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tvText4 &lt;/span&gt;= (TextView) findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvText4&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tvText5 &lt;/span&gt;= (TextView) findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvText5&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;btnSample &lt;/span&gt;= (Button) findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;btnSample&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;rcContent &lt;/span&gt;= (RecyclerView) findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;rcContent&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;제일먼저 우리는&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt; 아무생각없이 findViewById() 노가다&lt;/span&gt;를 해줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이 레이아웃은 간단한 샘플이기 때문에 몇개 안되는 뷰이지만&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;만약 10개,100개 그리고 그 이상이라면 그만큼 노가다코드가 필요할 것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그래서 우리는 버터나이프(Butterknife)를 사용해왔습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://gun0912.tistory.com/2&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드]유용한 라이브러리 - Butter Knife (View Inject)&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;버터나이프를 사용한다면 우리는 조금이나마 findViewById()노가다를 줄일 수 있습니다.&lt;/b&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindView&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvText1&lt;/span&gt;)&lt;br /&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvText1&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindView&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvText2&lt;/span&gt;)&lt;br /&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvText2&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindView&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvText3&lt;/span&gt;)&lt;br /&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvText3&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindView&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvText4&lt;/span&gt;)&lt;br /&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvText4&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindView&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvText5&lt;/span&gt;)&lt;br /&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvText5&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindView&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;btnSample&lt;/span&gt;)&lt;br /&gt;Button &lt;span style=&quot;color:#9876aa;&quot;&gt;btnSample&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindView&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;rcContent&lt;/span&gt;)&lt;br /&gt;RecyclerView &lt;span style=&quot;color:#9876aa;&quot;&gt;rcContent&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;protected void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onCreate&lt;/span&gt;(&lt;span style=&quot;color:#bbb529;&quot;&gt;@Nullable &lt;/span&gt;Bundle savedInstanceState) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.onCreate(savedInstanceState)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;setContentView(R.layout.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;butterknife_activity&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;ButterKnife.&lt;span style=&quot;font-style:italic;&quot;&gt;bind&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;버터나이프를 알게되면서 저는 행복했습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;소스코드의 양을 반으로 줄여 주었으니까요.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;strike&gt;사랑합니다 Jake Wharton, 물론 전 남자를 좋아하지는 않습니다.&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(255, 0, 0);&quot;&gt;하지만 데이터바인딩(Databinding)&lt;/span&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(255, 0, 0);&quot;&gt;을 사용한다면 어떨까요?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: Menlo; font-size: 9pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;위의 화면은 오류가 아닙니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;따로 View를 정의하고 이어줄 필요가 없습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Databinding&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;을 사용한다면 우리는 아무 소스코드를 적지 않아도 Databinding이 &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;알아서 다 해줍니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 217px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2360534458A70A1A0F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2360534458A70A1A0F&quot; width=&quot;200&quot; height=&quot;217&quot; filename=&quot;databinding.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 217px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;최소사항&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Android 2.1(API레벨&amp;nbsp;7) 이상&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Android Plugin for Gradle 1.5.0-alpha1 이상&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Android Studio 1.3 이상&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아주 옛날의 환경으로 작업하고 있지 않는한 지금쓰는 환경에서 바로 사용할 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;설정&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;build.gradle (Module:app)&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;android{&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;//...&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;dataBinding {&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;enabled &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;true&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;설정은 gradle에서 enable만 true로 설정해주시면 끝납니다.&lt;/p&gt;&lt;p&gt;참 간단하죠?&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;xml&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Databinding을 사용하기 위해서는 xml의 최상위에 &amp;lt;layout&amp;gt;태그를 감싸줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xml version=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;1.0&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;encoding=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;?&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;layout &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xmlns:&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;LinearLayout&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:orientation=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;vertical&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&amp;lt;!--&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            ...&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        --&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/LinearLayout&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/layout&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;Java&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Activity에서 항상 해주던 setContentView()대신에 DataBindingUtil.setContentView()를 이용해서 layout xml을 이어줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;DatabindingActivityBinding &lt;span style=&quot;color:#9876aa;&quot;&gt;binding&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;protected void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onCreate&lt;/span&gt;(&lt;span style=&quot;color:#bbb529;&quot;&gt;@Nullable &lt;/span&gt;Bundle savedInstanceState) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.onCreate(savedInstanceState)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;binding &lt;/span&gt;= DataBindingUtil.&lt;span style=&quot;font-style:italic;&quot;&gt;setContentView&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;this, &lt;/span&gt;R.layout.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;databinding_activity&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;binding&lt;/span&gt;.setActivity(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;xml의 파일이름을 기준으로 XXXBinding 클래스가 새로 생성됩니다.&lt;/p&gt;&lt;p&gt;여기서는 xml의 이름이 databinding_activity.xml 이기때문에 자동으로 DatabindingActivityBinding 클래스가 새로 생성되었습니다.&lt;/p&gt;&lt;p&gt;Binding클래스 이름의 생성은 파스칼표기법 기준으로 변경됩니다.&lt;/p&gt;&lt;p&gt;예를들어 ted_park_activity.xml 파일은 TedParkActivityBinding 클래스를 생성시킵니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;View를 사용하고자 할때는 binding변수에서 아래와 같이 사용할 수 있습니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 702px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/26689B4258A95DBA0F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F26689B4258A95DBA0F&quot; width=&quot;702&quot; height=&quot;190&quot; filename=&quot;그림1.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;View의 이름은 카멜표기법 기준으로 변경됩니다.&lt;/p&gt;&lt;p&gt;@+id/tv_text_name 의 뷰는 tvTextName으로 이름이 변경되어 사용할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(255, 0, 0);&quot;&gt;Click Event&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용자가 어떤 버튼을 클릭하면 아래 함수를 실행하도록 하려고 합니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onButtonClick&lt;/span&gt;(View view){&lt;br /&gt;    Toast.&lt;span style=&quot;font-style:italic;&quot;&gt;makeText&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;this,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;Button Click&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;Toast.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;LENGTH_SHORT&lt;/span&gt;).show()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;기본&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;버튼에 setOnClickListener()를 달아서 클릭이벤트를 받아주도록 할것 입니다.&amp;nbsp;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#808080;&quot;&gt;//btnSample.setOnClickListener(this);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;btnSample&lt;/span&gt;.setOnClickListener(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;View.OnClickListener() {&lt;br /&gt;    &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onClick&lt;/span&gt;(View view) {&lt;br /&gt;                onButtonClick(view)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;})&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;setOnClickListener(this)를 하셨다면 implements View.OnClickListener 를 하셔서 onButtonClick()함수를 호출 하셨을겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;버터나이프&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;버터나이프에서는 @OnClick(R.id.xxx) 만 함수에 넣어주면 됩니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@OnClick&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;btnSample&lt;/span&gt;)&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onButtonClick&lt;/span&gt;(View view) {&lt;br /&gt;    Toast.&lt;span style=&quot;font-style:italic;&quot;&gt;makeText&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;this, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;Button Click&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Toast.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;LENGTH_SHORT&lt;/span&gt;).show()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;div&gt;정말 간단합니다.&lt;/div&gt;&lt;div&gt;버터나이프를 왜 사용해야하는지에 대한 여러가지 이유중에 하나이기도 합니다.&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;데이터바인딩&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;데이터바인딩은 xml에서 클릭되면 실행하고자하는 함수를 지정해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;Button&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/btnSample&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:onClick=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{activity::onButtonClick}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;button&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;위에서는 android:onClick에서 activity라는 곳에 있는 onButtonClick()을 실행하도록 설정 해두었습니다.&lt;/p&gt;&lt;p&gt;여기에서 activity라는것은 xml에서 선언해둔 변수입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;layout &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xmlns:&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;data&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;variable&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;activity&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;type=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;gun0912.databinding.compare.databinding.DataBindingActivity&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;/data&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;xml에서 &amp;lt;data&amp;gt;태그를 이용해서 그안에 각각 사용하고자하는 변수를 &amp;lt;variable&amp;gt;로 정의해주면 사용 할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;DatabindingActivityBinding &lt;span style=&quot;color:#9876aa;&quot;&gt;binding&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;protected void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onCreate&lt;/span&gt;(&lt;span style=&quot;color:#bbb529;&quot;&gt;@Nullable &lt;/span&gt;Bundle savedInstanceState) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.onCreate(savedInstanceState)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;binding &lt;/span&gt;= DataBindingUtil.&lt;span style=&quot;font-style:italic;&quot;&gt;setContentView&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;this, &lt;/span&gt;R.layout.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;databinding_activity&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;binding&lt;/span&gt;.setActivity(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Java파일에서는 이 변수가 어떤값을 넣어줄건지 지정해주어야 합니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;setActivity(this)가 activity라는 변수를 이 Class로 지정하겠다는 의미인 것입니다.&lt;/p&gt;&lt;p&gt;setActivity()함수 또한 자동으로 생성된 함수입니다.&lt;/p&gt;&lt;p&gt;우리가 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;xml에서 aa라는 변수를 만들었다면 자동으로 binding.setAA()함수가 생성&lt;/span&gt;됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;MVP패턴을 사용하신다면 presenter를, MVVM패턴을 사용하신다면 ViewModel를 활용해서 클릭이벤트에 맞는 동작을 수행하도록 지정하면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;함수 이름을 지정할때 기존에는 @{activity.함수이름()} 으로 해도 문제가 없었지만 언젠가부터 이 방법은 deprecated되었다고 나오며 @{activity::함수이름()}으로 사용하도록 안내하고 있습니다.&lt;/p&gt;&lt;p&gt;물론 activity.함수이름()으로 사용해도 문제가 없으나 Google의 공식문서에서도 변수이름::함수이름() 으로 나와있으니 가이드를 따라서 작성하는것이 좋을것 같습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;RecyclerView 리스트&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 535px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2443564D58A963A908&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2443564D58A963A908&quot; width=&quot;535&quot; height=&quot;380&quot; filename=&quot;그림2.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;RecyclerView를 이용해서 이러한 리스트목록을 만드는 작업을 해보겠습니다.&lt;/p&gt;&lt;p&gt;사용자의 사진,이름,나이로 구성되어있는 화면입니다.&lt;/p&gt;&lt;p&gt;이 글을 읽는 여러분들은 화면만 봐도 레이아웃 구성을 어떻게 가져가야 할지 잘 아실겁니다.&lt;/p&gt;&lt;p&gt;각각의 item View로 쓰일 layout에서 1개의 ImageView와 2개의 TextView으로 레이아웃을 구성해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xml version=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;1.0&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;encoding=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;?&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;LinearLayout&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xmlns:&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:orientation=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;horizontal&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:padding=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/list_item_container_padding&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:gravity=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;center_vertical&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;gun0912.databinding.common.view.CircleImageView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/list_item_avatar_size&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/list_item_avatar_size&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/ivProfile&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;LinearLayout&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginLeft=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/list_item_container_padding&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:orientation=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;vertical&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/tvName&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/tvAge&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginTop=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/list_item_text_margin&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;/LinearLayout&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/LinearLayout&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또한 이 리스트에서 쓰일 사용자 User 클래스도 생성해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;User {&lt;br /&gt;&lt;br /&gt;    String &lt;span style=&quot;color:#9876aa;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    int &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;String &lt;span style=&quot;color:#9876aa;&quot;&gt;imgUrl&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    public &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;User&lt;/span&gt;(String name&lt;span style=&quot;color:#cc7832;&quot;&gt;,int &lt;/span&gt;age&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;String imgUrl){&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;name&lt;/span&gt;=name&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;age&lt;/span&gt;=age&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;imgUrl&lt;/span&gt;=imgUrl&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public &lt;/span&gt;String &lt;span style=&quot;color:#ffc66d;&quot;&gt;getName&lt;/span&gt;() {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setName&lt;/span&gt;(String name) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;name &lt;/span&gt;= name&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public int &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;getAge&lt;/span&gt;() {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setAge&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;age) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;age &lt;/span&gt;= age&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public &lt;/span&gt;String &lt;span style=&quot;color:#ffc66d;&quot;&gt;getImgUrl&lt;/span&gt;() {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;imgUrl&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setImgUrl&lt;/span&gt;(String imgUrl) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;imgUrl &lt;/span&gt;= imgUrl&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;실제로는 서버에서 이 사용자의 목록을 받아오겠지만 여기서는 샘플 데이터를 생성해서 활용하도록 할 것입니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;List&amp;lt;User&amp;gt; users = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ArrayList()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;users.add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;User(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;Ted&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;https://t1.daumcdn.net/cfile/tistory/251F6B4C558E627E26&quot;&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;users.add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;User(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;Jane&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;http://image.celebtide.com/celeb/new/ve/279_ve_1452259300.jpg&quot;&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;users.add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;User(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;Paul&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;http://res.heraldm.com/content/image/2013/12/01/20131201000224_0.jpg&quot;&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;users.add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;User(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;Ailee&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;25&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;https://t1.daumcdn.net/cfile/tistory/194599374F7049A901&quot;&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;ViewHolder&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;각각의 item view를 보여주기위해서 ViewHolder에서 View를 만들어주는 작업을 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;기본&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;UserViewHolder &lt;span style=&quot;color:#cc7832;&quot;&gt;extends &lt;/span&gt;RecyclerView.ViewHolder {&lt;br /&gt;&lt;br /&gt;    TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvName&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvAge&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;ImageView &lt;span style=&quot;color:#9876aa;&quot;&gt;ivProfile&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    public &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;UserViewHolder&lt;/span&gt;(View itemView) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;(itemView)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tvName &lt;/span&gt;= (TextView) itemView.findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvName&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tvAge &lt;/span&gt;= (TextView) itemView.findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvAge&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;ivProfile &lt;/span&gt;= (ImageView) itemView.findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ivProfile&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;버터나이프&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;UserViewHolder &lt;span style=&quot;color:#cc7832;&quot;&gt;extends &lt;/span&gt;RecyclerView.ViewHolder {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#bbb529;&quot;&gt;@BindView&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvName&lt;/span&gt;)&lt;br /&gt;    TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvName&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindView&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tvAge&lt;/span&gt;)&lt;br /&gt;    TextView &lt;span style=&quot;color:#9876aa;&quot;&gt;tvAge&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindView&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ivProfile&lt;/span&gt;)&lt;br /&gt;    ImageView &lt;span style=&quot;color:#9876aa;&quot;&gt;ivProfile&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    public &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;UserViewHolder&lt;/span&gt;(View itemView) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;(itemView)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;ButterKnife.&lt;span style=&quot;font-style:italic;&quot;&gt;bind&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;this,&lt;/span&gt;itemView)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;데이터바인딩&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;UserViewHolder &lt;span style=&quot;color:#cc7832;&quot;&gt;extends &lt;/span&gt;RecyclerView.ViewHolder {&lt;br /&gt;&lt;br /&gt;    DatabindingItemBinding &lt;span style=&quot;color:#9876aa;&quot;&gt;binding&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    public &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;UserViewHolder&lt;/span&gt;(View itemView) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;(itemView)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;binding &lt;/span&gt;= DataBindingUtil.&lt;span style=&quot;font-style:italic;&quot;&gt;bind&lt;/span&gt;(itemView)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Item세팅&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;onBindView()에서 각각의 position에 맞는 User클래스의 내용에 따라 뷰의 내용을 넣어주는 작업을 해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;기본 / 버터나이프&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onBindView&lt;/span&gt;(UserViewHolder holder&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;position) {&lt;br /&gt;&lt;br /&gt;    User user = getItem(position)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;String name = user.getName()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;holder.&lt;span style=&quot;color:#9876aa;&quot;&gt;tvName&lt;/span&gt;.setText(name)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    int &lt;/span&gt;age = user.getAge()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;holder.&lt;span style=&quot;color:#9876aa;&quot;&gt;tvAge&lt;/span&gt;.setText(Integer.&lt;span style=&quot;font-style:italic;&quot;&gt;toString&lt;/span&gt;(age))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;String imgUrl=user.getImgUrl()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;ImageUtil.&lt;span style=&quot;font-style:italic;&quot;&gt;loadImage&lt;/span&gt;(holder.&lt;span style=&quot;color:#9876aa;&quot;&gt;ivProfile&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;imgUrl&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;ContextCompat.&lt;span style=&quot;font-style:italic;&quot;&gt;getDrawable&lt;/span&gt;(getContext()&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;R.drawable.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;no_pic&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이미지를 로딩할때는 아래와 같이 로딩할 것입니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;ImageUtil {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public static void &lt;/span&gt;&lt;span style=&quot;background-color:#344134;&quot;&gt;loadImage&lt;/span&gt;(ImageView imageView&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;String url&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Drawable errorDrawable) {&lt;br /&gt;        Glide.&lt;span style=&quot;font-style:italic;&quot;&gt;with&lt;/span&gt;(imageView.getContext()).load(url).error(errorDrawable).into(imageView)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;데이터바인딩&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onBindView&lt;/span&gt;(UserViewHolder holder&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;position) {&lt;br /&gt;&lt;br /&gt;    User user = getItem(position)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;holder.&lt;span style=&quot;color:#9876aa;&quot;&gt;binding&lt;/span&gt;.setUser(user)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;원래의 기본이나 버터나이프에서는 각각 holder의 View에 사용자 정보를 넣어주는 작업을 해주었지만 데이터바인딩에서는 그럴 필요가 없습니다.&lt;/p&gt;&lt;p&gt;setUser()라는 함수를 보고 유추해 본다면, xml의 어딘가에서 user라는 변수를 만들어주었고 그 변수를 setUser()를 통해서 할당해준다는것을 아실겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xml version=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;1.0&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;encoding=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;?&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;layout&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xmlns:&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xmlns:&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;http://schemas.android.com/apk/res-auto&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;data&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;variable&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;user&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;type=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;gun0912.databinding.common.model.User&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;/data&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;onBindView()에서 값을 넣어주는대신에 데이터바인딩에서는 xml에서 값을 넣어줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/tvName&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{user.name}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/tvAge&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginTop=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/list_item_text_margin&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{Integer.toString(user.age)}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;android:text에 @{user.필드이름} 을 넣어주는것만으로 user의 정보를 가져와서 다시 TextView에 넣어주는 작업을 해줄 필요가 없는 것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;@BindingAdapter&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그런데 여기서 의문이 생깁니다.&lt;/p&gt;&lt;p&gt;User정보중에 imgUrl이라는 필드는 'http://xxx/xxx.jpg' 처럼 이미지가 저장되어있는 주소값으로 되어있습니다.&lt;/p&gt;&lt;p&gt;이걸 그냥 TextView에서 넣는다면 이미지 url만 출력되는 원하지 않는 결과를 볼것입니다.&lt;/p&gt;&lt;p&gt;이럴때 @BindingAdapter를 이용해주면 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저 사용된 방식부터 살펴보겠습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;gun0912.databinding.common.view.CircleImageView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/ivProfile&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/list_item_avatar_size&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/list_item_avatar_size&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:error=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{@drawable/no_pic}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:imageUrl=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{user.imgUrl}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용자의 이미지url을 app:imageUrl에 넣어주고, 오류가 발생했을때의 이미지 drawable을 app:error에 넣어줍니다.&lt;/p&gt;&lt;p&gt;이렇게 사용할 수 있는것은 아래와 같이 @BindingAdapter를 미리 만들어 두었기 때문입니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindingAdapter&lt;/span&gt;({&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;bind:imageUrl&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;bind:error&quot;&lt;/span&gt;})&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public static void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;loadImage&lt;/span&gt;(ImageView imageView&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;String url&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Drawable errorDrawable) {&lt;br /&gt;    ImageUtil.&lt;span style=&quot;font-style:italic;&quot;&gt;loadImage&lt;/span&gt;(imageView&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;url&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;errorDrawable)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;여기서 bind:imageUrl, bind:error로 만들어주었기때문에 xml에서 이걸 이용해서 값을 넣어 줄 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;@BindingAdapter응용&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;@BindingAdapter를 잘 응용하면 유용한 기능들을 소스코드를 줄이면서 사용할 수 있습니다.&lt;/p&gt;&lt;p&gt;커스텀폰트를 보여주고자 할때 사용하는 라이브러리중 제일 유명한 &lt;a href=&quot;https://github.com/chrisjenx/Calligraphy&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Calligraphy&lt;/a&gt;라는 라이브러리가 있습니다.&lt;/p&gt;&lt;p&gt;@BindingAdapter를 이용해서 라이브러리사용없이 똑같은 기능을 구현할 수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindingAdapter&lt;/span&gt;({&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;bind:font&quot;&lt;/span&gt;})&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public static void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setFont&lt;/span&gt;(TextView textView&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;String fontName) {&lt;br /&gt;    textView.setTypeface(Typeface.&lt;span style=&quot;font-style:italic;&quot;&gt;createFromAsset&lt;/span&gt;(textView.getContext().getAssets()&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;fonts/&quot; &lt;/span&gt;+ fontName))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:font=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{`Source-Sans-Pro-Regular.ttf`}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아마 기존에 Calligraphy 라이브러리를 사용해보신분들은 이 방법이 얼마나 유용한지 이해 하실 수 있을겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;물론 저는 커스텀폰트를 사용하고자 할때는 Typekit을 이용합니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/10&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드]커스텀 폰트 쉽게 적용하는 방법 - Typekit&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 24pt;&quot;&gt;@BindingConversion&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;만약 사용자 정보중에 Date타입의 timeDate라는 필드가 있다고 가정을 해보겠습니다.&lt;/p&gt;&lt;p&gt;이 정보를 TextView에서 1900.01.01&amp;nbsp;과 같은 방식으로 보여주고자 한다면 어떻게하면 좋을까요?&lt;/p&gt;&lt;p&gt;Java소스코드에서 Date필드를 가져온뒤, SimpleDateFormat을 이용해서 Date-&amp;gt;Text로 날짜형식 변환을 해주고, TextView에 해당 값을 넣어줄겁니다.&lt;/p&gt;&lt;p&gt;하지만 @BindingConversion을 이용한다면 간단합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindingConversion&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public static &lt;/span&gt;String &lt;span style=&quot;color:#ffc66d;&quot;&gt;convertDateToDisplayedText&lt;/span&gt;(Date date) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;return new &lt;/span&gt;SimpleDateFormat(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;yyyy.MM.dd&quot;&lt;/span&gt;).format(date)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@+id/tvUserTime&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{user.timeDate}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;@BindingConversion에서 Date타입이 들어오면 이를 String으로 변경해서 리턴해주도록 만들어 두었기때문에 xml에서 text에 Date타입의 필드를 넣어주면 알아서 변경되서 값이 변경됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;@BindingConversion 응용&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;값에따라서 View를 보여주거나 숨기고 싶은경우 아래와 같이 해줄 수도 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@BindingConversion&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public static int &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;convertBooleanToVisibility&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;boolean &lt;/span&gt;visible) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;visible ? View.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;VISIBLE &lt;/span&gt;: View.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;GONE&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:visibility=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{user.age &amp;gt; 20}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;RelativeLayout&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:visibility=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{user.loaded}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;android:visibility 는 원래 int값이 들어가야하지만 true/false에 따라서 이를 맞게 표시하도록 설정해주면 xml에서 편하게 사용할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 24pt;&quot;&gt;식언어&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;xml에서 사용할 수 있는 식언어는 아래와 같습니다.&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;수학 + - / * %&lt;/li&gt;&lt;li&gt;문자열 연결 +&lt;/li&gt;&lt;li&gt;논리 &amp;amp;&amp;amp; ||&lt;/li&gt;&lt;li&gt;이항 &amp;amp; | ^&lt;/li&gt;&lt;li&gt;단항 + - ! ~&lt;/li&gt;&lt;li&gt;시프트 &amp;gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; &amp;lt;&amp;lt;&lt;/li&gt;&lt;li&gt;비교 == &amp;gt; &amp;lt; &amp;gt;= &amp;lt;=&lt;/li&gt;&lt;li&gt;instanceof&lt;/li&gt;&lt;li&gt;그룹화 ()&lt;/li&gt;&lt;li&gt;리터럴 - 문자, 문자열, 숫자, null&lt;/li&gt;&lt;li&gt;형변환&lt;/li&gt;&lt;li&gt;메서드 호출&lt;/li&gt;&lt;li&gt;필드 액세스&lt;/li&gt;&lt;li&gt;배열 액세스 []&lt;/li&gt;&lt;li&gt;삼항 연산자 ?:&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{String.valueOf(index+1)}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:visibility=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{user.age&amp;gt;20 ? View.VISIBLE : View.GONE}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:transitionName=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;'@{&quot;image_&quot;+id}'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 24pt;&quot;&gt;Include&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래와 같은 화면구성에서 3개의 뷰는 하나의 layout을 재사용해서 사용할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 533px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2541D13358A96DE502&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2541D13358A96DE502&quot; width=&quot;533&quot; height=&quot;288&quot; filename=&quot;그림3.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;layout의 구조는 같지만 안의 내용이 달라지기때문에 이럴때 우리는 보통 CustomView를 만들어서 attribute에 해당 값을 넣어서 보여주는 방식을 이용하곤 했습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/38&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드]CustomView를 만들어서 재사용하기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만 데이터바인딩과 include를 잘 활용한다면 우리는 커스텀뷰를 만들지않고도 이를 구성할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;재사용될 xml layout&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;layout&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xmlns:&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;data&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;variable &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;count&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;type=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;int&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;variable &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;title&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;type=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;String&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;/data&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;LinearLayout&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:gravity=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;center&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:orientation=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;vertical&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@style/CustomText_Subhead&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{Integer.toString(count)}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:textStyle=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;bold&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@style/CustomText_Body&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{title}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@color/txt_midiumgray&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;/LinearLayout&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/layout&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;이 layout에서는 count와 title을 변수로 받아올것이고 이를 TextView에 넣어주는 작업을 해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;LinearLayout&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:orientation=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;horizontal&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;include&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;layout=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@layout/sns_counter&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;0dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_weight=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;1&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:count=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{user.postCount}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:title=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{@string/post}&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;include&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;layout=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@layout/sns_counter&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;0dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_weight=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;1&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:count=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{user.followerCount}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:title=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{@string/follower}&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;include&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;layout=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@layout/sns_counter&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;0dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_weight=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;1&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:count=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{user.followingCount}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:title=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{@string/following}&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/LinearLayout&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;위의 layout을 &amp;lt;include&amp;gt; 태그로 재사용해주면서 위에서 선언해주었던 count,title 변수값을 넣어주면 됩니다.&lt;/p&gt;&lt;p&gt;이러한 방식을 이용해서 CustomView로 사용하던것도 얼마든지 간단하게 include로 재사용 할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 24pt;&quot;&gt;Observable&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 536px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/226E535058A9742522&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F226E535058A9742522&quot; width=&quot;536&quot; height=&quot;287&quot; filename=&quot;그림4.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 화면에서 데이터값이 변경되면 View도 갱신하려면 어떻게 해주어야 할까요&lt;/p&gt;&lt;p&gt;아래 방법이 일반적인 방법입니다.&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot;&gt;&lt;li&gt;데이터 가져오기&lt;/li&gt;&lt;li&gt;TextView에 setText()&lt;/li&gt;&lt;li&gt;데이터 변경됨&lt;/li&gt;&lt;li&gt;변경된 데이터 가져오기&lt;/li&gt;&lt;li&gt;TextView에 setText()&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만 Observable을 이용한다면, 한번 TextView에 setText()해준 이후에 값이 변경되면 알아서 변경된 내용으로 View를 업데이트 시켜줄 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Class를 정의할때 BaseObservable을 상속받습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;&lt;span style=&quot;background-color:#344134;&quot;&gt;User&lt;/span&gt; &lt;span style=&quot;color:#cc7832;&quot;&gt;extends &lt;/span&gt;BaseObservable {&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;getXXX()함수에는 @Bindable을, setXXX()함수에는 notifyPropertyChanged()함수를 추가해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;String &lt;span style=&quot;color:#9876aa;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Bindable&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public &lt;/span&gt;String &lt;span style=&quot;color:#ffc66d;&quot;&gt;getName&lt;/span&gt;() {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setName&lt;/span&gt;(String name) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;name &lt;/span&gt;= name&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;notifyPropertyChanged(BR.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;name&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이렇게 설정해주고 xml에서 android:text=&quot;@{user.name}&quot; 으로 넣어두면 사용자의 이름이 변경되면 알아서 해당 TextView의 내용도 변경되도록 할 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@style/CustomText_Body&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginTop=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@dimen/default_padding&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;@{user.name}&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:textStyle=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;bold&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;ObservableField&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;BaseObservable을 상속받아서 setXXX(), getXXX()함수를 만드는게 귀찮다면 ObservableField를 사용할 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;&lt;span style=&quot;background-color:#344134;&quot;&gt;User2&lt;/span&gt;  {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public final &lt;/span&gt;ObservableField&amp;lt;String&amp;gt; &lt;span style=&quot;color:#9876aa;&quot;&gt;name &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ObservableField&amp;lt;&amp;gt;()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    public final &lt;/span&gt;ObservableInt &lt;span style=&quot;color:#9876aa;&quot;&gt;postCount &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ObservableInt()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    public final &lt;/span&gt;ObservableBoolean &lt;span style=&quot;color:#9876aa;&quot;&gt;follow &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ObservableBoolean()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ObservableField로 사용할수 있는 타입은 아래와 같습니다.&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;ObservableField&lt;/li&gt;&lt;li&gt;ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble, ObservableParcelable&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;변수를 set, get 할때는 아래와 같이 사용해주면 됩니다.&lt;/div&gt;&lt;div&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;String name = user.name.get()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;user.&lt;span style=&quot;color:#9876aa;&quot;&gt;name&lt;/span&gt;.set(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;aa&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(255, 0, 0);&quot;&gt;응용&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금까지 설명드렸던 내용들을 잘 활용한다면 아래와 같은 동작을&amp;nbsp;간단하게&amp;nbsp;구성해줄 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 320px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2377183758A9762717&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2377183758A9762717&quot; width=&quot;320&quot; height=&quot;569&quot; filename=&quot;ezgif.com-video-to-gif.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot;&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;팔로우 버튼 클릭시, 팔로우 버튼 숨기기&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Progressbar 보이기&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;팔로우 완료시, 팔로워 숫자 +1 하기&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;변경된 팔로워 숫자를 TextView에 다시 setText()해주기&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Progressbar 숨기기&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;팔로우 완료되어있는 팔로잉 버튼 보이기&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이 과정을 소스코드로 만들었을대 어떻게 할지 잘 생각해보시고 데이터바인딩에서 xml로 어떻게 간단하게 해결했는지 살펴보시기 바랍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;지금까지 설명드렸던 예제들과 위의 응용 동작은 Github에서 샘플 프로젝트로 확인 해보실 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedDataBindingSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedDataBindingSample&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;(내용이 유용하셨다면 Github&amp;nbsp;오른쪽위의&amp;nbsp;[Star]버튼을 눌러주시면 감사하겠습니다&lt;/p&gt;&lt;p&gt;저에게는 별풍선 주시는 효과가 있어요!)&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;600&quot; width=&quot;600&quot; exif=&quot;{}&quot; id=&quot;tx_entry_51030_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/2625B4395917C42F09&quot; height=&quot;304&quot; title=&quot;더블클릭을 하시면 이미지를 수정할 수 있습니다&quot; style=&quot;width: 150px; height: 76px;&quot;&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(255, 0, 0);&quot;&gt;불편사항&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;데이터바인딩을 사용해보면서 몇가지 불편한 사항들이 있었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;물론 이러한 것들도 점점 개선될 것이라고 믿고 있습니다.&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;버터나이프에서 사용하는 Resource binding은 사용할 수 없다(@BindString, @BindDimen, … )&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Android Studio 최신버전인데도 제대로 반영이 안된다&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;여러 군데에서 같은 변수이름의 @BindingAdapter 을 사용해도 오류가 없다고 한다&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;인코딩 문제때문인지 xml에서 ‘&amp;amp;&amp;amp;’ 대신 ‘&amp;amp;amp;&amp;amp;amp;’로 써야한다&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Java소스코드는 줄어들지만 xml소스코드는 늘어난다&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그럼에도 불구하고 데이터바인딩을 아주 좋습니다.&lt;/p&gt;&lt;p&gt;이제는 버터나이프대신 데이터바인딩을 사용해서 프로젝트를 만들어 보세요&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Goodbye 버터나이프 Hello 데이터바인딩&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 113px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2226043558A9784216&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2226043558A9784216&quot; width=&quot;200&quot; height=&quot;113&quot; filename=&quot;goodbye.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 200px; height: 113px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 개발자끼리 소통하기위한 오픈채팅방을 만들었습니다.&lt;/p&gt;&lt;p&gt;안드로이드 관련 Q&amp;amp;A및 팁을 공유하는 곳입니다.&lt;/p&gt;&lt;p&gt;관심있으신분들은 참여해보세요.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://open.kakao.com/o/g8rSGB&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://open.kakao.com/o/g8rSGB&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/71</guid>
      <comments>https://gun0912.tistory.com/71#entry71comment</comments>
      <pubDate>Sun, 19 Feb 2017 20:05:35 +0900</pubDate>
    </item>
    <item>
      <title>English Article</title>
      <link>https://gun0912.tistory.com/70</link>
      <description>&lt;p&gt;Now english article&amp;nbsp;moved to medium.&lt;/p&gt;&lt;p&gt;You can read article at medium.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://medium.com/tedpark-developer&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://medium.com/tedpark-developer&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (English)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/70</guid>
      <comments>https://gun0912.tistory.com/70#entry70comment</comments>
      <pubDate>Thu, 9 Feb 2017 12:28:40 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]Stetho로 DB/SharedPreference값,네트워크상태등 앱 디버깅하기</title>
      <link>https://gun0912.tistory.com/69</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 319px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/276A4A4D585379ED11&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F276A4A4D585379ED11&quot; width=&quot;319&quot; height=&quot;170&quot; filename=&quot;debug.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;디버깅(Debugging)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;앱을 개발하면서 앱안에서의 변수값, Lifecycle순서, SharedPreference값, DB값등을 알고 싶은경우가 많이 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;그럴때마다 우리는 Logcat을 이용해서 Log를 찍어보거나 BreakPoint를 이용한 디버깅을 수행합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/263F83355850F5E826&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F263F83355850F5E826&quot; width=&quot;820&quot; height=&quot;178&quot; filename=&quot;Screenshot at 12월 14 14-27-29.png&quot; filemime=&quot;image/jpeg&quot; original=&quot;yes&quot;/&gt;&lt;span class=&quot;cap1&quot; style=&quot;display: block; max-width:100%; &quot;&gt;(Logcat)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 514px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/216AFE395850F5D938&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F216AFE395850F5D938&quot; width=&quot;514&quot; height=&quot;264&quot; filename=&quot;22-conditionalbreakpoint.gif&quot; filemime=&quot;image/gif&quot; original=&quot;yes&quot;/&gt;&lt;span class=&quot;cap1&quot; style=&quot;display: block; max-width:100%; &quot;&gt;(Break Point)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;하지만 이러한 방법에는 한계가 있으며 불편하기도 합니다&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(189, 189, 189); background-color: rgb(255, 255, 255);&quot;&gt;(사실 더 좋은 방법을 모를때는 이 방법이 최선이라고 생각해서 불편함을 느끼지 못할수도 있습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(189, 189, 189); background-color: rgb(255, 255, 255);&quot;&gt;'불편 했었다'는건 그보다 더 좋은 기능을 알게된뒤에 드는 생각이죠..)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Facebook에서 내놓은 Stetho를 이용하면 우리는 좀더 다양한 기능과 편리한 방법으로 디버깅을 수행할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 36pt;&quot;&gt;Stetho&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/265A603C58537D8922&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F265A603C58537D8922&quot; width=&quot;820&quot; height=&quot;359&quot; filename=&quot;Screenshot at 12월 16 14-36-57.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Stetho는 Facebook에서 만든 안드로이드 개발을 위한 디버깅 플랫폼&lt;/span&gt;입니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;크롬(Chrome)브라우저의 developer tool을 활용해서 우리는 브라우저에서 앱의 상태나 화면구조 db, SharedPreference 등 다양한 값들을 살펴보고 수정도 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://facebook.github.io/stetho/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span&gt;소개페이지&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/facebook/stetho&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span&gt;Github&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;기능 소개&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Stetho로 할수있는 것들에 대해서 먼저 간략하게 소개해드린뒤 실제 적용하면서 확인할 수 있었던 것들에 대해서 자세히 살펴보도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1. 네트워크&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;p&gt;유틸성앱이 아닌이상 Retrofit이나 URLConnection을 사용해서 API서버와 네트워크 통신을 하고 계실겁니다.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;이러한 통신에서의 Response값이나 Header값등등&amp;nbsp;네트워크의 진행상황에 대해서 궁금한 경우가 많습니다.&lt;/p&gt;&lt;p&gt;Stetho는 해당앱의 각각의 네트워크 통신의 정보를 상세하게 살펴볼 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2. &lt;/span&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;DB / SharedPreference / 기타 저장된 값&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;p&gt;네 맞습니다. SQLite를 이용해서 DB에 저장하는경우 에뮬레이터는 DDMS로 해당 DB내용을 볼수 있지만 실기기는 그럴수 없었습니다..&lt;/p&gt;&lt;p&gt;SharedPreference나 쿠키,기타 값들은 아예 알수있는 방법이 없기때문에 항상 로그로 해당 값들을 찍어볼 수 밖에 없었습니다.&lt;/p&gt;&lt;p&gt;Stetho를 이용하면 해당 값들을 조회할수 있을뿐만 아니라 DB에 쿼리를 날려볼 수도 있고 값을 수정할 수도 있습니다.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3. &lt;/span&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;화면 레이아웃&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;xml이 실제 앱에서 화면으로 보여질때 어떠한 값들과 세팅들이 되어서 보여지는지 볼 수 있습니다.&lt;/p&gt;&lt;p&gt;또한 특정 View를 선택하면 해당 View가 휴대폰 화면에서 어디에 위치되어있는지 표시해서 보여주기도 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4. 콘솔&lt;/span&gt;&lt;/p&gt;&lt;p&gt;콘솔창에서 명령어 입력이 가능합니다.&lt;/p&gt;&lt;p&gt;앱안에서의 Resource값들을 가져오거나 앱에서 Toast창을 띄울수도 있습니다.&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;5. dumpapp&lt;/span&gt;&lt;/p&gt;&lt;p&gt;UI방식이 아닌 커맨드라인 입력방식으로 동작을 수행할수 있으며 값들을 조회하고 수정할수도 있고 미리 정의해둔 커스텀값들을 활용할 수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;설정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;Gradle&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;compile &lt;span style=&quot;color:#6a8759;&quot;&gt;'com.facebook.stetho:stetho:1.4.1'&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;버전은 현재시점에서 최신버전으로 설정해주시면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;만약 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;네트워크 분석기능을 사용하시려면 사용하시는 네트워크 방식에 따라서 추가로 gradle에&amp;nbsp;추가&lt;/span&gt;해주셔야 합니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;compile &lt;span style=&quot;color:#6a8759;&quot;&gt;'com.facebook.stetho:stetho-okhttp:1.4.1'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// or&lt;br /&gt;&lt;/span&gt;compile &lt;span style=&quot;color:#6a8759;&quot;&gt;'com.facebook.stetho:stetho-okhttp3:1.4.1'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// or&lt;br /&gt;&lt;/span&gt;compile &lt;span style=&quot;color:#6a8759;&quot;&gt;'com.facebook.stetho:stetho-urlconnection:1.4.1'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;저는 okhttp 3이전버전을 사용하고 있어서&amp;nbsp;'com.facebook.stetho:stetho-okhttp:1.4.1' 만을 추가해주었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;만약&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt; 콘솔을 이용한 명령어 입력기능을 사용하시려면 아래 라이브러리도 gradle에 추가&lt;/span&gt;해주셔야 합니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;compile &lt;span style=&quot;color:#6a8759;&quot;&gt;'com.facebook.stetho:stetho-js-rhino:1.4.1'&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;Setup&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Application클래스의 onCreate()에 아래 코드 한줄만 넣어주면 됩니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;Stetho.&lt;span style=&quot;font-style:italic;&quot;&gt;initializeWithDefaults&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;highlight&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-variant-numeric: inherit; font-stretch: inherit; font-size: 12px; line-height: inherit; font-family: monospace; vertical-align: baseline; background: rgb(240, 240, 240); color: rgb(29, 29, 29);&quot;&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot; style=&quot;margin: 1em 0px; padding: 12px; border-width: 0px 0px 0px 4px; border-top-style: initial; border-right-style: initial; border-bottom-style: initial; border-left-style: solid; border-top-color: initial; border-right-color: initial; border-bottom-color: initial; border-left-color: rgb(70, 162, 74); border-image: initial; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; vertical-align: baseline; color: rgb(0, 0, 0); display: block; overflow-x: auto; background: rgb(240, 240, 240); text-size-adjust: none;&quot;&gt;&lt;span class=&quot;kd&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;hljs-class&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nc&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(68, 85, 136);&quot;&gt;&lt;span class=&quot;hljs-class&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;&lt;span class=&quot;hljs-title&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(136, 0, 0);&quot;&gt;MyApplication&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hljs-class&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kd&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;hljs-class&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;&lt;span class=&quot;hljs-class&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;&lt;span class=&quot;hljs-title&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(136, 0, 0);&quot;&gt;Application&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hljs-class&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;hljs-function&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(68, 85, 136);&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;hljs-function&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(153, 0, 0);&quot;&gt;&lt;span class=&quot;hljs-function&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;&lt;span class=&quot;hljs-title&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(136, 0, 0);&quot;&gt;onCreate&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;hljs-function&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: teal;&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;Stetho&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: teal;&quot;&gt;initializeWithDefaults&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline;&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;기본설정값 외에 커스텀하게 지정하고 싶은경우 좀더 다양한 방법으로 설정할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;Network&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;네트워크 분석기능을 사용하시는경우 네트워크 설정 부분에 아래 코드들을 입력해주어야 합니다&lt;/p&gt;
&lt;div&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// OkHttp 2.x 버전&lt;br /&gt;&lt;/span&gt;OkHttpClient client = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;OkHttpClient()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;client.networkInterceptors().add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;StethoInterceptor())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// OkHttp 3.x 버전&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;OkHttpClient.Builder()&lt;br /&gt;        .addNetworkInterceptor(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;StethoInterceptor())&lt;br /&gt;        .build()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;HttpURLConnection을 사용하는경우 따로 설정 방법이 존재하지만 대부분 네트워크통신을 하신다면 Retrofit을 사용하며 Okhttp를 사용하실거라 생각하기에 생략하도록 하겠습니다&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;혹시 HttpURLConnection의 설정방법이 궁금하시면 Stetho홈페이지에서 확인해보실 수 있습니다&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;적용예제&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 설정을 완료하신뒤 컴파일하고 앱을&amp;nbsp;실행시킵니다.&lt;/p&gt;&lt;p&gt;에뮬레이터든 실제 기기이든 상관없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 601px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2337D93F5852096A1D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2337D93F5852096A1D&quot; width=&quot;601&quot; height=&quot;351&quot; filename=&quot;Screenshot at 12월 15 11-40-10.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;크롬 브라우저에서 &lt;a href=&quot;chrome://inspect&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;chrome://inspect&lt;/a&gt;&amp;nbsp;를 입력하면 위와같은 화면을 볼수 있고 여기서 inspect를 클릭합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 722px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/220441465852093242&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F220441465852093242&quot; width=&quot;722&quot; height=&quot;275&quot; filename=&quot;Screenshot at 12월 15 12-08-23.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Developer Tools창이 우리를 반겨줍니다.&lt;/p&gt;&lt;p&gt;보통 브라우저에서 웹페이지를 개발자도구로 열었을때 볼수있는 창입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;네트워크&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2407724F58520BFA23&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2407724F58520BFA23&quot; width=&quot;820&quot; height=&quot;321&quot; filename=&quot;Screenshot at 12월 15 12-18-30.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;API 서버에 요청하고난 결과값이나 걸린시간, Header정보 등을 로그로 찍어서 확인해볼 필요가 없습니다.&lt;/p&gt;&lt;p&gt;앱안에서 이루어지는 Network 목록을 볼 수 있습니다.&lt;/p&gt;&lt;p&gt;POST/GET/PUT/DELETE의 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Method와 Response status값, 요청에 걸린시간등 다양한 정보를 알 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/277C8D505853680E05&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F277C8D505853680E05&quot; width=&quot;820&quot; height=&quot;491&quot; filename=&quot;Screenshot at 12월 15 12-21-46_d.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;각각의 API요청을 선택하면 해당 요청정보에 대해서 좀더 상세하게 볼 수 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Header, Cookie값은 물론이고 해당 요청으로 받은 결과값도 자세히 살펴볼 수 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;더이상 &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Response의&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&amp;nbsp;J&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;son&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;값 로그찍지마세요!!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;DB / SharedPreference / 기타 저장된 값&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;DB값이나 SharedPreference도 로그 찍지 마세요!!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;DB&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2366274758536B5229&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2366274758536B5229&quot; width=&quot;820&quot; height=&quot;491&quot; filename=&quot;Screenshot at 12월 16 13-17-03.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;SQLite를 이용해서 db를 저장하고 있다면 이제 로그를 찍지 않아도 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;에뮬레이터뿐만 아니라 실제 기기에서도 테이블과 해당 row값들을 볼 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2363474358536C262C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2363474358536C262C&quot; width=&quot;820&quot; height=&quot;490&quot; filename=&quot;Screenshot at 12월 16 13-22-45.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Viewer의 기능뿐만 아니라&amp;nbsp;직접 쿼리문을 날릴수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;테스트 해본결과 Select뿐만 아니라 Update등의 수정권한 쿼리도 동작했습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;SharedPreference&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/245C664558536C7320&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F245C664558536C7320&quot; width=&quot;820&quot; height=&quot;492&quot; filename=&quot;Screenshot at 12월 16 13-24-06.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;SharedPreference에 저장하고 있는 key와 value를 조회할 수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/272D683D58536CBA2D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F272D683D58536CBA2D&quot; width=&quot;820&quot; height=&quot;497&quot; filename=&quot;Screenshot at 12월 16 13-25-06.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;DB와는 다르게 직접 SharedPreference값을 추가하거나 수정,삭제도 가능합니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;화면 레이아웃&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px; width: 820px; height: 503px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/272F264358520A1413&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F272F264358520A1413&quot; width=&quot;820&quot; height=&quot;503&quot; filename=&quot;Screenshot at 12월 15 12-11-53.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 820px; height: 503px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;xml구조 뿐만이 아니라 오른쪽에 해당 View의 설정된 값이나 id등 기타 정보들을 알수 있습니다.&lt;/p&gt;&lt;p&gt;또한 특정 View를 선택할경우 휴대폰의 화면에 아래와 같이 해당 View의 범위와 위치가 표시됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/230E764458520A4B17&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F230E764458520A4B17&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;KakaoTalk_Photo_2016-12-15-12-13-06_73.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 445px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2272054758520AC72B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2272054758520AC72B&quot; width=&quot;820&quot; height=&quot;187&quot; filename=&quot;Screenshot at 12월 15 12-14-39.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;오른쪽에서 해당 View위치나 padding, margin도 의도한대로 잘 설정되어있는지도 확인해볼수 있습니다.&lt;/p&gt;&lt;p&gt;xml에서 설정한대로 실제앱이 잘 나오지 않아서 애를 먹을때 활용하면 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;참고영상&lt;/b&gt;&lt;/p&gt;&lt;div class=&quot;tt-youtube-plugin&quot; style=&quot;text-align: left;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/EN60lzfv7po?rel=0&quot; width=&quot;560&quot; height=&quot;420&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;(https://medium.com/@jmarsican/effective-and-easy-apps-debugging-work-with-stetho-ac67954ac897#.6m6flvml0)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;콘솔&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/25724433585372F521&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F25724433585372F521&quot; width=&quot;820&quot; height=&quot;249&quot; filename=&quot;Screenshot at 12월 16 13-51-52.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;콘솔창에 js명령어를 입력할 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;(만약 오류가 발생하신다면 위의&lt;/span&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;&amp;nbsp;설정방법에 나와있는대로&lt;/span&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;&amp;nbsp;'com.facebook.stetho:stetho-js-rhino:1.4.1' 를 추가하&lt;/span&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;셨는지 확인해보시기 바랍니다.&lt;/span&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;.)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;위와같은 명령어를 입력하면 아래와 같이 앱안에서 동적으로 토스트를 띄워줄수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 444px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2354E8385853731106&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2354E8385853731106&quot; width=&quot;250&quot; height=&quot;444&quot; filename=&quot;KakaoTalk_Photo_2016-12-16-13-51-56_39.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 444px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;context.getResources().getString(R.string.app_name); 같은 명령어를 입력하면 string.xml의 app_name의 값이&amp;nbsp;출력된다고 하는데 저는 오류가 발생합니다..&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이부분은 왜그런지 한번 잘 살펴봐야 할것 같습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;context 혹은 context.getResources()같은 명령어들은 잘 나옵니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;Dumpapp&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 724px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/23185841585377621A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F23185841585377621A&quot; width=&quot;724&quot; height=&quot;412&quot; filename=&quot;dumpapp-prefs.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;솔직히 이 기능은 사용한적이 없어서 정확한 사용방법에 대해서는 잘 알지 못합니다...&lt;/p&gt;&lt;p&gt;명령어로 값들을 직접 확인해볼수 있고 수정도 할수 있으며&lt;/p&gt;&lt;p&gt;커스텀하게 만든 플러그인을 통해서 여러가지 활용할 수 있는 개념정도로만 알고 있습니다.&lt;/p&gt;&lt;p&gt;혹시 dumapp에 대해서 여러가지 방법으로 활용해보신분이 계시다면 댓글로 알려주세요&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr class=&quot;tx-hr-image-4&quot; style=&quot;background: url(//i1.daumcdn.net/deco/contents/horizontalrule/line08.gif?v=2) repeat-x scroll left; height: 15px; border:0; width:54px; margin:30px auto&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Stetho에서 제가 제일 유용하게 사용하는건 네트워크 결과값 확인/ DB값 확인 / SharedPreference값 확인 3가지 입니다.&lt;/p&gt;&lt;p&gt;이걸 사용하지 않았다면 저는 아마 계속 Logcat에 해당 값들을 로그찍어보고 있었을겁니다.&lt;/p&gt;&lt;p&gt;&lt;strike&gt;(사실 지금도 이런짓을 하고있긴합니다..)&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금까지는 Stetho를 몰라서 안썼지만 이제부터 여러분은 Stetho를 안쓸이유가 하나도 없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 445px; width: 445px; height: 250px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/242077455853784136&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F242077455853784136&quot; width=&quot;445&quot; height=&quot;250&quot; filename=&quot;b2049663c7953373bb0a200a04b2c6ea_yhofweNDK7xOq1yamThCgIrijANR.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 445px; height: 250px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;행복한 디버깅과 함께 행복한 개발로 행복한 서비스를 만드시기 바랍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;감사합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참고하면 좋은 관련블로그&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://code.facebook.com/posts/393927910787513/stetho-a-new-debugging-platform-for-android/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://code.facebook.com/posts/393927910787513/stetho-a-new-debugging-platform-for-android/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://code.tutsplus.com/tutorials/debugging-android-apps-with-facebooks-stetho--cms-24205&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://code.tutsplus.com/tutorials/debugging-android-apps-with-facebooks-stetho--cms-24205&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://medium.com/@jmarsican/effective-and-easy-apps-debugging-work-with-stetho-ac67954ac897#.sczt1ro7h&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://medium.com/@jmarsican/effective-and-easy-apps-debugging-work-with-stetho-ac67954ac897#.sczt1ro7h&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://medium.com/quick-mobile/stetho-a-debugging-bridge-for-android-applications-eacc139dfda7#.447lczshl&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://medium.com/quick-mobile/stetho-a-debugging-bridge-for-android-applications-eacc139dfda7#.447lczshl&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-right: 0px; margin-left: 0px; padding: 0px; line-height: 1.7; font-family: &amp;quot;나눔 고딕&amp;quot;, NanumGothic, &amp;quot;맑은 고딕&amp;quot;, &amp;quot;Malgun Gothic&amp;quot;; color: rgb(102, 102, 102); font-size: 14px;&quot;&gt;안드로이드 개발자끼리 소통하기위한 오픈채팅방을 만들었습니다.&lt;/p&gt;&lt;p style=&quot;margin-right: 0px; margin-left: 0px; padding: 0px; line-height: 1.7; font-family: &amp;quot;나눔 고딕&amp;quot;, NanumGothic, &amp;quot;맑은 고딕&amp;quot;, &amp;quot;Malgun Gothic&amp;quot;; color: rgb(102, 102, 102); font-size: 14px;&quot;&gt;안드로이드 관련 Q&amp;amp;A및 팁을 공유하는 곳입니다.&lt;/p&gt;&lt;p style=&quot;margin-right: 0px; margin-left: 0px; padding: 0px; line-height: 1.7; font-family: &amp;quot;나눔 고딕&amp;quot;, NanumGothic, &amp;quot;맑은 고딕&amp;quot;, &amp;quot;Malgun Gothic&amp;quot;; color: rgb(102, 102, 102); font-size: 14px;&quot;&gt;관심있으신분들은 참여해보세요.&lt;/p&gt;&lt;p style=&quot;margin-right: 0px; margin-left: 0px; padding: 0px; line-height: 1.7; font-family: &amp;quot;나눔 고딕&amp;quot;, NanumGothic, &amp;quot;맑은 고딕&amp;quot;, &amp;quot;Malgun Gothic&amp;quot;; color: rgb(102, 102, 102); font-size: 14px;&quot;&gt;&lt;a href=&quot;https://open.kakao.com/o/g8rSGB&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot; style=&quot;color: rgb(51, 51, 51);&quot;&gt;https://open.kakao.com/o/g8rSGB&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/69</guid>
      <comments>https://gun0912.tistory.com/69#entry69comment</comments>
      <pubDate>Fri, 16 Dec 2016 14:38:47 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]유용한 라이브러리 - TedBottomPicker(이미지 선택, Image Picker)</title>
      <link>https://gun0912.tistory.com/68</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 225px; width: 225px; height: 400px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/212D1049583FECDD1F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F212D1049583FECDD1F&quot; width=&quot;225&quot; height=&quot;400&quot; filename=&quot;screenshot1 (1).jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 225px; height: 400px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;저는 Google의 &lt;a href=&quot;https://material.google.com/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Material 디자인&lt;/a&gt;을 좋아합니다.&lt;/p&gt;&lt;p&gt;디자인과는 거리가 먼 개발자들에게 정말 많은 도움을 줍니다.&lt;/p&gt;&lt;p&gt;적당한 색상, 적당한 여백, 적당한 크기등등 구글이 연구하고 가지고 있는 노하우를 가이드라인으로 제시해주고&amp;nbsp;있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그중에서&amp;nbsp;&lt;a href=&quot;https://material.google.com/components/bottom-sheets.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Bottom Sheet&lt;/a&gt;는 제가 좋아하는 화면방식입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 239px; width: 239px; height: 400px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2122974B583FE0C81D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2122974B583FE0C81D&quot; width=&quot;239&quot; height=&quot;400&quot; filename=&quot;NS8W3.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 239px; height: 400px;&quot; original=&quot;yes&quot;/&gt;&lt;span class=&quot;cap1&quot; style=&quot;display: block; max-width:100%; width: 239px; height: 400px;;&quot;&gt;(Popup 방식)&lt;/span&gt;&lt;/span&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 225px; width: 225px; height: 400px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/224F9349583FE0AF0F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F224F9349583FE0AF0F&quot; width=&quot;225&quot; height=&quot;400&quot; filename=&quot;XRiy0.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 225px; height: 400px;&quot; original=&quot;yes&quot;/&gt;&lt;span class=&quot;cap1&quot; style=&quot;display: block; max-width:100%; width: 225px; height: 400px;;&quot;&gt;(BottomSheet 방식)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;보통 Popup으로 가운데에 뜨던 방식에서 BottomSheet방식으로 많이 전환하고 있는 추세입니다.&lt;/p&gt;&lt;p&gt;BottomSheet는 &lt;a href=&quot;http://android-developers.blogspot.kr/2016/02/android-support-library-232.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Design Support Library 23.2버전&lt;/a&gt;이상부터&amp;nbsp;공식적으로 지원하고 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;기존에 이미지선택을 위한 &lt;a href=&quot;https://github.com/ParkSangGwon/TedPicker&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;TedPicker&lt;/a&gt; &amp;nbsp;라이브러리를 만들었지만 Bottom Sheet를 활용한 이미지 선택 라이브러리를 만들고 싶어졌습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;TedBottomPicker&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedBottomPicker&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedBottomPicker&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;맨 위의 GIF이미지에서도 확인하셨겠지만 라이브러리를 사용하면 아래와 같은 작동방식을 보실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 225px; width: 225px; height: 400px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/26550A4E583FE2E80C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F26550A4E583FE2E80C&quot; width=&quot;225&quot; height=&quot;400&quot; filename=&quot;screenshot1 (1).jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 225px; height: 400px;&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 225px; width: 225px; height: 400px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/233B384E583FE2EB26&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F233B384E583FE2EB26&quot; width=&quot;225&quot; height=&quot;400&quot; filename=&quot;tedbottompicker.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 225px; height: 400px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;TedBottomPicker라이브러리는 3가지의 이미지선택방법을 제공합니다.&lt;/p&gt;&lt;p&gt;1. 카메라로 사진 찍기&lt;/p&gt;&lt;p&gt;2. 갤러리에서 사진 선택하기&lt;/p&gt;&lt;p&gt;3. 저장되어있는 최근 사진 XX장중에서 선택하기&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용자에게 이미지를 선택하게 만들때 사용자가 원하는 방식으로 선택할수 있도록 할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;사용방법&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;1. gradle 추가&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;dependencies {&lt;br /&gt;   &lt;span style=&quot;color:#6a8759;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;compile &lt;span style=&quot;color:#6a8759;&quot;&gt;'gun0912.ted:tedbottompicker:1.0.4'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;2. 권한 허가&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용자가 사진을 찍는 방법을 선택하는 경우&amp;nbsp;WRITE_EXTERNAL_STORAGE 권한이 필요하게 됩니다.&lt;/p&gt;&lt;p&gt;만약 targetSDK가 22버전 이하라면 Manifest에만 선언해주면 되겠지만, 23버전 이상이라면 동적권한체크도 구현해주어야 합니다.&lt;/p&gt;&lt;p&gt;마시멜로우 이상에서 권한체크와 관련해서는 아래 블로그를 참고하시면 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/55&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드]6.0 마시멜로우 권한체크하고 최적화하기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/61&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드]유용한 라이브러리 - TedPermission(마시멜로우 권한체크)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;직접 권한체크를 하셔도 좋고 라이브러리를 사용하셔도 좋습니다.&lt;/p&gt;&lt;p&gt;어떠한 방법을 사용하셨든 &lt;b&gt;WRITE_EXTERNAL_STORAGE 권한을 사용할 수 있어야&lt;/b&gt; 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;3. TedBottomPicker실행&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;실행 방법은 아래와 같습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;br /&gt;TedBottomPicker bottomSheetDialogFragment = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;TedBottomPicker.Builder(MainActivity.&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;br /&gt;        .setOnImageSelectedListener(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;TedBottomPicker.OnImageSelectedListener() {&lt;br /&gt;            &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onImageSelected&lt;/span&gt;(Uri uri) {&lt;br /&gt;              &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color:#808080;&quot;&gt;// uri 활용&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;        })&lt;br /&gt;        .create()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;bottomSheetDialogFragment.show(getSupportFragmentManager())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;show()가 실행되고나서 사용자가 이미지를 선택하게 되면&amp;nbsp;OnImageSelectedListener 로 들어오게되면서 uri을 넘겨줍니다.&lt;/p&gt;&lt;p&gt;여기서 넘겨받은 uri를 활용해서 원하시는 작업을 해주시면 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;4. 커스터마이징&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 267px; width: 267px; height: 150px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/251AC647583FE6941D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F251AC647583FE6941D&quot; width=&quot;267&quot; height=&quot;150&quot; filename=&quot;custom.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 267px; height: 150px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위와같은 기본적인 사용방법 말고도&lt;/p&gt;&lt;p&gt;- BottomSheet가 올라오는 높이를 조정하거나,&lt;/p&gt;&lt;p&gt;- 카메라/갤러리의 기본이미지를 변경하거나,&lt;/p&gt;&lt;p&gt;- 이미지들 사이의 간격을 변경하거나,&lt;/p&gt;&lt;p&gt;- 기타 커스터마이징을 위한 함수들이 제공되고 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 16px;&quot;&gt;&lt;li style=&quot;box-sizing: border-box;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setMaxCount(Int) (default: 25)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setPeekHeight(Int)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setPeekHeightResId(R.dimen.xxx)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;showCameraTile(Boolean) (default: true)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setCameraTile(R.drawable.xxx or Drawable)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setCameraTileBackgroundResId(R.color.xxx)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setGalleryTile(R.drawable.xxx or Drawable)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;showGalleryTile(Boolean) (default: true)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setGalleryTileBackgroundResId(R.color.xxx)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setSpacing(Int)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setSpacingResId(R.dimen.xxx)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setOnErrorListener(OnErrorListener)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setTitle(String or R.string.xxx) (default: 'Select Image','사진 선택')&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;showTitle(Boolean) (default: true)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setTitleBackgroundResId(R.color.xxx)&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;box-sizing: border-box; margin-top: 0.25em;&quot;&gt;&lt;code style=&quot;box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px;&quot;&gt;setImageProvider(ImageProvider)&lt;/code&gt;&amp;nbsp;: If you want load grid image yourself, you can use your ImageProvider&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;커스터마이징을 위한 기능들은 추가로 더 늘어날수 있으니 Github의 내용을 참고하시면 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;(내용이 유용하셨다면 Github&amp;nbsp;오른쪽위의&amp;nbsp;[Star]버튼을 눌러주시면 감사하겠습니다&lt;/p&gt;&lt;p&gt;저에게는 별풍선 주시는 효과가 있어요!)&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;600&quot; width=&quot;600&quot; exif=&quot;{}&quot; id=&quot;tx_entry_51030_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/2625B4395917C42F09&quot; height=&quot;304&quot; title=&quot;더블클릭을 하시면 이미지를 수정할 수 있습니다&quot; style=&quot;width: 150px; height: 76px;&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용자로부터 이미지를 선택하게하고 가져와야하는경우 &lt;a href=&quot;https://github.com/ParkSangGwon/TedPicker&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;TedPicker&lt;/a&gt;를 사용하시거나 &lt;a href=&quot;https://github.com/ParkSangGwon/TedBottomPicker&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;TedBottomPicker&lt;/a&gt;를 사용하셔서 빠르고 좋은앱을 개발하셨으면 좋겠습니다.&lt;/p&gt;&lt;p&gt;2개의 Image Picker라이브러리에서 부족함을 느끼셨다면 Android Arsenal에서 &lt;a href=&quot;https://android-arsenal.com/tag/157&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;ImagePicker 라이브러리&lt;/a&gt;들을 찾아보실 수도 있습니다.&lt;/p&gt;&lt;p&gt;이 라이브러리가 유용하셨다면 Github에서 Star를 주시면 제게 큰 힘이 됩니다.&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/68</guid>
      <comments>https://gun0912.tistory.com/68#entry68comment</comments>
      <pubDate>Thu, 1 Dec 2016 18:09:48 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]Palette,Swatch를 활용해서 이미지의 테마색 가져오기</title>
      <link>https://gun0912.tistory.com/67</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 225px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2568183D5811B5381F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2568183D5811B5381F&quot; width=&quot;225&quot; height=&quot;400&quot; filename=&quot;palette2.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Grid형태로 데이터를 보여주는 형태의 뷰가 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;텍스트가 들어가는 부분의 배경색이 각각 사진의 분위기에 맞춰서 들어가 있는것을 확인할 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;글씨색또한 배경에 따라서 잘 어울리는 색으로 구성되어 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://android-developers.blogspot.kr/2014/10/implementing-material-design-in-your.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Material Design이 소개&lt;/a&gt;되면서 우리는 Palette를 이용해서 &lt;b&gt;동적으로 해당 이미지의 테마에 어울리는 색들을 찾을 수 있습니다.&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;성격급하신 분들을 위해 준비했습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;일단 먼저 실행해보고 싶으신분은 아래 주소에서 직접 프로젝트를 실행해보시기 바랍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPaletteSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedPaletteSample&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Palette라이브러리는 공식적으로 지원되고 있기때문에 gradle에 추가만 해주시면 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 600px; width: 600px; height: 224px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2217AC3D5811B68602&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2217AC3D5811B68602&quot; width=&quot;600&quot; height=&quot;224&quot; filename=&quot;Screenshot at 10월 27 17-10-34.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 600px; height: 224px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;사용방법은 아주 간단합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://developer.android.com/reference/android/support/v7/graphics/Palette.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Palette&lt;/a&gt;와 &lt;a href=&quot;https://developer.android.com/reference/android/support/v7/graphics/Palette.Swatch.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Palette.Swatch&lt;/a&gt;에 대해서만 아시면 충분합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;Palette 생성&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Bitmap으로부터 Palette를 가져옵니다.&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43);&quot;&gt;&lt;p&gt;&lt;font color=&quot;#808080&quot; face=&quot;Menlo&quot;&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;font-size: 12px;&quot;&gt;Synchronously&lt;/span&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font color=&quot;#a9b7c6&quot; face=&quot;Menlo&quot;&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;Palette palette = Palette.&lt;/span&gt;&lt;/font&gt;&lt;span style=&quot;color: rgb(169, 183, 198); font-family: Menlo; font-size: 9pt; font-style: italic;&quot;&gt;from&lt;/span&gt;&lt;font color=&quot;#a9b7c6&quot; face=&quot;Menlo&quot;&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;(bitmap).generate()&lt;/span&gt;&lt;/font&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Menlo; font-size: 9pt;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Menlo; font-size: 9pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;font color=&quot;#808080&quot; face=&quot;Menlo&quot;&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;font-size: 12px;&quot;&gt;Asynchronously&lt;/span&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font color=&quot;#a9b7c6&quot; face=&quot;Menlo&quot;&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;Palette.&lt;/span&gt;&lt;/font&gt;&lt;span style=&quot;color: rgb(169, 183, 198); font-family: Menlo; font-size: 9pt; font-style: italic;&quot;&gt;from&lt;/span&gt;&lt;font color=&quot;#a9b7c6&quot; face=&quot;Menlo&quot;&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;(bitmap).generate(&lt;/span&gt;&lt;/font&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Menlo; font-size: 9pt;&quot;&gt;new &lt;/span&gt;&lt;font color=&quot;#a9b7c6&quot; face=&quot;Menlo&quot;&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;Palette.PaletteAsyncListener() {&lt;br /&gt;    &lt;/span&gt;&lt;/font&gt;&lt;span style=&quot;color: rgb(187, 181, 41); font-family: Menlo; font-size: 9pt;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(187, 181, 41); font-family: Menlo; font-size: 9pt;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Menlo; font-size: 9pt;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 198, 109); font-family: Menlo; font-size: 9pt;&quot;&gt;onGenerated&lt;/span&gt;&lt;font color=&quot;#a9b7c6&quot; face=&quot;Menlo&quot;&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;(Palette palette) {&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;})&lt;/span&gt;&lt;/font&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Menlo; font-size: 9pt;&quot;&gt;;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;함수는 동기함수와 비동기함수를 사용할 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;동기함수는 메인쓰레드에서 성능에 영향을 미칠 수 있기때문에 백그라운드의 경우에만 사용하는것이 좋습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그렇기 때문에 대부분의 경우에서&amp;nbsp;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;비동기 함수를 사용하는것을 추천&lt;/span&gt;드립니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Palette가 null이 올수도 있기때문에 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;null체크를 해서 오류를 방지해야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Palette를 가져올때 기본적으로 16개의 색상을 이용하지만&amp;nbsp;&lt;a href=&quot;https://developer.android.com/reference/android/support/v7/graphics/Palette.Builder.html#maximumColorCount(int)&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;maximumColorCount()&lt;/a&gt;를 통해 Palette로 이용할 색상의 개수를 지정할 수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;지정한 색상의 개수가 늘어날수록 Palette의 계산시간도 늘어나게 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;Swatch 생성&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Swatch를 통해&amp;nbsp;Palette를 가지고 유용한 색상값들을 가져올 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Swatch는 6개의 테마색을 제공합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Vibrant&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Vibrant dark&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Vibrant light&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Muted&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Muted dark&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Muted light&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;위에서 Palette를 가져왔다면 getXXXSwatch()함수를 통해서 각각의 Swatch를 가져올 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;Palette.Swatch vibrantSwatch = palette.getVibrantSwatch()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;처음에 Vibrant와 Muted라는 영어단어가 생소하게 느껴져서 네이버사전을 찾아보니 아래와 같았습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 318px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/254228485811C56622&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F254228485811C56622&quot; width=&quot;318&quot; height=&quot;106&quot; filename=&quot;Screenshot at 10월 27 18-13-55.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 280px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/224E33485811C56616&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F224E33485811C56616&quot; width=&quot;280&quot; height=&quot;102&quot; filename=&quot;Screenshot at 10월 27 18-14-01.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 198px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/254DB0485811C5E819&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F254DB0485811C5E819&quot; width=&quot;198&quot; height=&quot;150&quot; filename=&quot;stupid.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;네... 사실 정확히는 딱 무슨뜻인지 감이 오지는 않았습니다...&lt;/p&gt;&lt;p&gt;대충 느낌적인 느낌으로만 보자면 Vibrant는 메인이 될만한 진~한 색감을 가져오는것이고 Muted는 그 반대의 개념으로 이해할 수 있을것 같습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;실제로 Palette를 이용하시다보면 Vibrant와 VibrantDark를 많이 사용하시게 될겁니다.&lt;/p&gt;&lt;p&gt;Swatch또한 null로 올수 있기때문에 &lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;null체크를 해주셔야 합니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Swatch에서 제공하는 여러 함수중에서 3가지정도 많이쓰는 함수를 소개해 드리겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://developer.android.com/reference/android/support/v7/graphics/Palette.Swatch.html#getRgb()&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;getRgb()&lt;/a&gt;: Vibrant로 하셨다면 해당 이미지의 Vibrant에 해당하는 RGB색상값을 가져옵니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://developer.android.com/reference/android/support/v7/graphics/Palette.Swatch.html#getTitleTextColor()&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;getTitleTextColor()&lt;/a&gt;: 위의 RGB색상값에 잘 어울리는 제목의 색상값을 가져옵니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://developer.android.com/reference/android/support/v7/graphics/Palette.Swatch.html#getBodyTextColor()&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;getBodyTextColor()&lt;/a&gt;: 위의 RGB색상값에 잘 어울리는 본문의 색상값을 가져옵니다.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;실제로&amp;nbsp;getTitleTextColor() 사용했을때 제목이 본문보다 좀더 투명하게 나와서 제가 기대한 느낌으로 보여지지는 않았습니다.&lt;/p&gt;&lt;p&gt;오히려 반대로 되는게 더 맞을수도 있다는 생각이 들지만 구글형이 그렇게 만들었으니 믿고 따라가 봅니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;Palette와 Swatch를 이용한 배경색,글씨색 변경&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 방법으로 Palette와 Swatch를 이용한다면 아래와 같은 코드로 이미지의 테마에 맞는 배경색과 글씨색들을 지정해 줄수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/19673335a6a39e50082b45e78fb1cdab.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;같은 방식으로 각각 6개의 테마색과 Title,Body색을 지정해줄경우 아래와 같은 결과를 얻으실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/24031B4E5811C8B019&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F24031B4E5811C8B019&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;KakaoTalk_Photo_2016-10-27-18-27-40_84.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;Glide&lt;/span&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&amp;nbsp;연동&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;실제로 서비스중인 앱에 적용할경우 URL형식의 이미지를 가져와서 표시하는경우가 많습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;제가 사랑하는 Glide에 Palette를 적용하는경우는 Glide의 기본 behavior를 활용해서 구현해줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://github.com/bumptech/glide/wiki/Custom-targets#overriding-default-behavior&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Glide Wiki&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/a1ac9966c4fd35997c5ffadc77d695ac.js&quot;&gt;&lt;/script&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 &lt;a href=&quot;https://github.com/bumptech/glide/wiki/Custom-targets#overriding-default-behavior&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Glide Wiki&lt;/a&gt;문서에도 나와있듯이 이 방법은 기본적인 심플예제일뿐 &lt;b&gt;추천되는 방식은 아닙니다.&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;RecyclerView의 ViewHolder에서 사용되는경우 Palette의 generate 시차때문에 엉뚱한 위치에 해당 색상이 지정될 위험이 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;strike&gt;(그럼에도 불구하고 귀찮아서 우리는 아마 이대로 사용하겠죠..)&lt;/strike&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;다음 Glide버전에는 기본적으로 Palette를 제공해줄 예정이라고 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;위와같은 문제를 완벽하게 해결하고 싶은경우&lt;a href=&quot;https://github.com/bumptech/glide/wiki/Custom-targets#palette-example&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt; Glide에서 안내하는 예제&lt;/a&gt;를 확인하신뒤 구현하시면 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Palette 예제 프로젝트는 아래 주소에서 확인해보실 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPaletteSample&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedPaletteSample&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;(내용이 유용하셨다면 Github&amp;nbsp;오른쪽위의&amp;nbsp;[Star]버튼을 눌러주시면 감사하겠습니다&lt;/p&gt;&lt;p&gt;저에게는 별풍선 주시는 효과가 있어요!)&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;600&quot; width=&quot;600&quot; exif=&quot;{}&quot; id=&quot;tx_entry_51030_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/2625B4395917C42F09&quot; height=&quot;304&quot; title=&quot;더블클릭을 하시면 이미지를 수정할 수 있습니다&quot; style=&quot;width: 150px; height: 76px;&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Palette를 잘 활용하셔서 예쁜 화면UX/UI를 만드시기 바랍니다~&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/67</guid>
      <comments>https://gun0912.tistory.com/67#entry67comment</comments>
      <pubDate>Thu, 27 Oct 2016 18:48:53 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]Linkify로 TextView의 특정단어 클릭시 URL이동시키기</title>
      <link>https://gun0912.tistory.com/66</link>
      <description>&lt;p&gt;로그인이 필요한 대부분의 서비스를 보면 로그인화면에서&amp;nbsp;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;'...xxx의 &lt;/span&gt;&lt;u&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;이용약관&lt;/span&gt;&lt;/u&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;, &lt;/span&gt;&lt;u&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;개인정보 취급방침&lt;/span&gt;&lt;/u&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;, ... 에 동의하시게 됩니다.'&lt;/span&gt; 라는 문구를 많이 보셨을겁니다.&lt;/p&gt;&lt;p&gt;여기서 '&lt;u&gt;이용약관&lt;/u&gt;' 을 클릭하면 해당 서비스의 이용약관&amp;nbsp;웹페이지가 열립니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 253px; width: 253px; height: 450px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/25568B3857AB39A708&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F25568B3857AB39A708&quot; width=&quot;253&quot; height=&quot;450&quot; filename=&quot;Screenshot_20160810-231936.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 253px; height: 450px;&quot; original=&quot;yes&quot;/&gt;&lt;/span&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;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 253px; width: 253px; height: 450px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2335443857AB39A929&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2335443857AB39A929&quot; width=&quot;253&quot; height=&quot;450&quot; filename=&quot;Screenshot_20160810-232002.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 253px; height: 450px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이 기능은 한문장에서 특정 단어를 눌렀을때 그와 관련된 URL을 호출해야하는 기능을 만들어야하는 요건입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;처음에 이 기능을 만들때 어떻게 만들어야하나 고민이 많았습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;각각 특정단어를 TextView로 만들어서 일렬로 쭉 붙이는것도 레이아웃상으로 말이 안되고, '개인정보취급방침'&amp;nbsp;이라는 글씨자체는 보통의 전화번호나 http://...와 같은 URL형식이 아니기때문에 autoLink로 걸수도 없었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이 하나의 문장은 하나의 TextView에 들어가 있는것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;Linkify를 이용한다면 간단하게 특정단어에 반응해서 동작을 수행하도록 설정할 수 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;사실 우리는 우리도 모르게 xml의 autoLink에서 기본적인 Linkify기능을 사용하고&amp;nbsp;있었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 443px; width: 443px; height: 400px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/226CDC3A57AB3E8A1B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F226CDC3A57AB3E8A1B&quot; width=&quot;443&quot; height=&quot;400&quot; filename=&quot;Screenshot at 8월 10 23-46-52.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 443px; height: 400px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;autoLink에 설정되어 있는 패턴의 텍스트가 포함되어 있는경우 자동으로 인식하도록 설정할 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;예를들어 &lt;b&gt;'phone'&lt;/b&gt;으로 하는경우 &lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;010-AAAA-BBBB&lt;/span&gt;와 같은&amp;nbsp;전화번호패턴이 문장에 있으면 바로 전화를 걸수 있도록 되고&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;'email'&lt;/b&gt;로 되어있는경우,&amp;nbsp;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;abcdefg@naver.com&lt;/span&gt;의 이메일패턴을 인식해서 이메일을 보낼수 있도록 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 위에서 언급했던것처럼 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;우리는 email,phone과는 다르게&amp;nbsp;아무 연관없는 패턴의 텍스트를 인식해서 특정 url을 실행하도록 해야합니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이러한경우&amp;nbsp;Linkify의&amp;nbsp;addLinks()를 이용할 것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://developer.android.com/reference/android/text/util/Linkify.html#addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter)&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;공식문서&lt;/a&gt;에서 살펴보면 addLinks()함수에 들어갈 인자들은 아래와 같습니다.&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2743433357AB420903&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2743433357AB420903&quot; width=&quot;820&quot; height=&quot;405&quot; filename=&quot;Screenshot at 8월 10 23-54-19.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;- text:&lt;/b&gt; Linkify를 적용할 대상 TextView&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;- pattern:&lt;/b&gt; 감지하고자 하는 텍스트의 패턴(Pattern 클래스로 텍스트를 컴파일)&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;- scheme:&lt;/b&gt; 해당 텍스트를 눌렀을때 이동시킬 URL&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;- matchFilter:&lt;/b&gt; 허용하고자 하는 매칭패턴을 설정해줄&amp;nbsp;filter&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;- transformFilter: &lt;/b&gt;감지된 텍스트와 이동시킬 URL를 활용해서 Custom하게 url을 설정해줄 filter&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 150px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2533E53757AB427C0B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2533E53757AB427C0B&quot; width=&quot;200&quot; height=&quot;150&quot; filename=&quot;question.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 200px; height: 150px;&quot; original=&quot;yes&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;물론 설명만 읽고서는 이해가 안갑니다..백문이불여일견!&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;코드를 보시면서 따라오시면 쉽게 이해하실 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/c16913b4b786e57d3ae6cc0e247c2c39.js?file=MainActivity.java&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;

&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/c16913b4b786e57d3ae6cc0e247c2c39.js?file=activity_main.xml&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;여기서 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;눈여겨&amp;nbsp;보실 부분은&amp;nbsp;TransformFilter의&amp;nbsp;transformUrl()&lt;/span&gt;입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;만약 이 필터를 설정하지 않는다면 &lt;b&gt;'셀폰'&lt;/b&gt;이라는 텍스트에 대해서 &lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;'http://selphone.co.kr'&lt;/span&gt; 의 url을 설정해놓은것에 대해서 실제로는 2개가 합쳐진 &lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;'http://selphone.co.kr셀폰'&lt;/span&gt;으로 url이 만들어져 버립니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;즉, 우리가 설정한 scheme뒤에 감지하고자한 텍스트가 붙어버리는 현상이 발생합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그래서 우리는 뒤에 &lt;b&gt;어떤&amp;nbsp;텍스트도 추가되지 않도록 transformUrl()함수에서 공백을 리턴&lt;/b&gt;해줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그렇게하면&amp;nbsp;온전히 우리가 설정한 url scheme이 실행됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;transformUrl()를 잘&amp;nbsp;응용한다면 감지된 텍스트에 따라서 뒤에 이동시킬 url을 다르게 바꿔줄 수도 있는 기능입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;문제없이 잘 만드셨다면&amp;nbsp;아래와 같은 화면을&amp;nbsp;볼 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 254px; width: 254px; height: 450px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/277EFF3D57AB454509&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F277EFF3D57AB454509&quot; width=&quot;254&quot; height=&quot;450&quot; filename=&quot;Screenshot_20160811-001217.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 254px; height: 450px;&quot; original=&quot;yes&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;위의 소스코드에서 설정한대로 &lt;b&gt;'셀폰'&lt;/b&gt; 을 인식했고 이 텍스트를 누를경우 &lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;http://selphone.co.kr&lt;/span&gt;로 이동합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아래 텍스트도 마찬가지로 동작합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;여기서 좀더 응용해본다면 Custom Scheme을 이용해서 텍스트를 눌렀을때 특정 액티비티를 실행시킬수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Csutom URL Scheme에대해 궁금하시다면 아래 포스팅을 참고하세요&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://gun0912.tistory.com/13&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드]URL로 액티비티 실행하는 방법(Custom URL Scheme)&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;지금까지&amp;nbsp;Linkify를 이용해서&amp;nbsp;TextView의 특정단어를&amp;nbsp;클릭시 지정한&amp;nbsp;URL을 실행하는 방법에 대해 포스팅해보았습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;감사합니다.&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/66</guid>
      <comments>https://gun0912.tistory.com/66#entry66comment</comments>
      <pubDate>Thu, 11 Aug 2016 08:51:45 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/JAVA]한글 받침에따라서 '을/를' 구분하기</title>
      <link>https://gun0912.tistory.com/65</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 200px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2367D64B57A2FE4B26&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2367D64B57A2FE4B26&quot; width=&quot;200&quot; height=&quot;200&quot; filename=&quot;Screenshot at 8월 04 17-32-14111.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 200px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;안드로이드뿐만아니라 아이폰,PC에서 서비스를 사용할때 'xxx을(를)' 혹은 'xxx이(가)' 로 표시되는 메세지를 많이 보셨을겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 350px; width: 350px; height: 257px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/220F694D57A2FF011C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F220F694D57A2FF011C&quot; width=&quot;350&quot; height=&quot;257&quot; filename=&quot;Screenshot_20160804-170125.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 350px; height: 257px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이는 한글의 받침때문에 일어나는 한국어만의 문제입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;받침이 있느냐 없느냐에 따라 뒤에 붙는 글자가&amp;nbsp;'을/를', '이/가','은/는'이 되기 때문입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;서비스를 개발하면서 변수로 사용되는 이름 혹은 단어가 어떤게 올지 모르지 개발자 입장에서는 위와 같이 대응하는 방법이 제일 편하고 쉽습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 좀더 깔끔한 문장을 만들기위해서는 받침의 유무에따라서 뒤에붙는 글자를 판단하고 싶은경우가 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;'박상권을(를) 좋아합니다' 보다는 '박상권을 좋아합니다' 라고 쓰여있는 문장이 좀더 깔끔한 문장으로 보여질것입니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;해당 변수의 한글단어에 따라서 뒤에 붙는 조사를 판단하는 방법에 대해서 포스팅 해보겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;1. 종성 가져오기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;한글은 실제코드에서는&amp;nbsp;유니코드로 구성되어있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;19개의 초성, 21개의 중성, 28개의 중성의 조합으로 한글이 만들어 집니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 668px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2218A04457A300B217&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2218A04457A300B217&quot; width=&quot;668&quot; height=&quot;348&quot; filename=&quot;Screenshot at 8월 04 17-04-44.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(166, 166, 166);&quot;&gt;(사진출처: http://blog.finsternis.me/380)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;1개의 한글은 각 초성/중성/종성의 조합으로 유니코드값이&amp;nbsp;만들어집니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;한글 유니코드값을 초성/중성/종성으로 나누는 방법과 반대로 초성/중성/종성을 조합해서 유니코드를 만드는 방법은 인터넷에 검색해보시면 정말 많이 나와있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://hanpsy.tistory.com/2&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://hanpsy.tistory.com/2&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://dream.ahboom.net/entry/%ED%95%9C%EA%B8%80-%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C-%EC%9E%90%EC%86%8C-%EB%B6%84%EB%A6%AC-%EB%B0%A9%EB%B2%95&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://dream.ahboom.net/entry/%ED%95%9C%EA%B8%80-%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C-%EC%9E%90%EC%86%8C-%EB%B6%84%EB%A6%AC-%EB%B0%A9%EB%B2%95&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://divestudy.tistory.com/8&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://divestudy.tistory.com/8&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;사실 결론적으로 아래 수식만 알고 계시면됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;한글 유니코드 조합하기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;= 0xAC00(처음 한글 시작값) + (초성 인덱스&amp;nbsp;x 21 x 28 ) + (중성 인덱스&amp;nbsp;x 28) + 종성 인덱스&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;유니코드 분해하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;초성 인덱스&amp;nbsp;= ((한글 유니코드값&amp;nbsp;- 0xAC00) / 28) / 21&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;중성 인덱스&amp;nbsp;= ((한글 유니코드값&amp;nbsp;- 0xAC00) / 28) % 21&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;종성 인덱스&amp;nbsp;= (한글 유니코드값&amp;nbsp;- 0xAC00) % 28&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;여기서 우리는 종성인덱스 값을 가져올 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이를 안드로이드의 코드로 구현해본다면 아래와 같습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;char &lt;/span&gt;lastName = name.charAt(name.length() - &lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;index= (lastName - &lt;span style=&quot;color:#6897bb;&quot;&gt;0xAC00&lt;/span&gt;) % &lt;span style=&quot;color:#6897bb;&quot;&gt;28&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;찾고자하는 값의 마지막 글자를 가져온뒤, 이 글자의 종성 인덱스 값을 찾아옵니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;2. 받침포함여부 가져오기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 종성테이블에서 보시면 아시겠지만 받침이 없는경우는 종성 인덱스가 0으로 구성되어 있습니다.&lt;/p&gt;&lt;p&gt;그러므로&lt;b&gt; 1번에서 가져온 종성인덱스가 0이상일 경우는 받침이 있는경우이며 그렇지 않은경우는 받침이 없는 경우&lt;/b&gt;입니다.&lt;/p&gt;&lt;p&gt;우리는 이 경우를 판단해서 해당 단어 뒤에 '을/를', '이/가','은/는' 을 붙여주면 되는것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;최종 만들어질 함수의 내용은 아래와 같은 방식으로 만들어 집니다.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/c3fc35dd1072255b72b68920e7aeaae6.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용하실때는 아래와 같이 사용해주시면 됩니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;String name=&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;박상권&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;String name1=KoreanUtil.&lt;span style=&quot;font-style:italic;&quot;&gt;getComleteWordByJongsung&lt;/span&gt;(name&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;을&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;를&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;String name2=KoreanUtil.&lt;span style=&quot;font-style:italic;&quot;&gt;getComleteWordByJongsung&lt;/span&gt;(name&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;이&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;가&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;String name3=KoreanUtil.&lt;span style=&quot;font-style:italic;&quot;&gt;getComleteWordByJongsung&lt;/span&gt;(name&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;은&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;는&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;어때요?&lt;/p&gt;&lt;p&gt;한글이 가지고 있는 매력덕분에 유니코드도 공부하고 깔끔한 문장도 만들수 있게 되셨죠?&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 149px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2520E93357A306F222&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2520E93357A306F222&quot; width=&quot;200&quot; height=&quot;149&quot; filename=&quot;clean.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 200px; height: 149px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 방법을 사용하셔서&amp;nbsp;이(가), 은(는) 같은 문장보다는 좀더 깔끔한 문장으로 사용자에게 서비스를 제공하셨으면 좋겠습니다.&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/65</guid>
      <comments>https://gun0912.tistory.com/65#entry65comment</comments>
      <pubDate>Thu, 4 Aug 2016 18:19:40 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]삼성 '스마트매니저' 푸시알림 차단이슈 대응하기</title>
      <link>https://gun0912.tistory.com/64</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 150px; width: 150px; height: 150px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2518B64A57900B192D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2518B64A57900B192D&quot; width=&quot;150&quot; height=&quot;150&quot; filename=&quot;스마트-매니저.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 150px; height: 150px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;스마트매니저....Smart Manager....&lt;/p&gt;&lt;p&gt;저는 이 아이콘만 봐도 치가 떨립니다...&lt;/p&gt;&lt;p&gt;이 글을 읽기전 이 아이콘만 봐도 저처럼 화가 나시는분이 계시다면 분명 저와 같은 이유일겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;작년 갤럭시S6에 기본으로&amp;nbsp;'스마트매니저' 가 기본탑재되고 그 이후 다른 기종들도 업데이트하면 해당 기능이 사용되도록 변경되었습니다.&lt;/p&gt;&lt;p&gt;아, 물론 취지는 좋습니다.&lt;/p&gt;&lt;p&gt;특정앱의 과도한 데이터, 배터리 사용을 감지해서 알려주거나 불필요한 데이터나 사용자의 데이터를 한번에 정리해주는등 유용한 기능들도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://news.samsung.com/kr/%ED%98%84%EC%9E%AC-%EB%82%B4-%EC%8A%A4%EB%A7%88%ED%8A%B8%ED%8F%B0%EC%9D%98-%EC%83%81%ED%83%9C%EB%8A%94-%EC%8A%A4%EB%A7%88%ED%8A%B8%ED%8F%B0%EC%9D%84-%EB%8A%98-%EC%83%88%EA%B2%83&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[이 앱, 아셨어요?] 소중한 내 폰, 늘 빠릿빠릿하게! ‘스마트 매니저’&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/266EC73C57900D6202&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F266EC73C57900D6202&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;Screenshot_20160721-083144.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 445px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만 문제가 되는건 '앱 절전' 기능입니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;'앱 절전'기능은 앱을 3일이상 한번도 사용하지 않으면 앱으로부터 오는 푸시/알람이 전혀 오지 않도록 설정&lt;/span&gt;됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;더군다나 모든 앱이 &lt;b&gt;이 기능이 기본으로 '적용'이 되어있는 상태&lt;/b&gt;라는 것입니다.&lt;/p&gt;&lt;p&gt;사용자가 필요없다고 판단해서 앱을 하나하나 '적용'하는 블랙리스트방식이 아니라,&amp;nbsp;&lt;/p&gt;&lt;p&gt;기본으로 다 '적용'을 해두고 사용자가 필요한 앱을 '해지'하는 화이트리스트'방식을 택한것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용자는 내가 사용하는 앱이 이 기능이 적용되어 있다는 사실도 모른채 사용하고 있는것입니다.&lt;/p&gt;&lt;p&gt;심지어 사용자는 스마트매니저가 뭔지도 모르고&amp;nbsp;실행되고 있다는 사실도 모릅니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;3일이상 앱을 사용하지 않으면&amp;nbsp;채팅앱이든, 알람앱이든, 기타 앱의 모든 알림/푸시를 아무리 보내도 사용자는 받아볼 수 없습니다.&lt;/p&gt;&lt;p&gt;무슨생각으로 화이트리스트 방식으로 기획을 하셨는지 삼성 스마트매니저 기획자분께 여쭤보고 싶습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 230px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2236494E5790148706&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2236494E5790148706&quot; width=&quot;300&quot; height=&quot;230&quot; filename=&quot;Screenshot at 7월 21 09-16-33.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 230px;&quot; original=&quot;yes&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;뭣이 중헌디!!!!!!! 뭣이 중허냐고!!!!!!&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사실 좀더 정확하게 말하자면&amp;nbsp;모든앱에&amp;nbsp;이 기능이 적용되어 있지는 않습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/260B9C4B57900FDE02&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F260B9C4B57900FDE02&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;Screenshot_20160721-085608.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 445px;&quot;/&gt;&lt;/span&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;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/24054F4B57900FE007&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F24054F4B57900FE007&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;Screenshot_20160721-085602.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 445px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;카카오톡, 라인, 밴드, 올레통신사 앱등 &lt;b&gt;대형 통신사나 앱서비스회사들의 앱은 이 절전 기능이 기본으로 꺼져&amp;nbsp;있습니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;심지어 일부앱은 절전 기능을 적용할수도 없게 무조건 '꺼짐' 기능밖에 못하도록 되어있습니다.&lt;/p&gt;&lt;p&gt;그래서 더 화가 납니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만 화가나도 어쩔수 없습니다.&lt;/p&gt;&lt;p&gt;저는 작은&amp;nbsp;스타트업을 운영하고 있는 불효자니까요..&lt;/p&gt;&lt;p&gt;그래서 이 절전기능 이슈에 대응해온 과정을 소개 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(255, 0, 0);&quot;&gt;스마트 매니저 '절전'&lt;/span&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(255, 0, 0);&quot;&gt;기능 대응하기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;1. &lt;/span&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;우리 앱도 기본으로 '꺼짐'&lt;/span&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;으로 되어있는 앱목록에 껴주세요!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 방법이 제일 쉽습니다. 우리는 추가로 개발할게 없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 150px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/252F624E579012A006&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F252F624E579012A006&quot; width=&quot;200&quot; height=&quot;150&quot; filename=&quot;join.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 200px; height: 150px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만 이 방법은 제일 어렵습니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;삼성에서 우리의 앱을 저 목록에 끼워줄리가 없으니까요..&lt;/p&gt;&lt;p&gt;삼성 관계자 여러분, 저 목록에는 대기업&amp;nbsp;앱만 끼워주시는건가요?&lt;/p&gt;&lt;p&gt;이유를 알고 싶습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;2. 사용자&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;여러분! 절전모드를 사용하지마세요!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;앱안에서 삼성스마트매니저가 깔려있는 사용자들에게 아래와 같은 팝업을 띄워주었습니다.&lt;/p&gt;&lt;p&gt;그리고 사용자가 설정으로 이동할수있도록 버튼까지 같이 보여주었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 459px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/276E75475790121D38&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F276E75475790121D38&quot; width=&quot;300&quot; height=&quot;459&quot; filename=&quot;Screenshot at 7월 21 09-06-42.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 459px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 사용자는 귀찮은걸 싫어합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;공지사항,팝업,알림등 귀찮다고 느껴지는 것들은 읽어보지도 않고 닫아버리는 경우가 대다수입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;실제로 GA에서 이벤트로 찍어서 데이터를 분석해보면 팝업이 떴을때 그냥 닫아버리는 사용자가 대다수였습니다..&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이 방법도 역시 임시방편일뿐 대부분의 사용자는 여전히 절전기능 이슈가 존재한다고 생각했습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;3. 3일에 한번 앱을 실행시키자!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이 절전기능 이슈를 해결하기위한 방법을 생각해보면 아래와 같습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;1. 적어도 3일에 한번 앱을 실행시킨다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2. 뜬금없이 앱이 실행되면 사용자가 이상하게 생각하므로 사용자가 모르게 앱을 실행시켰다가 바로 닫는다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;위의 2가지만 충족시킨다면 절전기능 이슈로부터 벗어날 수 있게 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;이 방법은 '알람몬'을 운영하고 있는 '말랑스튜디오'로부터 영감을 받았습니다.&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아래 설명을 읽기&amp;nbsp;귀찮으신분은 '말랑스튜디오'에서&amp;nbsp;라이브러리형태로 제공하고있는 이 기능을 사용하시면 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://github.com/malangstudio/AvoidSmartManager&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/malangstudio/AvoidSmartManager&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2번의 해결방법은 쉽습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;별도로 투명한 액티비티를 만들고 이 액티비티를 실행했다가 바로 finish()해주면 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/cd2e71d694222ab8c54cdaca6b88d286.js?file=AvoidSmartManagerActivity.java&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그리고 이 액티비티의 Manifest에는 excludeFromrecents, taskAffinity 를 넣어주어야 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;excludeFromrecents을 true로 설정하면&amp;nbsp;최근실행된 앱 리스트에 이 액티비티는 표시되지 않습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;taskAffinity를 별도의 이름으로 지정하지 않으면 투명한 액티비티가 실행될때 이액티비티만 실행되는것이 아니라 다른 액티비티도 함께 실행됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그래서 투명한 액티비티가 실행되었다가 종료되도 앱의 메인액티비티가 실행되버리는 현상이 발생합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/cd2e71d694222ab8c54cdaca6b88d286.js?file=Manifest1.xml&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;



&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;적어도 3일에 한번 앱을 실행시키기 위해서는 앱을 실행시키기 위한 어떤 특정 이벤트가 필요합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Receiver를 두어서 어떤 이벤트가 일어날때 이를 감지하고 위에서 만든 투명한 액티비티를 실행한다면 이 문제는 해결할 수 있습니다.&lt;/p&gt;&lt;p&gt;그럼 어떤 이벤트에 대해서 모니터링을 걸어두어야 할까요?&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;잘 생각해보면 스마트폰을 사용한다면 누구나 3일에 한번은 최소한 한번 이상 '충전을 하거나', '충전을 해제하거나', '휴대폰을 재부팅시키거나' 할것입니다.&lt;/p&gt;&lt;p&gt;여기서 우리는 아래 이벤트를 감지하는 Receiver를 만들면 되는것 입니다.&lt;/p&gt;&lt;p&gt;- ACTION_POWER_CONNECTED&lt;/p&gt;&lt;p&gt;- ACTION_POWER_DISCONNECTED&lt;/p&gt;&lt;p&gt;- BOOT_COMPLETED&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그렇게해서 만들어진 Manifest는 아래와 같이 정의될것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/cd2e71d694222ab8c54cdaca6b88d286.js?file=Manifest2.xml&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;AvoidSmartManagerReceiver에서는 미리 만들어둔 투명한 액티비티를 실행했다가 바로 종료하는 코드를 작성해주면 됩니다.&lt;/p&gt;&lt;p&gt;이 리시버에서는 위에서 정의한 이벤트가 발생했는지를 검사하고 삼성스마트매니저의 설치여부를 알아낸뒤 투명한 액티비티를 랜덤시간이후에 실행하는 동작을 수행 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/cd2e71d694222ab8c54cdaca6b88d286.js?file=AvoidSmartManagerReceiver.java&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 18pt;&quot;&gt;문제점&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 방법으로 문제를 해결할 수 있는것처럼 보이지만 완벽한 해결방법은 아닙니다.&lt;/p&gt;&lt;p&gt;우리가 의도치 않은 문제가 발생할 수 있기 때문입니다.&lt;/p&gt;&lt;p&gt;사용자가 게임을 하고있거나 동영상을 보고 있을때 충전기를 연결하면 갑자기 영상이나 게임이 일시정지 됩니다.&lt;/p&gt;&lt;p&gt;왜냐하면 순간적으로 우리의 앱이 실행되었다가 종료 되기때문에 기존에 실행되던 동영상이나 앱은 onPause()상태로 가게 될것이고 그래서 일시정지상태가 되는것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;아, 물론 사용자는 우리가 설정해둔 이 기능때문에 게임이나 영상이 멈췄다는것을 알지&amp;nbsp;못합니다.&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 이것은 사용자에게 서비스를 제공하는&amp;nbsp;입장에서 그리고 양심적으로 문제가 생기는 부분입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;만약 이러한 방법으로 여러앱에서 설정해둔경우 투명한 액티비티가 엄청 여러개 실행되었다가 종료되는 상황이 발생할 것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 18pt;&quot;&gt;결론&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;지금까지 여러 과정을 거쳐보니&amp;nbsp;이 이슈에 대한 완벽한 해결책은 아직 없는것 같습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;제가 생각하는 완벽한 해결책은 딱 하나 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;삼성에서 스마트매니저 절전기능을 기본으로 '해제'시킨상태로 시작&lt;/b&gt;하게 해주는것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;사용자가 필요없다고 생각하는 앱을 직접 '적용' 할때 비로소 이 절전기능이 실행된다면 좋겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 150px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2270403A5791B94D0B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2270403A5791B94D0B&quot; width=&quot;200&quot; height=&quot;150&quot; filename=&quot;pray.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 200px; height: 150px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;삼성 스마트매니저 관계자 여러분,&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;사용자가 그리고 앱을 서비스하는 사람들이 불편한 기능이라면 이는 필요하지 않은 기능입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;오히려 사용자를 불편하게 만드는 기능은 없어져야 하는것이 맞을것 같습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;지금까지 삼성 '스마트매니저' 푸시알림 차단이슈에 대응하는 방법에 대해서 포스팅 해보았습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이 글을 읽으신분들중에 다른 방법으로 이 이슈를 회피해보신 경험이 있으시다면 댓글로 정보공유 해주시면 감사하겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;감사합니다.&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/64</guid>
      <comments>https://gun0912.tistory.com/64#entry64comment</comments>
      <pubDate>Fri, 22 Jul 2016 15:21:31 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]API Gateway - RESTful API만들기</title>
      <link>https://gun0912.tistory.com/63</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 200px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/253BFA47578EAD7C15&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F253BFA47578EAD7C15&quot; width=&quot;200&quot; height=&quot;200&quot; filename=&quot;api_gateway.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 200px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;AWS Lambda의 소개 및 서버없이 Restful API서버구성을 만드는 방법이 궁금하시다면 아래 블로그부터 확인하시고 이 글을 따라오시길 권장합니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/59&quot; target=&quot;_blank&quot;&gt;[IT/AWS] - [AWS]서버없이 Lambda와 API Gateway로 서버API 만들기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;REST API가 뭐지?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;blockquote cite=&quot;https://spoqa.github.io/2012/02/27/rest-introduction.html&quot;&gt;
&lt;p&gt;REST는 Representational state transfer의 약자로, 월드와이드웹과 같은 분산 하이퍼미디어 시스템에서 운영되는 소프트웨어 아키텍처스타일입니다.&lt;/p&gt;&lt;p&gt;2000년에 Roy Fielding에 의해 처음 용어가 사용되었는데, 이 분은 HTTP/1.0, 1.1 스펙 작성에 참여했었고 아파치 HTTP 서버 프로젝트의 공동설립자이기도 합니다.&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;REST는 HTTP/1.1 스펙과 동시에 만들어졌는데, HTTP 프로토콜을 정확히 의도에 맞게 활용하여 디자인하게 유도하고 있기 때문에 디자인 기준이 명확해지며, 의미적인 범용성을 지니므로 중간 계층의 컴포넌트들이 서비스를 최적화하는 데 도움이 됩니다.&lt;/p&gt;&lt;p&gt;REST의 기본 원칙을 성실히 지킨 서비스 디자인은 “RESTful 하다.” 라고 흔히 표현합니다.&lt;/p&gt;
&lt;br /&gt;
&lt;cite&gt;&lt;a href=&quot;https://spoqa.github.io/2012/02/27/rest-introduction.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;spoqa 기술블로그 'REST 아키텍처를 훌륭하게 적용하기 위한 몇 가지 디자인 팁' 에서&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;용어에 대한 정의는 항상 읽어도 읽어도 공대생인 저에게는 어려운 말입니다...&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 150px; width: 150px; height: 112px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2229444D578EAF8E14&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2229444D578EAF8E14&quot; width=&quot;150&quot; height=&quot;112&quot; filename=&quot;dont know.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 150px; height: 112px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;RESTful 하게 API를 구성했다고 하는건 여러가지 필요한것들이 있겠지만,&lt;/p&gt;&lt;p&gt;HTTP method인 POST, GET, PUT, DELETE에 해당하는 액션만 잘 이해하고 있어도 반이상은 구성하셨다고 볼 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;여기서 각 method는 아래와 같은 의미입니다.&lt;/p&gt;&lt;p&gt;- POST: 새로 생성(Create)&lt;/p&gt;&lt;p&gt;- GET: 조회(Read)&lt;/p&gt;&lt;p&gt;- PUT: 수정(Update)&lt;/p&gt;&lt;p&gt;- DELETE: 삭제(delete)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또한 같은 method이더라도 API에서 사용하는 url인&amp;nbsp;resource주소가 어떻게 구성되느냐에 따라서 각각 다른 동작을 수행하도록 되어있습니다.&lt;/p&gt;&lt;p&gt;아래의 표를 제대로 이해하고 계신다면 RESTful API를 구성하실 준비는 끝났다고 봐도 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 425px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2616443C578EB14D23&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2616443C578EB14D23&quot; width=&quot;425&quot; height=&quot;228&quot; filename=&quot;Prag_REST_CRUD_thumb.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사실&amp;nbsp;RESTful하게 API를 구성하시려면 이 외에도 좀더 많은것을 아셔야 할 부분이 있습니다.&lt;/p&gt;&lt;p&gt;아래 블로그를 참고하시면 도움이 되실겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://spoqa.github.io/2012/02/27/rest-introduction.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;REST 아키텍처를 훌륭하게 적용하기 위한 몇 가지 디자인 팁&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://blog.remotty.com/blog/2014/01/28/lets-study-rest/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;RESTFul이란 무엇인가?&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://beyondj2ee.wordpress.com/2013/03/21/%EB%8B%B9%EC%8B%A0%EC%9D%98-api%EA%B0%80-restful-%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%80-5%EA%B0%80%EC%A7%80-%EC%A6%9D%EA%B1%B0/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;당신의 API가 Restful 하지 않은 5가지 증거&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;API Gateway로 RESTful API구성하기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;기본설정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사실 API Gateway는 여기로 들어온 요청을 지정된곳으로 리다이렉트해주는 개념정도로 볼 수 있습니다.&lt;/p&gt;&lt;p&gt;우리는 POST, GET, PUT, DELETE로 요청된 resource를 일반적인 http로 보내는것이 아니라&amp;nbsp;Lambda Function을 실행하도록 구성할 것입니다.&lt;/p&gt;&lt;p&gt;Lambda를 구성하는 방법에 대해서 궁금하시다면 아래 포스팅을 한번 읽고 시작하시는것이 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/60&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[AWS]Lambda의 시작 - 'Hello World' 출력하기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1. AWS콘솔에서 API Gateway서비스로 이동합니다.&lt;/p&gt;&lt;p&gt;2. 처음 만드시는 경우라면 [Get Started Now]버튼을 눌러 시작합니다.&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2753BF40578EB36626&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2753BF40578EB36626&quot; width=&quot;820&quot; height=&quot;257&quot; filename=&quot;Screenshot at 7월 20 08-09-54.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이전에 만드신적이 있다면 [Create API]를 클릭합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/216BD346578EB3CB25&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F216BD346578EB3CB25&quot; width=&quot;820&quot; height=&quot;249&quot; filename=&quot;Screenshot at 7월 20 08-11-47.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;3. API이름과 설명을 적으신후 [Create API]를 클릭합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/246E0546578EB43225&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F246E0546578EB43225&quot; width=&quot;820&quot; height=&quot;305&quot; filename=&quot;Screenshot at 7월 20 08-13-23.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;4. 위의 예제처럼 /dogs 라는 resource를 생성해주기위헤 [Create Resource]를 클릭해줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/25388447578EB48C26&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F25388447578EB48C26&quot; width=&quot;820&quot; height=&quot;297&quot; filename=&quot;Screenshot at 7월 20 08-14-40.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;5. Resource&amp;nbsp;Name으로 'dogs'를 입력해주면 아래에 path도 함께 같은 내용으로 채워집니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2573044F578EB4E31B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2573044F578EB4E31B&quot; width=&quot;820&quot; height=&quot;301&quot; filename=&quot;Screenshot at 7월 20 08-16-04.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;6. resource가 만들어졌다면 POST, GET, PUT, DELETE에 맞게 각각 [Create Method]를 클릭해서 생성해주는 작업을 하면됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/23779A50578EB5511E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F23779A50578EB5511E&quot; width=&quot;820&quot; height=&quot;287&quot; filename=&quot;Screenshot at 7월 20 08-17-23.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;POST&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[Create Method]를 클릭한뒤 POST를 선택하고 체크아이콘을 클릭해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2131484B578EB5CA29&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2131484B578EB5CA29&quot; width=&quot;820&quot; height=&quot;293&quot; filename=&quot;Screenshot at 7월 20 08-20-17.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Integration type에서 'Labmda Funtion'을 선택해 줍니다.&lt;/p&gt;&lt;p&gt;미리 POST에 해당하는 Lambda Funtion을 만드셨다면 선택하면 되겠지만, 처음 시작할때는 당연히 없을겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/274A9249578EB89229&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F274A9249578EB89229&quot; width=&quot;820&quot; height=&quot;321&quot; filename=&quot;Screenshot at 7월 20 08-30-36.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;GET,PUT,DELETE도 마찬가지로 Lambda function을 먼저 만들고 그뒤에 API Gateway에서 각각에 맞는 Lambda function으로 할당해주어야 합니다.&lt;/p&gt;&lt;p&gt;그렇기때문에 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;우리는 먼저 Lambda Funtion을 구성해주어야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Lambda function을 새로 만들때 'Configure triggers' 라는 단계가 새로 생겼습니다.&lt;/p&gt;&lt;p&gt;예전에는 API Gateway에서 resource와 method를 만들고 Lambda를 만들었지만,&lt;/p&gt;&lt;p&gt;지금은 거꾸로 Lambda를 만드는 시점에 API Gateway의 resource와 method를 만들어 줄수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/24423747578EB97C2F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F24423747578EB97C2F&quot; width=&quot;820&quot; height=&quot;365&quot; filename=&quot;Screenshot at 7월 20 08-36-10.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위에서 우리가 만든 API name과 resource name 그리고 POST method를 선택하고 [Next]를 클릭합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2174814F578EB9C027&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2174814F578EB9C027&quot; width=&quot;820&quot; height=&quot;499&quot; filename=&quot;Screenshot at 7월 20 08-36-58.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Lambda code에는 요청에 대해서 무조건 성공응답을 보내고&amp;nbsp;request를 출력해보기 위해서 console.log()를 찍는 소스코드를 넣어줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/270AD73E578EBA8C05&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F270AD73E578EBA8C05&quot; width=&quot;820&quot; height=&quot;380&quot; filename=&quot;Screenshot at 7월 20 08-39-42.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;작성한 내용을 확인하고 [Create funtion]을 클릭합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/241EF540578EBB4E04&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F241EF540578EBB4E04&quot; width=&quot;820&quot; height=&quot;516&quot; filename=&quot;Screenshot at 7월 20 08-41-36.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;function을 만들고 나면 아래와 같이 Lambda를 trigger 시키는 것들에 대해서 보여지게 됩니다.&lt;/p&gt;&lt;p&gt;우리는 API Gateway를 연결해두었기 때문에 해당 resource의 url로 POST 전송을 하면 동작할 것입니다.&lt;/p&gt;&lt;p&gt;위의 [Test]버튼을 눌러 테스트를 해보겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/22634F41578EBC9D03&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F22634F41578EBC9D03&quot; width=&quot;820&quot; height=&quot;253&quot; filename=&quot;Screenshot at 7월 20 08-45-24.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;테스트에 들어갈 event 내용은 원하시는 형태로 아무거나 테스트로 넣으시면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 815px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2502C14B578EBD5C06&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2502C14B578EBD5C06&quot; width=&quot;815&quot; height=&quot;776&quot; filename=&quot;Screenshot at 7월 20 08-52-41.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;테스트 결과는 아래와 같습니다.&lt;/p&gt;&lt;p&gt;우리가 Lambda function 코드에서 항상 &quot;&quot;을 리턴해주고 event로 들어온값을 로그로 찍어준것처럼 아래에 그대로 로그와 응답으로 넘어오게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/25041147578EBDA20A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F25041147578EBDA20A&quot; width=&quot;820&quot; height=&quot;304&quot; filename=&quot;Screenshot at 7월 20 08-53-25.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;기본적인 POST로의 연동은 끝났습니다.&lt;/p&gt;&lt;p&gt;나중에 실제 구현하실때는 /dogs의 POST는 dog 데이터를 생성해주는 작업을 하는 API이므로&amp;nbsp;event에서 받은 값들을 우리의 DB에 저장하는 코드를 Lambda function 코드에 넣어주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;GET&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;GET의 방법도 위의 POST를 구성하는 방식과 동일합니다.&lt;/p&gt;&lt;p&gt;/dogs의 GET은 dog 와 관련된 테이블의 모든 데이터 리스트를 리턴해주는 작업을 해주어야 하므로 DB에서 해당 dog 데이터들을 불러와서&lt;/p&gt;&lt;p&gt;context.succeed()함수 결과에 데이터리스트들을 리턴시켜주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;PUT&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;DELETE&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;PUT과 DELETE는 /dogs 가 아닌 /dogs/1 과 같은 특정 dog의 id에 대한 동작입니다.&lt;/p&gt;&lt;p&gt;PUT&amp;nbsp;/dogs/1 은 1번 데이터에 해당하는 dog 정보를 수정하는 작업이고,&lt;/p&gt;&lt;p&gt;DELTE /dogs/1 은 1번 데이터에 해당하는 dog 정보를 삭제하는 작업입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그렇기때문에 아래 그림처럼 /dogs 아래에 새로운 resource를 생성해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2550DB38578EBF451F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2550DB38578EBF451F&quot; width=&quot;820&quot; height=&quot;303&quot; filename=&quot;Screenshot at 7월 20 09-00-36.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;여기서 /dogs 아래에 생기는 resource이름이 중요합니다.&lt;/p&gt;&lt;p&gt;PUT, DELETE의 경우 수정,삭제하고자 하는 db id를 path로 넘겨줄것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;PUT /dogs/1&lt;/p&gt;&lt;p&gt;PUT /dogs/123&lt;/p&gt;&lt;p&gt;PUT /dogs/123456&lt;/p&gt;&lt;p&gt;PUT /dogs/7777&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그렇기때문에 우리는 resource path에 {id} 로 만들어주어 어떤 path parameter도 받아줄 수 있도록 구성합니다.&lt;/p&gt;&lt;p&gt;그림에도 이와같은 설며이 잘 나와 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2143793B578EC59021&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2143793B578EC59021&quot; width=&quot;820&quot; height=&quot;303&quot; filename=&quot;Screenshot at 7월 20 09-13-59.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이제 resource를 만들었으니 PUT,DELETE를 위한 Lambda funtion을 만들어줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;POST에서 만들던 방법대로 &amp;nbsp;resource&amp;nbsp;name과 method를 선택해줍니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2445373B578EC5921E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2445373B578EC5921E&quot; width=&quot;820&quot; height=&quot;498&quot; filename=&quot;Screenshot at 7월 20 09-17-30.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;PUT,DELTE Lambda코드에서는 특별히 id라는 path 파라미터가 들어오기때문에 이 파라미터를 잘 가져올수 있는지를 보기 위하여 받아온 id를 리턴하는 코드로 작성해 보겠습니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 736px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/213FF63B578EC59323&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F213FF63B578EC59323&quot; width=&quot;736&quot; height=&quot;198&quot; filename=&quot;Screenshot at 7월 20 09-21-21.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;POST,GET에서는 위의 단계까지만 하면 끝이었지만 PUT,DELETE는 오류가 발생합니&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Request의 정보들을 각각 body와 path 그리고 기타 request와 관련된 정보들을 함께 넣어주는 템플릿 개념을 추가해주어야 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;자세한 설명은 아래에&amp;nbsp;하겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;API Gateway에서 [Integration Request]를 눌러줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2447353B578EC5931D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2447353B578EC5931D&quot; width=&quot;820&quot; height=&quot;392&quot; filename=&quot;Screenshot at 7월 20 09-22-11.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아래의 [Body Mapping Templates]에서 요청하는 request의 Content-Type을 지정해주시고 가장 기본으로 되어있는 템플릿을 지정합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;자신만의 템플릿을 위해서 해당 템플릿을 가지고 원하시는대로 수정하실 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/250EC639578EC5972C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F250EC639578EC5972C&quot; width=&quot;820&quot; height=&quot;499&quot; filename=&quot;Screenshot at 7월 20 09-23-59.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;requst를 위한 integration을 거치고 [Test]를 수행해줍니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/270B2339578EC5982F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F270B2339578EC5982F&quot; width=&quot;820&quot; height=&quot;374&quot; filename=&quot;Screenshot at 7월 20 09-24-31.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;path 파라미터에 12345를 넣는다는 의미는 PUT /dogs/12345를 실행한다는 의미와 같습니다.&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/250A4039578EC5992E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F250A4039578EC5992E&quot; width=&quot;820&quot; height=&quot;376&quot; filename=&quot;Screenshot at 7월 20 09-24-45.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이렇게 실행을 해주면 우리가 앞서 코드에 넣어둔대로 path로 받은 12345의 id를 결과로 리턴해주게 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그 뿐만 아니라 로그를 보시면 우리가 설정한 템플릿에 나와있는대로&amp;nbsp;각각 body,params 그리고 기타 context들을 출력해주게 됩니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2111CE39578EC59A29&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2111CE39578EC59A29&quot; width=&quot;820&quot; height=&quot;429&quot; filename=&quot;Screenshot at 7월 20 09-25-54.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/26168839578EC59A25&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F26168839578EC59A25&quot; width=&quot;820&quot; height=&quot;501&quot; filename=&quot;Screenshot at 7월 20 09-26-52.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;PUT,DELTE에서 /dogs/12345로 요청하면서 body에 {&quot;id&quot;: &quot;gun0912&quot;}로 들어오고 로그를 찍는것까지 해보았습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;실제 dogs의 12345데이터를 수정,삭제하는 작업은 그 다음단계에서 DB와 연동해서 작업을 해주시면됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Lambda와 API Gateway의 화면이나 구성하는 방법이 계속 바뀌기 때문에 이 글을 읽는 시점에서 위의 단계가 맞지 않을 수도 있습니다...&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 150px; width: 150px; height: 113px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/255F1638578EC9A933&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F255F1638578EC9A933&quot; width=&quot;150&quot; height=&quot;113&quot; filename=&quot;nervous.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 150px; height: 113px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 이 블로그 포스팅을 참고하셔서 각각 POST / GET / PUT / DELETE API를 구성하는 원리를 이해하시고 만드신다면 좀더 이해가 빠르실 겁니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;지금까지 아래와 같은 단계를 통해 포스팅이 이루어졌습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;-&amp;nbsp;&lt;a href=&quot;http://gun0912.tistory.com/59&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[AWS]서버없이 Lambda와 API Gateway로 서버API 만들기&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;-&amp;nbsp;&lt;a href=&quot;http://gun0912.tistory.com/60&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[AWS]Lambda의 시작 - 'Hello World' 출력하기&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;-&amp;nbsp;&lt;a href=&quot;http://gun0912.tistory.com/58&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[카카오톡 옐로아이디]자동응답API 설정하기&lt;/a&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;맨 마지막에는 이 모든걸 종합해서 옐로우아이디에서 채팅을 보내면 보낸내용을 그대로 보내주는 봇을 구성하는 포스팅을 작성해 보겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;( 옐로아이디 &amp;lt;-&amp;gt; API Gateway &amp;nbsp;&amp;lt;-&amp;gt; Lambda )&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;이미 적용되어있는 &amp;nbsp;옐로아이디를 테스트해보고 싶으시다면&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;아래 예시처럼 친구찾기에서 '박상권'을 검색하신뒤 친구추가하시고 테스트해보시거나 아래 링크를 따라서 친구추가해보시면 됩니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://plus.kakao.com/home/ltrrr3dq&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://plus.kakao.com/home/ltrrr3dq&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 355px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/254EA73B578ECB0228&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F254EA73B578ECB0228&quot; width=&quot;200&quot; height=&quot;355&quot; filename=&quot;Screenshot_20160527-093132 (1).png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 355px;&quot;/&gt;&lt;/span&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;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 355px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/21270D35578ECAC207&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F21270D35578ECAC207&quot; width=&quot;200&quot; height=&quot;355&quot; filename=&quot;Screenshot_20160527-090500 (1).png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 355px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;</description>
      <category>IT/AWS</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/63</guid>
      <comments>https://gun0912.tistory.com/63#entry63comment</comments>
      <pubDate>Wed, 20 Jul 2016 09:53:46 +0900</pubDate>
    </item>
    <item>
      <title>Android N requires the IDE to be running with Java 1.8 or later</title>
      <link>https://gun0912.tistory.com/62</link>
      <description>&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Android N requires the IDE to be running with Java 1.8 or later&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 API 24 로 업데이트 하면 xml의 Preview에서 위와같은 오류메세지가 나타납니다.&lt;/p&gt;&lt;p&gt;이미 JDK는 1.8버전으로 깔려 있는데도 자꾸 1.8이상으로 설치하라고만 나옵니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;간단하게 xml에서 기준 api버전을 23이하로 변경하면 바로 나오긴 하지만 여전히 거슬립니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아직 정확한 이유를 알수는 없지만 이렇게하면 정상적으로 해결되긴 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드의&amp;nbsp;Info.plist 파일을 수정하면 됩니다.&lt;/p&gt;&lt;p&gt;OX X의 경우 Android Studio.app에서 [패키지보기]를 선택한뒤 Contents폴더 아래에서&amp;nbsp;Info.plist파일을 찾아볼수 있다.(/Applications/Android\ Studio.app/Contents/Info.plist)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;파일 내용중 아래 JVMVersion key를 찾습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;default prettyprint prettyprinted&quot; style=&quot;margin-top: 0px; margin-bottom: 1em; padding: 5px; border: 0px; width: auto; max-height: 600px; overflow: auto; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(239, 240, 241);&quot;&gt;&lt;code style=&quot;margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; white-space: inherit;&quot;&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;str&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(125, 39, 39);&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;&lt;span class=&quot;typ&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(43, 145, 175);&quot;&gt;JVMVersion&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;str&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(125, 39, 39);&quot;&gt;&amp;lt;string&amp;gt;1.6+,&lt;/span&gt;&lt;span class=&quot;lit&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(125, 39, 39);&quot;&gt;1.7&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;+&amp;lt;/&lt;/span&gt;&lt;span class=&quot;kwd&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(16, 16, 148);&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;code style=&quot;margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; white-space: inherit;&quot;&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(48, 51, 54);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이부분에서 1.6+ 를 지우고 저장하면 거짓말처럼 해결됩니다.&lt;/p&gt;&lt;p&gt;발생원인과 해결되는 이유는 추후에 자세하게 분석후 추가하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-ERROR&amp;amp;SOLVE</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/62</guid>
      <comments>https://gun0912.tistory.com/62#entry62comment</comments>
      <pubDate>Thu, 30 Jun 2016 23:41:11 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]유용한 라이브러리 - TedPermission(마시멜로우 권한체크)</title>
      <link>https://gun0912.tistory.com/61</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 400px; width: 400px; height: 301px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/26415E50574FAB1B32&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F26415E50574FAB1B32&quot; width=&quot;400&quot; height=&quot;301&quot; filename=&quot;marshmallow-permissions-17_0.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 400px; height: 301px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 6.0 마시멜로우버전부터 개발자들에게는 귀찮은(?) 변경이 있었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;카메라를 사용하거나 문자를 읽어오는 등의 권한을 사용할때&lt;/p&gt;&lt;p&gt;기존에는 앱을 다운받을때에만 사용자로부터 동의를 받으면 그이후는 마음대로 권한을 사용할 수 있었지만,&amp;nbsp;&lt;/p&gt;&lt;p&gt;이제는 권한을 사용하는 시점에 사용자에게 권한허가를 받아야 하고 또한 사용자가 언제든지 권한을 켜고끌수 있도록 변경되었습니다.&lt;/p&gt;&lt;p&gt;이 이슈와 관련해서&amp;nbsp;아래 글을 읽어보시면 좀더 많은 도움이 되실겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/55&quot; target=&quot;_blank&quot;&gt;[안드로이드]6.0 마시멜로우 권한체크하고 최적화하기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 글의 내용처럼 기본으로 제공되는 권한체크 함수들을 사용하고 이를 구조화해서 잘 만들기에는 많은 시간과 노력이 필요합니다.&lt;/p&gt;&lt;p&gt;권한을 체크하는 같은 코드를 복사/붙여넣기해서 금방금방 할수도 있겠지만 아주&amp;nbsp;좋지 않은 방식이라고 생각합니다.&lt;/p&gt;&lt;p&gt;&lt;strike&gt;(이렇게 코딩하면 우리 직원들은 저한테 1시간동안 갈굼 당합니다)&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만 걱정할 필요없습니다.&lt;/p&gt;&lt;p&gt;TedPermission이 있다면 권한체크를 아주 간단하고 효과적으로 할&amp;nbsp;수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;TedPermission&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedPermission&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사실 TedPermission은 이름에서 보시면 알 수 있듯이 제가 만든 라이브러리입니다.&lt;/p&gt;&lt;p&gt;(제 영어이름이 Ted Park입니다)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 150px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/226D8A3C574FAE842F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F226D8A3C574FAE842F&quot; width=&quot;200&quot; height=&quot;150&quot; filename=&quot;genius.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 200px; height: 150px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 라이브러리는 제가 수많은 삽질을 거치며 어느정도 구조화해서 만든 권한체크 라이브러리입니다.&lt;/p&gt;&lt;p&gt;기존에 권한체크방식을 설계하고 코딩해보신 분이라면 얼마나 간단하게 줄여졌는지 체감하실 수 있을겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;1. Gradle 추가&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43);&quot;&gt;&lt;p style=&quot;font-family: NanumGothicCoding; font-size: 9pt; color: rgb(169, 183, 198);&quot;&gt;dependencies {&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: NanumGothicCoding; font-size: 9pt; color: rgb(106, 135, 89);&quot;&gt;    &lt;/span&gt;&lt;font color=&quot;#a9b7c6&quot; style=&quot;font-family: NanumGothicCoding; font-size: 9pt;&quot;&gt;compile &lt;/font&gt;&lt;font color=&quot;#6a8759&quot; face=&quot;NanumGothicCoding&quot;&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;'&lt;/span&gt;&lt;span style=&quot;font-size: 12px;&quot;&gt;gun0912.ted:tedpermission:2.0.0&lt;/span&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;'&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;font color=&quot;#a9b7c6&quot; style=&quot;font-family: NanumGothicCoding; font-size: 9pt;&quot;&gt;}&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;RxJava1,RxJava2도 지원합니다.&lt;/p&gt;&lt;p&gt;RxJava를 지원하는 TedPermission은 GitHub에서 직접 확인해주세요&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/ParkSangGwon/TedPermission&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;2.&amp;nbsp;PermissionListener 생성&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;권한이 허가되거나 거부당했을때 결과를 리턴해주는 리스너를 만들어줍니다.&lt;/p&gt;&lt;p&gt;onPermissionGranted()는 권한이 모두 허용 되고나서 실행되며 onPermissionDenied()는 요청한 권한중에서 거부당한 권한목록을 리턴해줍니다.&lt;/p&gt;&lt;p&gt;3개의 권한을 요청했는데 사용자가 1개만 허용하고 2개는 거부한경우 onPermissionDenied()에 2개의 거부당한 권한목록이 전달됩니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;PermissionListener permissionlistener = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;PermissionListener() {&lt;br /&gt;    &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onPermissionGranted&lt;/span&gt;() {&lt;br /&gt;        Toast.&lt;span style=&quot;font-style:italic;&quot;&gt;makeText&lt;/span&gt;(Activity1.&lt;span style=&quot;color:#cc7832;&quot;&gt;this, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;권한 허가&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Toast.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;LENGTH_SHORT&lt;/span&gt;).show()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onPermissionDenied&lt;/span&gt;(ArrayList&amp;lt;String&amp;gt; deniedPermissions) {&lt;br /&gt;        Toast.&lt;span style=&quot;font-style:italic;&quot;&gt;makeText&lt;/span&gt;(Activity1.&lt;span style=&quot;color:#cc7832;&quot;&gt;this, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;권한 거부&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot; &lt;/span&gt;+ deniedPermissions.toString()&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Toast.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;LENGTH_SHORT&lt;/span&gt;).show()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;3. 권한체크 시작&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;TedPermission 클래스를 이용해서 권한체크를 시작합니다.&lt;/p&gt;&lt;p&gt;이때 리스너, 요청하는 권한, 권한요청시 필요한 메세지들 등에 대해서 설정을 해주는 작업을 해주고 check()함수를 통해서 실제로 권한체크를 시작합니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;br /&gt;TedPermission.with(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;br /&gt;        .setPermissionListener(permissionlistener)&lt;br /&gt;        .setRationaleMessage(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;구글 로그인을 하기 위해서는 주소록 접근 권한이 필요해요&quot;&lt;/span&gt;)&lt;br /&gt;        .setDeniedMessage(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;왜 거부하셨어요...&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;하지만 [설정] &amp;gt; [권한] 에서 권한을 허용할 수 있어요.&quot;&lt;/span&gt;)&lt;br /&gt;        .setPermissions(Manifest.permission.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;READ_CONTACTS&lt;/span&gt;)&lt;br /&gt;        .check()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;4. 기타&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;커스터마이징을 지원하는 함수들을 통해서 원하시는 메세지 혹은 버튼이름을 설정할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;setRationaleMessage()&lt;/b&gt;&lt;/p&gt;&lt;p&gt;- 권한을 요청하기전에 이 권한이 필요한 이유에 대해서 설명하는 메세지를 설정합니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;- 기본으로 제공되는&amp;nbsp;shouldShowRequestPermissionRationale()&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 이용해서 이 메세지를 보여준다면,&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;제일 처음 권한을 요청할때는 false가 리턴되서 rationale 메세지를 보여주지 못하지만 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;TedPermission은 처음 요청할때&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;도 rationale 메세지를 보여줍니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;setRationaleConfirmText()&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;-&amp;nbsp;&lt;/b&gt;권한이 필요한 이유에 대해서 설명하는 다이어로그에서 [확인]버튼 텍스트를 설정합니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;setDeniedMessage()&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;-&amp;nbsp;&lt;/b&gt;사용자가 권한을 거부했을때 보여지는 메세지를 설정합니다.&lt;/p&gt;&lt;p&gt;- 여기서 다시한번 사용자가 권한을 허용할수있도록 유도하는 효과적인 메세지가 필요할 수도 있습니다&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;setDeniedCloseButtonText()&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;-&amp;nbsp;&lt;/b&gt;거부했을때 보여지는 메세지 다이어로그에서 [닫기]버튼 텍스트를 설정합니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;setGotoSettingButton()&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;-&amp;nbsp;&lt;/b&gt;사용자가 권한을 거부했을때 보여지는 메세지에서 '설정' 화면으로 갈수있는 버튼을 보여줄지 여부를 결정합니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;setGotoSettingButtonText()&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;-&amp;nbsp;&lt;/b&gt;'설정'화면으로 갈수있는 버튼을 보여주는경우 해당 버튼의 텍스트를 설정합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;동작원리&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;TedPermission의 핵심은 투명한 권한체크 Activity&lt;/span&gt;를 띄우는데에 있습니다.&lt;/p&gt;&lt;p&gt;권한을 체크하려면 권한을 요청하면 onRequestPermissionsResult() 함수로 대응을 해주어야 하기때문에 권한을 요청하는 경우 이 투명한 Activity에서 권한을 체크하고 결과를 리턴해주는 작업을 해줍니다.&lt;/p&gt;&lt;p&gt;&lt;strike&gt;그리고 결과들을 Event bus인 Otto를 이용하여 전달해주고 있습니다.&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/4&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;(&lt;/a&gt;RxJava를 지원하면서 Otto는 사용하지 않게되었습니다)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1. 권한체크 액티비티 시작&lt;/p&gt;&lt;p&gt;2. 체크해야할 권한목록을 가져옴&lt;/p&gt;&lt;p&gt;3-1. 이미 해당 권한들이 허가되어있는경우 권한이 허용되었음을 알림&lt;/p&gt;&lt;p&gt;3-2. 허용되어 있지 않은경우 rationale 메세지가 세팅되어있다면 권한이 필요한 이유를 보여주고 권한허가를 요청(그렇지않은경우 바로 권한허가를 요청)&lt;/p&gt;&lt;p&gt;4. onRequestPermissionsResult()에서 거부된 권한목록을 체크&lt;/p&gt;&lt;p&gt;5-1. 거부된권한이 하나도 없는경우는 모두 허가된것으로 판단하고 권한이 허용되었음을 알림&lt;/p&gt;&lt;p&gt;5-2. 하나라도 권한이 허용되지 않은경우 권한이 허용되지 않았음을 알리고 거부된 권한목록을 함께 보냄&lt;/p&gt;&lt;p&gt;6. 여기서 권한이&amp;nbsp;허용/거부 되었음을 알리는 방법으로는 Otto를 사용해서 Event를 날림&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;좀더 자세한 동작원리는 직접 &lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;TedPermission&lt;/a&gt; 프로젝트를 다운받고 살펴보셔도 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;(내용이 유용하셨다면 Github&amp;nbsp;오른쪽위의&amp;nbsp;[Star]버튼을 눌러주시면 감사하겠습니다&lt;/p&gt;&lt;p&gt;저에게는 별풍선 주시는 효과가 있어요!)&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;600&quot; width=&quot;600&quot; exif=&quot;{}&quot; id=&quot;tx_entry_51030_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/2625B4395917C42F09&quot; height=&quot;304&quot; title=&quot;더블클릭을 하시면 이미지를 수정할 수 있습니다&quot; style=&quot;width: 150px; height: 76px;&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;TedPermission를 유용하게 사용하셔서 사용자로부터 모든권한을 허가받으시고 행복한 개발 하셨으면 하는 마음입니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;사용하시면서 문제가 발생하시거나 좋은 기능을 추가하셨다면&amp;nbsp;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission/issues&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Issues&lt;/a&gt;&amp;nbsp;/&amp;nbsp;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission/pulls&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Pull&lt;/a&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission/pulls&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&amp;nbsp;&lt;/a&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission/pulls&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;requests&lt;/a&gt;를 보내주시면 감사하겠습니다.&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 142px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2150C545574FB63D1B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2150C545574FB63D1B&quot; width=&quot;300&quot; height=&quot;142&quot; filename=&quot;okay.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 300px; height: 142px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/61</guid>
      <comments>https://gun0912.tistory.com/61#entry61comment</comments>
      <pubDate>Thu, 2 Jun 2016 13:43:03 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]Lambda의 시작 - 'Hello World' 출력하기</title>
      <link>https://gun0912.tistory.com/60</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/27535633574B7DE526&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F27535633574B7DE526&quot; width=&quot;200&quot; height=&quot;200&quot; filename=&quot;AmazonLambda-200x200.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;AWS Lambda의 소개 및 서버없이 Restful API서버구성을 만드는 방법이 궁금하시다면 아래 블로그부터 확인하시고 이 글을 따라오시길 권장합니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/59&quot; target=&quot;_blank&quot;&gt;[IT/AWS] - [AWS]서버없이 Lambda와 API Gateway로 서버API 만들기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;Lambda로 'Hello World' 출력하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1.&lt;/b&gt; AWS콘솔에서 Lambda서비스로 이동합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2.&lt;/b&gt; 처음 만드시는경우라면 [Get Started Now]버튼을 눌러 시작합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2755A937574B7D1F22&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2755A937574B7D1F22&quot; width=&quot;820&quot; height=&quot;246&quot; filename=&quot;Screenshot at 5월 30 07-30-49.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;이전에 Lambda function을 만든적이 있다면 [Create a Lambda function]을 클릭합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/244C6A3C574B7D2D01&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F244C6A3C574B7D2D01&quot; width=&quot;820&quot; height=&quot;145&quot; filename=&quot;Screenshot at 5월 30 07-31-04.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;3.&lt;/b&gt; 제일처음 우리를 맞이하는것은 blueprint라는 일종의 템플릿 개념입니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;사람들이 많이 쓰일만한 패턴들의 소스코드들을 이미 템플릿으로 만들어져서 제공하고 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;가장 기본인 'hello world' 예제도 node.js, python용으로 미리 만들어져 있으며 S3, dynamodb, sns등 AWS자체의 서비스와 연동된 템플릿들도 제공을 합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;우리는 저돌적인 개발자이기때문에 쿨하게 [Skip]버튼을 눌러 직접 소스코드를 작성해보겠습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: center;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/24045638574B7D381B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F24045638574B7D381B&quot; width=&quot;820&quot; height=&quot;555&quot; filename=&quot;Screenshot at 5월 30 07-35-04.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;4.&lt;/b&gt; 'Step2'가 제일 메인이 되는 부분의 페이지입니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;Name&lt;/b&gt;이나 &lt;b&gt;Description&lt;/b&gt;은 원하시는대로 작성해주시고 &lt;b&gt;Runtime&lt;/b&gt; ( Node.js , Python, Java )에서 본인이 작성하길 원하는 언어의 코드를 선택해줍니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;이 블로그에서는 Node.js(v0.10.42)를 기준으로 소스코드를 작성할 예정입니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;아래 Lambda function code에서는 직접 소스코드를 작성할수도 있고, 미리 코딩한 파일을 zip파일형태로 업로드하거나 S3를 통해서 가져올수도 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;(저는 실제로 사용할때는 Webstorm을 이용해서 로컬에서 코딩을 끝내고 zip파일을 업로드 하고 있지만 이번 예제에서는 직접 코드를 입력하는 방식으로 진행하겠습니다)&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/214B7E37574B7D492D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F214B7E37574B7D492D&quot; width=&quot;820&quot; height=&quot;478&quot; filename=&quot;Screenshot at 5월 30 07-46-45.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;5.&lt;/b&gt; 다른 설정들보다도 제일 중요한건 Lambda funtion code작성입니다.&lt;/p&gt;&lt;p&gt;아래의 코드는 API Gateway를 통해서 Lambda가 호출됐을때 'Hello World'를 출력해주는 가장 기본적인 코드입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2109A63A574B7D5908&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2109A63A574B7D5908&quot; width=&quot;820&quot; height=&quot;575&quot; filename=&quot;Screenshot at 5월 30 07-49-10.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;여기서 우리는 handler, event, context에 대해서만 알아두면 됩니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;handler&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;handler함수가 Lambda funtion이 시작되는 메인 함수라고 보면 됩니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;이 함수에 앞으로 설명할 event,context가 넘어오고 이를 우리가 컨트롤 해주어야 합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;event&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Node.js에서 request의 개념으로 이해하시면 좋습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Lambda가 실행되면서 전달되는 파라미터값들이&amp;nbsp;event를 통해서 넘겨받게 됩니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;API Gateway와 연동될경우, GET,&amp;nbsp;POST, PUT, DELETE 의 동작에서 넘겨지는 query, body, params등의 값들을 event에서 가져올 수 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;context&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;event가 request개념이었다면 context는 response개념으로 이해하시면 좋습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;context에서 결과로 리턴하는 함수는 &lt;b&gt;done(), succeed(), fail()&lt;/b&gt;이 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;programlisting&quot; style=&quot;padding: 0.5em; font-size: 14px; font-family: 'Courier New', Courier, mono; border: 1px solid rgb(225, 225, 232); border-radius: 3px; color: rgb(68, 68, 68); overflow: auto; background-color: rgb(240, 240, 240);&quot;&gt;&lt;code class=&quot;nohighlight&quot; style=&quot;font-family: 'Courier New', Courier, mono; overflow: auto;&quot;&gt;context.succeed(Object result);&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;결과가 성공했을때&amp;nbsp;리턴해주는 함수입니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;여기서 Object는 json형식의 구조이어야 합니다.&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;물론 result값을 넘겨주지않고 succeed()나 succeed(null)로도 리턴할 수 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;programlisting&quot; style=&quot;padding: 0.5em; font-size: 14px; font-family: 'Courier New', Courier, mono; border: 1px solid rgb(225, 225, 232); border-radius: 3px; color: rgb(68, 68, 68); overflow: auto; background-color: rgb(240, 240, 240);&quot;&gt;&lt;code class=&quot;nohighlight&quot; style=&quot;font-family: 'Courier New', Courier, mono; overflow: auto;&quot;&gt;context.fail(Error error);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;clear: none; float: none;&quot;&gt;결과가 실패했을때 리턴해주는 함수입니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Error또한 값을 넘겨주지않고 사용할 수도 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;여기서 발생한 에러는 CloudWatch에 로그로 남겨지게 됩니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;programlisting&quot; style=&quot;padding: 0.5em; font-size: 14px; font-family: 'Courier New', Courier, mono; border: 1px solid rgb(225, 225, 232); border-radius: 3px; color: rgb(68, 68, 68); overflow: auto; background-color: rgb(240, 240, 240);&quot;&gt;&lt;code class=&quot;nohighlight&quot; style=&quot;font-family: 'Courier New', Courier, mono; overflow: auto;&quot;&gt;context.done(Error error, Object result);&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;결과가 성공이든 실패든 어떠한경우에도 쓰일수 있는 함수입니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;첫번째 파라미터인 error가 null이라면 성공으로, 그렇지않다면 실패로 판단합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;여기서 error가 발생한경우는 fail()처럼 CloudWatch에 로그로 남겨지게 됩니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;만약 Node.js를 v0.10이 아니라 v4.3을 쓰게 된다면 위의 함수들이 아닌 callback()함수를 사용해야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html#transition-to-new-nodejs-runtime&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html#transition-to-new-nodejs-runtime&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;succeed() -&amp;gt; callback()&lt;/p&gt;&lt;pre class=&quot;programlisting&quot; style=&quot;padding: 0.5em; font-size: 14px; font-family: 'Courier New', Courier, mono; border: 1px solid rgb(225, 225, 232); border-radius: 3px; color: rgb(68, 68, 68); overflow: auto; background-color: rgb(240, 240, 240);&quot;&gt;&lt;code class=&quot;nohighlight&quot; style=&quot;font-family: 'Courier New', Courier, mono; overflow: auto;&quot;&gt;// Old way (Node.js runtime v0.10.42).
context.succeed('Success message');  

// New way (Node.js runtime v4.3).
context.callbackWaitsForEmptyEventLoop = false; 
callback(null, 'Success message');  &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;fail() -&amp;gt; callback()&lt;/p&gt;&lt;pre class=&quot;programlisting&quot; style=&quot;padding: 0.5em; font-size: 14px; font-family: 'Courier New', Courier, mono; border: 1px solid rgb(225, 225, 232); border-radius: 3px; color: rgb(68, 68, 68); overflow: auto; background-color: rgb(240, 240, 240);&quot;&gt;&lt;code class=&quot;nohighlight&quot; style=&quot;font-family: 'Courier New', Courier, mono; overflow: auto;&quot;&gt;// Old way (Node.js runtime v0.10.42).
context.fail('Fail object');  

// New way (Node.js runtime v4.3).
context.callbackWaitsForEmptyEventLoop = false; 
callback('Fail object', 'Failed result'); &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;done() -&amp;gt; callback()&lt;/p&gt;&lt;pre class=&quot;programlisting&quot; style=&quot;padding: 0.5em; font-size: 14px; font-family: 'Courier New', Courier, mono; border: 1px solid rgb(225, 225, 232); border-radius: 3px; color: rgb(68, 68, 68); overflow: auto; background-color: rgb(240, 240, 240);&quot;&gt;&lt;code class=&quot;nohighlight&quot; style=&quot;font-family: 'Courier New', Courier, mono; overflow: auto;&quot;&gt;// Old way (Node.js runtime v0.10.42).
context.done(null, 'Success message');  

// New way (Node.js runtime v4.3).
context.callbackWaitsForEmptyEventLoop = false; 
callback(null, 'Success message');  &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Node.js v4.3부터 사용할 수 있는 callback()함수는 아래 링크에서 좀더 자세히 살펴 볼 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html#nodejs-prog-model-handler-callback&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html#nodejs-prog-model-handler-callback&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;위의 handler, event, context 개념을 잘 따라오셨다면 이제 'Hello&amp;nbsp;World' 를 리턴하는 이 소스코드를 이해하실 수 있으실겁니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;6.&lt;/b&gt; 소스코드 작성을 마쳤다면 아래에서 기타 설정들을 확인할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/23095D38574B7D6A17&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F23095D38574B7D6A17&quot; width=&quot;820&quot; height=&quot;518&quot; filename=&quot;Screenshot at 5월 30 08-19-55.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;&lt;b&gt;Handler&lt;/b&gt;&lt;/p&gt;&lt;p&gt;소스코드로 직접 작성할경우 이 파일이름이 index.js파일이 되는 개념이고 handler함수가 메인이기때문에 이 함수를 지정해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Role&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Lambda에서 S3나 Dynamodb처럼 다른 서비스에 접근해야하는 권한이 필요한경우 IAM Role을 만들어서 지정해주어야 합니다.&lt;/p&gt;&lt;p&gt;처음에는 만들어져있는 role이 없으므로 새로 하나 만들어주어야 합니다.&lt;/p&gt;&lt;p&gt;여기서는 가장 기본적인 [Basic execution role]을 선택하도록 하겠습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 466px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2663E936574B7D770A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2663E936574B7D770A&quot; width=&quot;466&quot; height=&quot;267&quot; filename=&quot;Screenshot at 5월 30 08-23-01.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;그다음 화면에서 만드는 과정은 별다르게 건드릴필요 없이 [Allow] 버튼을 누르면 생성됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그 외로 메모리설정이나 타임아웃시간, VPC를 지정할 수 있지만 기본으로 설정되어있는 상태에서 [Next]를 눌러줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;7.&lt;/b&gt; 이제 다 끝났습니다.&lt;/p&gt;&lt;p&gt;마지막으로 우리가 작성한 function내용을 확인하고 [Create funtion]을 눌러주면 완료됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2713E63C574B7D8633&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2713E63C574B7D8633&quot; width=&quot;820&quot; height=&quot;434&quot; filename=&quot;Screenshot at 5월 30 08-25-24.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;8.&lt;/b&gt; 우리가 만든 Lambda function code를 테스트 해볼수도 있습니다.&lt;/p&gt;&lt;p&gt;event로 넘겨줄 값을 설정하고 [Save and test]버튼을 누르면 아래 이미지처럼 우리가 설정해둔 결과를 받아 볼 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/23183634574B7D9610&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F23183634574B7D9610&quot; width=&quot;820&quot; height=&quot;544&quot; filename=&quot;Screenshot at 5월 30 08-30-56.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/222A4C34574B7D9703&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F222A4C34574B7D9703&quot; width=&quot;820&quot; height=&quot;317&quot; filename=&quot;Screenshot at 5월 30 08-31-15.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Lambda function code의 동작원리만 충분히 이해하신다면 기타 부가적인 설정들은 어렵지 않으실겁니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;이번 포스팅에서는 가장 기본적인 코드들과 설정방법에 대해서 알아보았습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Lambda와&amp;nbsp;API Gateway를 이용해서 서버없이 GET, POST, PUT, DELETE동작을 하는 Restful API를 구성하는 방법은 아래 포스팅을 참고하시면 됩니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://gun0912.tistory.com/63&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[AWS]API Gateway - RESTful API만들기&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;감사합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/AWS</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/60</guid>
      <comments>https://gun0912.tistory.com/60#entry60comment</comments>
      <pubDate>Mon, 30 May 2016 08:56:21 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]서버없이 Lambda와 API Gateway로 서버API 만들기</title>
      <link>https://gun0912.tistory.com/59</link>
      <description>&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;서버없이 서버기능을 만든다고?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;이 개념에 대해서 처음 접해보시는분은 언뜻 잘 이해가 되지 않으실겁니다.&lt;/p&gt;&lt;p&gt;붕어없는 붕어빵은 이해가 되는데, 서버없이 서버기능을 만든다니?!&lt;/p&gt;&lt;p&gt;하지만 이 글을 끝까지 읽어보시면 이 말이 이해가 가시게 될겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 300px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2759B940574B86E91A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2759B940574B86E91A&quot; width=&quot;300&quot; height=&quot;300&quot; filename=&quot;lambda apigateway.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 300px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;우리는 먼저 AWS에서 제공하는 &lt;a href=&quot;https://aws.amazon.com/ko/lambda/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Lambda&lt;/a&gt;와 &lt;a href=&quot;https://aws.amazon.com/ko/api-gateway/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;API Gateway&lt;/a&gt;에 대해서 알고 시작해야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;Lambda란?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;blockquote cite=&quot;http://ko.wikipedia.org/wiki/HTML5&quot;&gt;
&lt;p&gt;AWS Lambda를 사용하면 서버를 프로비저닝하거나 관리할 필요 없이 코드를 실행할 수 있습니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;사용한 컴퓨팅 시간만큼만 비용을 지불하고, 코드가 실행되지 않을 때는 요금이 부과되지 않습니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Lambda에서는 사실상 모든 유형의 애플리케이션이나 백엔드 서비스에 대한 코드를 별도의 관리 없이 실행할 수 있습니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;코드를 업로드하기만 하면, Lambda에서 높은 가용성으로 코드를 실행 및 확장하는 데 필요한 모든 것을 처리합니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;다른 AWS 서비스에서 코드를 자동으로 트리거하도록 설정하거나 웹 또는 모바일 앱에서 직접 코드를 호출할 수 있습니다.&lt;/p&gt;
&lt;br /&gt;
&lt;cite&gt;&lt;a href=&quot;https://aws.amazon.com/ko/lambda/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;AWS Lambda 소개내용&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;네, 그런데 제가 읽어도 무슨말인지 정확히 이해가 되지 않습니다...&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 138px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/210EBF49574B844202&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F210EBF49574B844202&quot; width=&quot;250&quot; height=&quot;138&quot; filename=&quot;confuse.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 250px; height: 138px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이해하기 쉽게 예를 들어보겠습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;저는 페이스북의 운영자입니다.&amp;nbsp;&lt;strike&gt;(사실 아닙니다)&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;strike&gt;&lt;br /&gt;&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;사용자가 사진을 페이스북에 올리는경우 원본사진과 함께 원본에 해당하는 썸네일 사진도 저장하고 싶은경우가 생겼습니다.&lt;/p&gt;&lt;p&gt;이럴경우 보통 서버에서 사진을 S3에 업로드 한뒤 따로 해당 이미지의 썸네일을 만드는 작업을 수행하고 다시 S3에 저장을 합니다.&lt;/p&gt;&lt;p&gt;그런데 만약 여러군데에서 사진을 업로드하는경우가 생긴다면 썸네일 만드는 작업을 수행하는걸 여러군데에서 수행하도록 코드를 짜야합니다.&lt;/p&gt;&lt;p&gt;썸네일을 만드는 공통함수로 만들어서 해당 함수만 호출하는 방법도 있지만 &lt;b&gt;이럴때&amp;nbsp;Lambda를 이용하면 간편합니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Lambda가 이미지가 저장되는 S3를 계속 모니터링 하도록 설정합니다.&lt;/p&gt;&lt;p&gt;어느경로를 통해서든지 S3에 새로운 이미지가 추가되는경우 Lambda가 이를 감지하고 미리 지정된 코드를 수행합니다.&lt;/p&gt;&lt;p&gt;미리 지정된코드에는 이미지를 썸네일로 만들고 S3에 저장하는 코드가 들어 있을겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 638px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/25609340574AC5F81F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F25609340574AC5F81F&quot; width=&quot;638&quot; height=&quot;359&quot; filename=&quot;aws-lambda-api-gateway-serverless-architecture-10-638.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;(출처: http://www.slideshare.net/awskorea/serverless-architecture-lambda-api-gateway)&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Lambda는 이 작업만 수행합니다.&lt;/p&gt;&lt;p&gt;별다른 서버가 필요 없습니다.&lt;/p&gt;&lt;p&gt;요금도 매월 일정수준까지 무료로 이용할수있고 요청수,시간만큼만 내면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;현재 Lambda는 Node.js, Python, Java 언어를 지원합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;API Gateway란?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;쉽게 생각하면 '라우터'개념으로도 볼수있습니다.&lt;/p&gt;&lt;p&gt;AWS의 설명에 따르자면 '현관문' 역할을 하기도 합니다.&lt;/p&gt;&lt;p&gt;/user 라는 API의 요청이 왔을때 이를 A서버의 /aaa 로 보낼수도 있고 B서버의 /bbb로 보낼수도 있습니다.&lt;/p&gt;&lt;p&gt;심지어 GET요청을 POST요청으로 바꿔서 연결해줄수도 있고 사용방법은 무궁무진 합니다.&lt;/p&gt;&lt;p&gt;여기에 더불어 위에서 알아봤던 Lambda로 코드를 작성한뒤 API Gateway에서 이 Lambda코드가 실행회도록 연결해줄 수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 638px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2242BF48574AC88102&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2242BF48574AC88102&quot; width=&quot;638&quot; height=&quot;359&quot; filename=&quot;build-and-manage-your-apis-with-amazon-api-gateway-11-638.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;(출처:&amp;nbsp;http://www.slideshare.net/AmazonWebServices/build-and-manage-your-apis-with-amazon-api-gateway)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;아몰랑, 어떻게하는지&lt;/span&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&amp;nbsp;알려줘&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;역시 개발자는 코드로 대화해야 제맛이죠&lt;/p&gt;&lt;p&gt;Lambda와 API Gateway를 이용해서 서버없이 Restful API구성을 해보도록 하겠습니다.&lt;/p&gt;&lt;p&gt;Lambda와 API Gateway를 설정하는 방법에 대해 각각 아래&amp;nbsp;포스팅을 참고하시면 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;Lambda&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/60&quot; target=&quot;_blank&quot;&gt;[IT/AWS] - [AWS]Lambda의 시작 - 'Hello World' 출력하기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;API Gateway&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/63&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[AWS]API Gateway - RESTful API만들기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2개의 블로그 글을 잘 따라오시면서 만드셨다면 여러분은 이미 서버없이 서버구성을 마치셨을겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그리고 이제 우리는 아래와 같은 아키텍처를 이해하고 직접 구성해볼&amp;nbsp;수 있을것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 800px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2372B639574B7EC614&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2372B639574B7EC614&quot; width=&quot;800&quot; height=&quot;600&quot; filename=&quot;squirrelbin-arch.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;어때요 참 쉽죠?&lt;/p&gt;&lt;p&gt;&lt;strike&gt;( 물론 전 어려웠습니다 )&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;strike&gt;&lt;br /&gt;&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 126px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/26327B3E574BE48A18&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F26327B3E574BE48A18&quot; width=&quot;300&quot; height=&quot;126&quot; filename=&quot;relax.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 300px; height: 126px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;AWS로 서버없이(serverless) 서버구성하기 어렵지 않아요&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위와같은 개념에 대해&amp;nbsp;제 블로그 하나만으로는 충분히 이해하기 힘들수 있습니다.&lt;/p&gt;&lt;p&gt;아래 링크들을 통해서 좀더 많은 도움이 되시길 바랍니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://www.slideshare.net/awskorea/serverless-architecture-powered-by-lambda-kiwoan-kim&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://www.slideshare.net/awskorea/serverless-architecture-powered-by-lambda-kiwoan-kim&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blog.outsider.ne.kr/1205&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://blog.outsider.ne.kr/1205&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://aws.amazon.com/ko/blogs/korea/serverless-architecture-by-korean-developers/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://aws.amazon.com/ko/blogs/korea/serverless-architecture-by-korean-developers/&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;</description>
      <category>IT/AWS</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/59</guid>
      <comments>https://gun0912.tistory.com/59#entry59comment</comments>
      <pubDate>Mon, 30 May 2016 08:55:05 +0900</pubDate>
    </item>
    <item>
      <title>[카카오톡 옐로아이디]자동응답API 설정하기</title>
      <link>https://gun0912.tistory.com/58</link>
      <description>&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;카카오톡 옐로아이디&lt;/span&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;가 뭐에요?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 356px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/276C9E4557478B2A09&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F276C9E4557478B2A09&quot; width=&quot;200&quot; height=&quot;356&quot; filename=&quot;unnamed.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 356px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;'옐로아이디는 고객과 소통할 수 있는 카카오톡 비즈니스 아이디입니다' 라고 옐로아이디 홈페이지에 나와있습니다.&lt;/p&gt;&lt;p&gt;옐로아이디의 활용방법은 무궁무진합니다.&lt;/p&gt;&lt;p&gt;음식점이나 쇼핑몰같은 매장 혹은 상점에서 고객관리 혹은 홍보가 가능합니다.&lt;/p&gt;&lt;p&gt;앱서비스나 기타 온라인서비스에서 고객문의나 불만사항접수등의 소통창구로 쓰이기도 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 100px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2536853C57478C8612&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2536853C57478C8612&quot; width=&quot;300&quot; height=&quot;100&quot; filename=&quot;img_ad_yellow_id.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 100px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;( 셀폰 앱서비스의 옐로아이디를 이용한 고객응대 )&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;옐로아이디에 대한 소개나 활용방법은 아래 공식홈페이지에서 확인해보시면 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://yellowid.kakao.com&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://yellowid.kakao.com&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;자동응답API란?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;텔레그램이나 슬랙같은곳에서 봇(Bot)이라는 개념을 들어보셨을겁니다.&lt;/p&gt;&lt;p&gt;네 맞습니다. 그 로봇의 봇(Bot)입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 110px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/232C043857478E321F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F232C043857478E321F&quot; width=&quot;200&quot; height=&quot;110&quot; filename=&quot;robot.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 200px; height: 110px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 봇의 개념은 여러용도로 사용할 수도 있습니다.&lt;/p&gt;&lt;p&gt;주식시황을 알려주는 봇을 만든다고 가정하면 채팅창에 '삼성전자' 라고 치면 현재가를 알려주도록 할수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 321px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/215C634357478EBB1D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F215C634357478EBB1D&quot; width=&quot;200&quot; height=&quot;321&quot; filename=&quot;다운로드.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 321px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;혹은 '심심이'처럼 봇과 대화할수있는 기능도 만들수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 356px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2659DB3F57478F9816&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2659DB3F57478F9816&quot; width=&quot;200&quot; height=&quot;356&quot; filename=&quot;Screenshot_20160527-090500.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 356px;&quot; original=&quot;yes&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이러한 기능을 할수 있도록 카카오 옐로아이디에서는 '자동응답 API'기능을 제공합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;자동응답 API 설정하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;우선 무엇보다도 옐로아이디 계정이 있으셔야 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;계정이 없으시다면 계정을 만드시고 심사를 통과하시면 자동응답 API를 설정하실 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;문제없이 옐로아이디를 만드셨다면 옐로아이디 페이지에서 [자동응답]-[자동응답 API]메뉴를 선택합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2310FB4B5747913D1A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2310FB4B5747913D1A&quot; width=&quot;820&quot; height=&quot;531&quot; filename=&quot;Screenshot at 5월 27 09-11-16.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 화면에서는 이미 자동응답기능이 설정되어 있지만 처음 화면에 들어오시는경우는 자동응답을 위한 앱등록을 해주셔야 합니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/plusfriend/auto_reply&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;자동응답 API&lt;/a&gt;에서는 5개의 API를 제공하고 있고 이에 대한 응답기능이 구현되어 있어야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1) &lt;a href=&quot;https://github.com/plusfriend/auto_reply#51-home-keyboard-api&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;키보드&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;GET /keyboard&lt;/p&gt;&lt;p&gt;- 처음에 사용자가 채팅방에 들어왔을때 사용자에게 아래 키보드에 보여질 내용을 리턴해주어야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2) &lt;a href=&quot;https://github.com/plusfriend/auto_reply#52-메시지-수신-및-자동응답-api&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;메세지&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;POST /message&lt;/p&gt;&lt;p&gt;- 자동응답 API에서 제일 핵심인 내용입니다. 사용자가 보내는 메세지/사진/동영상 을 이 API를 통해서 보내고 서버가 처리해서 그에맞는 응답을 해주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;3) &lt;a href=&quot;https://github.com/plusfriend/auto_reply#53-친구-추가차단-알림-api&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;친구추가&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;POST /friend&lt;/p&gt;&lt;p&gt;- 사용자가 옐로아이디를 친구추가했을때 호출되는 API입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;4) &lt;a href=&quot;https://github.com/plusfriend/auto_reply#53-친구-추가차단-알림-api&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;친구차단&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;DELETE /friend&lt;/p&gt;&lt;p&gt;- 사용자가 옐로아이디를 친구차단했을때 호출되는 API입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;5) &lt;a href=&quot;https://github.com/plusfriend/auto_reply#54-채팅방-나가기&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;채팅방 나가기&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;DELETE /chat_room&lt;/p&gt;&lt;p&gt;- 사용자가 채팅내용을 삭제했을때 호출되는 API입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 기능들을 완성하셨다면 API를 만든 서버주소정보를 입력하고 API테스트를 수행합니다.&lt;/p&gt;&lt;p&gt;문제가 없다면 정상적으로 앱등록이 완료되고 아래와 같은 화면을 보실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2433263C574793BA29&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2433263C574793BA29&quot; width=&quot;820&quot; height=&quot;529&quot; filename=&quot;Screenshot at 5월 27 09-23-10.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사실 관리페이지에서는 단계별로 필요한 정보를 입력하고 설정만 해주면 되기때문에 별로 어려운 작업은 없습니다.&lt;/p&gt;&lt;p&gt;자동응답 API 서버구성은 각자 편하신 언어/플랫폼에서 구성하시면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;자동응답 API가 적용되어있는 옐로아이디를 테스트해보고 싶으시다면&lt;/p&gt;&lt;p&gt;아래 예시처럼 친구찾기에서 '박상권'을 검색하신뒤 친구추가하시고 테스트해보시거나 아래 링크를 따라서 친구추가해보시면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://plus.kakao.com/home/ltrrr3dq&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://plus.kakao.com/home/ltrrr3dq&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 356px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2104C93B574795C838&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2104C93B574795C838&quot; width=&quot;200&quot; height=&quot;356&quot; filename=&quot;Screenshot_20160527-093132.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 356px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;다음에는&amp;nbsp;'자동응답 API'에 응답하기 위한 서버구성을 하는방법에 대해 포스팅하겠습니다.&lt;/p&gt;&lt;p&gt;( AWS에서 서버없이 API Gateway와 Lambda를 이용해서 서버응답API를 구성하는 방법입니다 )&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/기타정보</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/58</guid>
      <comments>https://gun0912.tistory.com/58#entry58comment</comments>
      <pubDate>Fri, 27 May 2016 09:30:19 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]Google Map에 Custom Marker 추가하는 방법</title>
      <link>https://gun0912.tistory.com/57</link>
      <description>&lt;p&gt;우리는 구글지도를 사용하면서 지도위에 찍는 마커를 사용합니다.&lt;/p&gt;&lt;p&gt;기본 Pin과 Pin을 눌렀을때 나오는&amp;nbsp;Snippet이 있지만 기본 Pin형식의 마커가 아닌 특정 정보를 보여주는 마커를 보여주고 싶을때가 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저 아래 예시 이미지를 보겠습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.airbnb.android&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;에어비앤비&lt;/a&gt;와&amp;nbsp;&lt;a href=&quot;https://play.google.com/store/apps/details?id=kr.co.selphone&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;셀폰&lt;/a&gt;&amp;nbsp;서비스에서 보듯이 서버로부터 상점 혹은 호스트의 정보들을 가져와서 해당 위치에 맞게 마커를 찍어줍니다.&lt;/p&gt;&lt;p&gt;그리고 마커가 그냥 Pin모양이 아니라 가격정보 혹은 상점 이름으로 표시해주는 기능이 구현되어 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2572FF4E571EA4FE32&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2572FF4E571EA4FE32&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;Screenshot_20160426-011537.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 445px;&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2553B14B571EA60B35&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2553B14B571EA60B35&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;Screenshot_20160426-081831.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 445px;&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/26620A4B571EA60E35&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F26620A4B571EA60E35&quot; width=&quot;250&quot; height=&quot;444&quot; filename=&quot;Screenshot_20160426-081851.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참고로 에어비앤비는 자체적으로 &lt;a href=&quot;http://nerds.airbnb.com/code/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;기술블로그&lt;/a&gt;를 운영하고있습니다.&lt;/p&gt;&lt;p&gt;여기서 많은 정보를 얻을수 있고 유용한 &lt;a href=&quot;http://airbnb.io/projects/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;오픈소스&lt;/a&gt;도 살펴볼 수 있습니다.&lt;/p&gt;&lt;p&gt;사랑합니다 에어비앤비&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 165px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/25592C34571EB72E0F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F25592C34571EB72E0F&quot; width=&quot;300&quot; height=&quot;165&quot; filename=&quot;love.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 300px; height: 165px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;보통은 아래와 같은 마커였겠지만 위의 에어비엔비나 셀폰의 화면이 좀더 사용자가 필요한 정보만을 직관적으로 보여줄수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px; width: 500px; height: 284px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/277BA445571EA6FB03&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F277BA445571EA6FB03&quot; width=&quot;500&quot; height=&quot;284&quot; filename=&quot;5-pin-google.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 500px; height: 284px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;마커를 Custom해서 우리가 보여주고자하는 정보 자체를 마커로 사용하는 방법에 대해 포스팅해보겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;먼저 최종결과물은 아래와 같이 움직이게 될것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 444px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/277ED93C571E42250F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F277ED93C571E42250F&quot; width=&quot;250&quot; height=&quot;444&quot; filename=&quot;ezgif.com-video-to-gif (2).gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 250px; height: 444px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;위치,가격정보를 받아와서 가격정보를 마커자체로 표시해주고,&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;마커가 선택되었을때 선택된 마커만 선택되어있음을 표시해주고 해당 마커를 지도의 가운데로 위치시킵니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;설명없이 바로 샘플프로젝트를 돌려보고 싶으신분들은 &lt;a href=&quot;https://github.com/ParkSangGwon/GoogleMapCustomMarker&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Github&lt;/a&gt;에서 받아보실 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;# 구현 순서&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;1. 구글지도&amp;nbsp;프로젝트 준비&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2. 선택/비선택 배경이미지 준비(9patch 이미지)&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;3. 커스텀마커를 위한 xml 생성&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;4. 마커에 사용될 위치/기타정보를 포함하는&amp;nbsp;Class 생성&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;5. 샘플 마커정보 목록 생성&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;6. 마커정보로부터 하나씩 마커 추가&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;7. 마커가 선택되었을때 수행할 작업 설정&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;8. 기타 작업&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;1. 구글지도 프로젝트 준비하기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://developers.google.com/maps/documentation/android-api/?hl=ko&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Google Maps Android API&lt;/a&gt;를 참조해서 구글지도를 설정할수도 있지만 New Project에서 구글지도 프로젝트를 바로 만들어 줄수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 600px; width: 600px; height: 394px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/257FD240571EAA4212&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F257FD240571EAA4212&quot; width=&quot;600&quot; height=&quot;394&quot; filename=&quot;Screenshot at 4월 26 08-34-20.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 600px; height: 394px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;물론 지도를 로딩하는데 필요한 API KEY는 각자&lt;a href=&quot;https://console.developers.google.com&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&amp;nbsp;Google API콘솔&lt;/a&gt;에서 발급 받아야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;2. 선택/비선택 배경이미지 준비&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;마커의 배경으로 사용할 이미지는 9patch이미지로 준비되어야 합니다.&lt;/p&gt;&lt;p&gt;가격정보를 TextView에 설정해줄때 9patch이미지로 이미지가 늘어날 부분을 결정해주고 글자가 들어갈 크기도 지정해 줄 수 있습니다.&lt;/p&gt;&lt;p&gt;9patch 이미지에 대해 아직 감이 안오신다면 검색을 통해서 익혀보시기 바랍니다.&lt;/p&gt;&lt;p&gt;(추후 블로그주제로 다루겠습니다.)&lt;/p&gt;&lt;p&gt;미리 제가 만들어둔 아래의 이미지를 사용하셔도 되고 9patch이미지가 준비되어 있다면 그 이미지를 사용하셔도&amp;nbsp;좋습니다.&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 100px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2368DD47571EAC4A18&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2368DD47571EAC4A18&quot; width=&quot;100&quot; height=&quot;76&quot; filename=&quot;ic_marker_phone.9.png&quot; filemime=&quot;image/png&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 100px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/22684747571EAC4A18&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F22684747571EAC4A18&quot; width=&quot;100&quot; height=&quot;76&quot; filename=&quot;ic_marker_phone_blue.9.png&quot; filemime=&quot;image/png&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;3. 커스텀마커를 위한 xml 생성&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;커스텀 마커 xml은 간단합니다.&lt;/p&gt;&lt;p&gt;FrameLayout아래에 가격정보를 설정할 TextView를 넣어주고 배경이미지로 위의 9patch이미지를 설정해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/d4125f74db2973acec514f7781b9f455.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;4.&amp;nbsp;마커에 사용될 위치/기타정보를 포함하는&amp;nbsp;클래스 생성&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;예를들어 상점이라면 상점과 관련된 많은 정보들이 있을겁니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;하지만 여기서는 상점이라고 예를들었을때 해당 상점의 위치와 판매하는 가격정보 3가지만을 가지고 있는 클래스를 만들겠습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;각자 서비스에 맞게 여러가지 변수정보들을 포함시켜주시면 됩니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/07691756fd1777994894a4434d136a6a.js&quot;&gt;&lt;/script&gt;
&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;5. 샘플 마커정보 목록 생성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;위에서 만든 클래스의 샘플리스트를 만들어 줍니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;실제로는 서버에서 해당 정보들의 목록을 받아오고 그 목록을 마커로 추가해주어야 합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;getSampleMarkerItems&lt;/span&gt;() {&lt;br /&gt;    ArrayList&amp;lt;MarkerItem&amp;gt; sampleList = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ArrayList()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;sampleList.add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;MarkerItem(&lt;span style=&quot;color:#6897bb;&quot;&gt;37.538523&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;126.96568&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;2500000&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;sampleList.add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;MarkerItem(&lt;span style=&quot;color:#6897bb;&quot;&gt;37.527523&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;126.96568&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;100000&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;sampleList.add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;MarkerItem(&lt;span style=&quot;color:#6897bb;&quot;&gt;37.549523&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;126.96568&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;15000&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;sampleList.add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;MarkerItem(&lt;span style=&quot;color:#6897bb;&quot;&gt;37.538523&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;126.95768&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;5000&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    for &lt;/span&gt;(MarkerItem markerItem : sampleList) {&lt;br /&gt;        addMarker(markerItem&lt;span style=&quot;color:#cc7832;&quot;&gt;, false&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;샘플로 4개의 MarkerItem을 만들고 추가해줍니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;완성된 샘플리스트에서 커스텀 마커를 추가하는&amp;nbsp;addMarker()를 각각 호출해줍니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;6. 마커정보로부터 하나씩 마커 추가&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;먼저 위에서 커스텀마커를 위해 만들어둔 xml을 가져옵니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setCustomMarkerView&lt;/span&gt;() {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;marker_root_view &lt;/span&gt;= LayoutInflater.&lt;span style=&quot;font-style:italic;&quot;&gt;from&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;).inflate(R.layout.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;marker_layout&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tv_marker &lt;/span&gt;= (TextView) &lt;span style=&quot;color:#9876aa;&quot;&gt;marker_root_view&lt;/span&gt;.findViewById(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;tv_marker&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;setCustomMarkerView() 은 onCreate()나 onMapReady()처럼 액티비티가 초기화되는 부분에 미리 뷰를 설정해주어야 합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;다음 실제 마커를 추가하는 addMarker()함수를 만들어줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private &lt;/span&gt;Marker &lt;span style=&quot;color:#ffc66d;&quot;&gt;addMarker&lt;/span&gt;(MarkerItem markerItem&lt;span style=&quot;color:#cc7832;&quot;&gt;, boolean &lt;/span&gt;isSelectedMarker) {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    LatLng position = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;LatLng(markerItem.getLat()&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;markerItem.getLon())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    int &lt;/span&gt;price = markerItem.getPrice()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;String formatted = NumberFormat.&lt;span style=&quot;font-style:italic;&quot;&gt;getCurrencyInstance&lt;/span&gt;().format((price))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tv_marker&lt;/span&gt;.setText(formatted)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    if &lt;/span&gt;(isSelectedMarker) {&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;tv_marker&lt;/span&gt;.setBackgroundResource(R.drawable.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ic_marker_phone_blue&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tv_marker&lt;/span&gt;.setTextColor(Color.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;WHITE&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;else &lt;/span&gt;{&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;tv_marker&lt;/span&gt;.setBackgroundResource(R.drawable.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ic_marker_phone&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tv_marker&lt;/span&gt;.setTextColor(Color.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;BLACK&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    MarkerOptions markerOptions = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;MarkerOptions()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;markerOptions.title(Integer.&lt;span style=&quot;font-style:italic;&quot;&gt;toString&lt;/span&gt;(price))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;markerOptions.position(position)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;markerOptions.icon(BitmapDescriptorFactory.&lt;span style=&quot;font-style:italic;&quot;&gt;fromBitmap&lt;/span&gt;(createDrawableFromView(&lt;span style=&quot;color:#cc7832;&quot;&gt;this, &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;marker_root_view&lt;/span&gt;)))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    return &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;mMap&lt;/span&gt;.addMarker(markerOptions)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;마커를 추가하기위해서 우리는 마커와 관련된 정보인 MarkerItem과 해당마커가 선택되어있는지 아닌지에 대한 isSelectedMarker정보를 받아옵니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;MarkerItem에서 위치정보와 가격정보를 받아옵니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;받아온 가격정보는 1000같은&amp;nbsp;숫자이지만 이 값을 W1,000 과 같이 표시해주기 위해&amp;nbsp;NumberFormat.getCurrencyInstance().format()를 사용합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;만약 선택되어있는 마커로 표시되어야 한다면 배경이미지를 파란색, 글씨색을 흰색으로 해주고&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;그렇지 않다면 배경이미지를 흰색, 글씨색을 검은색으로 설정하도록 해줍니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;MarkerOptions를 만들어주고 지도에 add하는 작업만 해주면 끝나는데 여기서 우리가 설정한 View를 Bitmap으로 변환해주는 작업이 필요합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;createDrawableFromView() 함수가 이 작업을 수행해 줍니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// View를 Bitmap으로 변환&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private &lt;/span&gt;Bitmap &lt;span style=&quot;color:#ffc66d;&quot;&gt;createDrawableFromView&lt;/span&gt;(Context context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;View view) {&lt;br /&gt;&lt;br /&gt;    DisplayMetrics displayMetrics = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;DisplayMetrics()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;view.setLayoutParams(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ViewGroup.LayoutParams(ViewGroup.LayoutParams.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;WRAP_CONTENT&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;ViewGroup.LayoutParams.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;WRAP_CONTENT&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;view.measure(displayMetrics.&lt;span style=&quot;color:#9876aa;&quot;&gt;widthPixels&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;displayMetrics.&lt;span style=&quot;color:#9876aa;&quot;&gt;heightPixels&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;view.layout(&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;displayMetrics.&lt;span style=&quot;color:#9876aa;&quot;&gt;widthPixels&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;displayMetrics.&lt;span style=&quot;color:#9876aa;&quot;&gt;heightPixels&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;view.buildDrawingCache()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;Bitmap bitmap = Bitmap.&lt;span style=&quot;font-style:italic;&quot;&gt;createBitmap&lt;/span&gt;(view.getMeasuredWidth()&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;view.getMeasuredHeight()&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Bitmap.Config.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ARGB_8888&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;Canvas canvas = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Canvas(bitmap)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;view.draw(canvas)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    return &lt;/span&gt;bitmap&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;이 함수는 넘겨받은 View를 Bitmap으로 변환하는 작업을 해주는데&amp;nbsp;buildDrawingCache()를 통해서 Bitmap으로 변환해줄수 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;이렇게까지 하시면 우리는 샘플리스트의 각각의 정보를 우리가 만든 커스텀 마커로 만들고 지도에 표시해주는 작업을 해줄수가 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/232DB250571EB2401A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F232DB250571EB2401A&quot; width=&quot;250&quot; height=&quot;444&quot; filename=&quot;Screenshot_20160426-091036.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;하지만 이게 끝은 아니죠&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;마커가 선택되었을때의 이미지를 추가해주어야 합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;7. 마커가 선택되었을때 수행할 작업 설정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;background-color:#344134;&quot;&gt;mMap&lt;/span&gt;.setOnMarkerClickListener(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;먼저 구글지도에 markerClickListener를 달아줍니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public boolean &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onMarkerClick&lt;/span&gt;(Marker marker) {&lt;br /&gt;&lt;br /&gt;    CameraUpdate center = CameraUpdateFactory.&lt;span style=&quot;font-style:italic;&quot;&gt;newLatLng&lt;/span&gt;(marker.getPosition())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;mMap&lt;/span&gt;.animateCamera(center)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;changeSelectedMarker(marker)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    return true;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;onMarkerClick()함수에서는&amp;nbsp;마커가 클릭되면 현재 클릭된 마커를 지도의 가운데로 이동시키고,&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;클릭된 마커를 선택된 마커로 변환해주는 함수를 호출합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;changeSelectedMarker&lt;/span&gt;(Marker marker) {&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 선택했던 마커 되돌리기&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;selectedMarker &lt;/span&gt;!= &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;        addMarker(&lt;span style=&quot;color:#9876aa;&quot;&gt;selectedMarker&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, false&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;selectedMarker&lt;/span&gt;.remove()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 선택한 마커 표시&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(marker != &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;selectedMarker &lt;/span&gt;= addMarker(marker&lt;span style=&quot;color:#cc7832;&quot;&gt;, true&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;marker.remove()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;changeSelectedMarker()함수는 약간의 눈속임 작업이 들어갑니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;사용자가 봤을때는 선택되었던게 선택되지않은 이미지로, 선택되지 않았던게 선택된 이미지로 바뀌는것처럼 보일것입니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;하지만 실제는 아래와 같은 작업이 이루어집니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;1. 기존에 선택되어있는 마커정보를 이용해서 같은 내용의 선택되지않은 마커를 추가&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;2. 기존에 선택되어있는 마커를 지도에서&amp;nbsp;삭제&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;3. 새로 선택된 마커를 선택되어있는 마커정보로 추가&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;4. 새로 선택된 마커를 지도에서 삭제&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;또한 같은 addMarker()지만 마커로부터 정보를 가져와서 위에 선언했던 원래의 addMarker()함수를 사용하기위해 별도의 addMarker()함수를 만들어줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private &lt;/span&gt;Marker &lt;span style=&quot;color:#ffc66d;&quot;&gt;addMarker&lt;/span&gt;(Marker marker&lt;span style=&quot;color:#cc7832;&quot;&gt;, boolean &lt;/span&gt;isSelectedMarker) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;double &lt;/span&gt;lat = marker.getPosition().&lt;span style=&quot;color:#9876aa;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    double &lt;/span&gt;lon = marker.getPosition().&lt;span style=&quot;color:#9876aa;&quot;&gt;longitude&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    int &lt;/span&gt;price = Integer.&lt;span style=&quot;font-style:italic;&quot;&gt;parseInt&lt;/span&gt;(marker.getTitle())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;MarkerItem temp = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;MarkerItem(lat&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;lon&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;price)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    return &lt;/span&gt;addMarker(temp&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;isSelectedMarker)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;8. 기타 작업&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;구지 해주지 않아도 되는 작업이지만 필요하다면 추가해줄 작업도 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;우리는 사용자의 편리함을 추구하니까요&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;사랑합니다 고갱님...&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 150px; width: 150px; height: 150px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/27377E34571EB75E04&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F27377E34571EB75E04&quot; width=&quot;150&quot; height=&quot;150&quot; filename=&quot;love2.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 150px; height: 150px;&quot; original=&quot;yes&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;마커가 아닌 지도가 선택되었을때 기존에 선택되어있는 마커는 선택되지 않은것으로 바꿔주는 작업을 해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;mMap&lt;/span&gt;.setOnMapClickListener(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;먼저 지도에 클릭리스너를 달아주고 마커가 아닌 지도가 클릭되면 기존의 선택되어있는 마커를 선택되지않은 마커로 변환해주는 작업을 수행합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onMapClick&lt;/span&gt;(LatLng latLng) {&lt;br /&gt;    changeSelectedMarker(&lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래는 최종  MapsActivity의 소스코드 입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/e3fa3af755ec6004ff1be06ffcd33b12.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;물론 이 프로젝트는 &lt;a href=&quot;https://github.com/ParkSangGwon/GoogleMapCustomMarker&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Github&lt;/a&gt;에서도 확인해보실수 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;(내용이 유용하셨다면 Github&amp;nbsp;오른쪽위의&amp;nbsp;[Star]버튼을 눌러주시면 감사하겠습니다&lt;/p&gt;&lt;p&gt;저에게는 별풍선 주시는 효과가 있어요!)&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;600&quot; width=&quot;600&quot; exif=&quot;{}&quot; id=&quot;tx_entry_51030_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/2625B4395917C42F09&quot; height=&quot;304&quot; title=&quot;더블클릭을 하시면 이미지를 수정할 수 있습니다&quot; style=&quot;width: 150px; height: 76px;&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;다음번에는 구글지도의 Clustering기능을 이용해서 마커가 한번에 몰려있을때는 개수로 표시해주고 줌인을 했을대 상세 마커들을 표시해주는 방법에 대해서 포스팅해보겠습니다.&lt;/p&gt;&lt;p&gt;Clustering이 적용된&amp;nbsp;화면은&amp;nbsp;아래와 같습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/24183F44571EB5F737&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F24183F44571EB5F737&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;Screenshot_20160426-092604.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 445px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;감사합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/57</guid>
      <comments>https://gun0912.tistory.com/57#entry57comment</comments>
      <pubDate>Tue, 26 Apr 2016 09:55:28 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]EditText를 커스텀하여 'X'버튼 추가하기 - ClearEditText</title>
      <link>https://gun0912.tistory.com/56</link>
      <description>&lt;p&gt;우리는 EditText를 구현하면서 사용자의 편의를 위해서 EditText와 겹쳐서&amp;nbsp;'X'버튼을 추가하는 경우가 많습니다.&lt;/p&gt;&lt;p&gt;'X'버튼을 누르면 EditText의 텍스트 내용을 초기화하는 작업을 해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래 화면은&amp;nbsp;제가 운영중인 &lt;a href=&quot;https://play.google.com/store/apps/details?id=kr.co.selphone&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;셀폰&lt;/a&gt;이라는 앱에서 이름을 변경하는 화면입니다.&lt;/p&gt;&lt;p&gt;사용자가 이름을 입력하게 되면 오른쪽에 'X'버튼 아이콘이 보여지고&amp;nbsp;사용자가 'X'버튼을 누르는경우 EditText의 모든 내용을 삭제할수 있도록 해주고 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 281px; width: 281px; height: 500px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/27267F40570BB41D24&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F27267F40570BB41D24&quot; width=&quot;281&quot; height=&quot;500&quot; filename=&quot;Screenshot_20160411-231618.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 281px; height: 500px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사실 이러한 패턴은 많은 안드로이드 앱에서 볼수 있습니다.&lt;/p&gt;&lt;p&gt;안드로이드 SDK tool인 uiautomatorviewer를 이용하여 카카오톡의 '대화방 검색'&amp;nbsp;EditText를 살펴보아도 역시 레이아웃에 EditText와 ImageButton을 겹쳐서 구현해 놓은것을 알 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 700px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2202D638570BB3A40B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2202D638570BB3A40B&quot; width=&quot;700&quot; height=&quot;485&quot; filename=&quot;Screenshot at 4월 11 23-18-50.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;위의 셀폰과&amp;nbsp;카카오톡뿐만 아니라 이와 비슷한 방식으로 구현하는 앱들은 대부분 아래와 같은 방식으로 구현되어 있을것입니다.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;1. 레이아웃 xml에 EditText와 ImageButton(혹은 ImageView)를 겹쳐서 배치(X버튼은 맨 오른쪽으로 위치)&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;2. EditText에 TextWatcher를 추가&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;3. TextWatcher의&amp;nbsp;onTextChanged()에서&amp;nbsp;Text의 길이에 따라 X버튼 보여주기/숨기기&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이게 엄청 복잡한 작업은 아니긴 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 앱의 기능이 많아질수록 EditText의 개수가 늘어나게&amp;nbsp;되면 위와같은 반복작업을 해주어야 합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(255, 0, 0);&quot;&gt;귀찮습니다&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 225px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2635C837570BB73207&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2635C837570BB73207&quot; width=&quot;300&quot; height=&quot;225&quot; filename=&quot;lazy.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 300px; height: 225px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;네, 맞습니다. 이러한 작업이 반복되면 귀찮아 집니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;우리는 귀찮은걸 참을수 없습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;ClearEditText만들기!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;'X'버튼을 함께 포함하고있는 EditText를 커스텀해서 만들어 보겠습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;strike&gt;(설명 읽기&amp;nbsp;귀찮으신분들은&amp;nbsp;&lt;a href=&quot;https://github.com/ParkSangGwon/ClearEditText&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Github&lt;/a&gt;에서 바로&amp;nbsp;다운받아서 실행해보세요)&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/237F3C45570C88C61B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F237F3C45570C88C61B&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;ezgif.com-video-to-gif.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 250px; height: 445px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;ClearEditText 에서 구현해야 하는 기능은 아래와 같습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;1. 'X'버튼을 EditText에 추가&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;2. 텍스트 길이에 따라 'X'버튼 보이기/숨기기&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;3. 'X'버튼이 눌리는 경우 텍스트 초기화&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;4. EditText에 포커스가 있을때에만 'X'버튼을 보이기&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;1. EditText에 'X'버튼 추가&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;AppCompatEditText를 상속받은 ClearEditText 클래스를 만들어 줍니다.&lt;/p&gt;&lt;p&gt;기본으로 생기는 생성자도 3개 모두&amp;nbsp;추가해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public &lt;/span&gt;ClearEditText(&lt;span style=&quot;color:#cc7832;&quot;&gt;final &lt;/span&gt;Context context) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;(context)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;init()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public &lt;/span&gt;ClearEditText(&lt;span style=&quot;color:#cc7832;&quot;&gt;final &lt;/span&gt;Context context&lt;span style=&quot;color:#cc7832;&quot;&gt;, final &lt;/span&gt;AttributeSet attrs) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;(context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;attrs)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;init()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public &lt;/span&gt;ClearEditText(&lt;span style=&quot;color:#cc7832;&quot;&gt;final &lt;/span&gt;Context context&lt;span style=&quot;color:#cc7832;&quot;&gt;, final &lt;/span&gt;AttributeSet attrs&lt;span style=&quot;color:#cc7832;&quot;&gt;, final int &lt;/span&gt;defStyleAttr) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;(context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;attrs&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;defStyleAttr)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;init()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;각 생성자에서 호출할 init()함수를 만들어줍니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;init()에서는 'X'버튼을 추가해주고 Touch,Focus,TextWatcher 리스너를 추가해줄것입니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제 우리는&amp;nbsp;EditText에 'X' 버튼을 추가해주어야 합니다.&lt;/p&gt;&lt;p&gt;여기서는 X버튼으로&amp;nbsp;appcompat에서 제공하는 abc_ic_clear_mtrl_alpha 를 사용하도록 하겠습니다.&lt;/p&gt;&lt;p&gt;혹은&amp;nbsp;자신이 원하는 'X'버튼을 이미지로 사용해도 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;Drawable tempDrawable = ContextCompat.&lt;span style=&quot;font-style:italic;&quot;&gt;getDrawable&lt;/span&gt;(getContext()&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;R.drawable.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;abc_ic_clear_mtrl_alpha&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;clearDrawable &lt;/span&gt;= DrawableCompat.&lt;span style=&quot;font-style:italic;&quot;&gt;wrap&lt;/span&gt;(tempDrawable)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;DrawableCompat.&lt;span style=&quot;font-style:italic;&quot;&gt;setTintList&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;clearDrawable&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;getHintTextColors())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;clearDrawable&lt;/span&gt;.setBounds(&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;clearDrawable&lt;/span&gt;.getIntrinsicWidth()&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;clearDrawable&lt;/span&gt;.getIntrinsicHeight())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;setClearIconVisible(&lt;span style=&quot;color:#cc7832;&quot;&gt;false&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;롤리팝 이하버전을 위해 Compat을 이용해서&amp;nbsp;wrapDrawable을 만들어주고&lt;/p&gt;&lt;p&gt;DrawableCompat을 이용해서 X이미지를 hint의 색깔에 맞춰서 같은 색으로 맞출수 있도록 Tint를 적용해줍니다.&lt;/p&gt;&lt;p&gt;getIntrinsicWidth()와&amp;nbsp;getIntrinsicHeight()를 이용해서 크기를 지정해 줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setClearIconVisible&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;boolean &lt;/span&gt;visible) {&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;clearDrawable&lt;/span&gt;.setVisible(visible&lt;span style=&quot;color:#cc7832;&quot;&gt;, false&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;setCompoundDrawables(&lt;span style=&quot;color:#cc7832;&quot;&gt;null,null, &lt;/span&gt;visible ? &lt;span style=&quot;color:#9876aa;&quot;&gt;clearDrawable &lt;/span&gt;: &lt;span style=&quot;color:#cc7832;&quot;&gt;null,null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;setCompoundDrawables()는 setDrawablePadding과 같은 효과를 줍니다. X버튼이 보여져야 하는경우 EditText의 오른쪽에 위치시킵니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;2. 텍스트 길이에 따라 X버튼 보이기/없애기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;init()에서&amp;nbsp;addTextChangedListener(this)를 추가해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public final void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onTextChanged&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;final &lt;/span&gt;CharSequence s&lt;span style=&quot;color:#cc7832;&quot;&gt;, final int &lt;/span&gt;start&lt;span style=&quot;color:#cc7832;&quot;&gt;, final int &lt;/span&gt;before&lt;span style=&quot;color:#cc7832;&quot;&gt;, final int &lt;/span&gt;count) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(isFocused()) {&lt;br /&gt;        setClearIconVisible(s.length() &amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;beforeTextChanged&lt;/span&gt;(CharSequence s&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;start&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;count&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;after) {&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;afterTextChanged&lt;/span&gt;(Editable s) {&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;Focus상태일때만 판단을 하며 텍스트의 길이가 0보다 크면 보여주고 그렇지 않으면 보여주지 않습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;3. X버튼이 눌리는경우 텍스트 초기화&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;init()에서&amp;nbsp;super.setOnTouchListener(this)를 추가해줍니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public boolean &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onTouch&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;final &lt;/span&gt;View view&lt;span style=&quot;color:#cc7832;&quot;&gt;, final &lt;/span&gt;MotionEvent motionEvent) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;final int &lt;/span&gt;x = (&lt;span style=&quot;color:#cc7832;&quot;&gt;int&lt;/span&gt;) motionEvent.getX()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;clearDrawable&lt;/span&gt;.isVisible() &amp;amp;&amp;amp; x &amp;gt; getWidth() - getPaddingRight() - &lt;span style=&quot;color:#9876aa;&quot;&gt;clearDrawable&lt;/span&gt;.getIntrinsicWidth()) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(motionEvent.getAction() == MotionEvent.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ACTION_UP&lt;/span&gt;) {&lt;br /&gt;            setError(&lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;setText(&lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return true;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;onTouchListener &lt;/span&gt;!= &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;onTouchListener&lt;/span&gt;.onTouch(view&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;motionEvent)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;else &lt;/span&gt;{&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return false;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;X버튼이 보여지고 있고 터치 위치가 X버튼의 위치일경우 text를 초기화 시킵니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;텍스트 에러를 표시해주고 있었다면 에러도 없애주기 위해 setError(null) 처리 해줍니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;이 ClearEditText 에도 터치리스너가 추가 될수 있으므로 터치리스너를 설정할수있는 함수를 제공해주고 터치리스너에게 터치값을 넘겨주어야 합니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setOnTouchListener&lt;/span&gt;( OnTouchListener onTouchListener) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;onTouchListener &lt;/span&gt;= onTouchListener&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;4. EditText에 포커스가 있을때에만 X버튼을 보이기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;init()에서&amp;nbsp;super.setOnFocusChangeListener(this)를 추가해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onFocusChange&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;final &lt;/span&gt;View view&lt;span style=&quot;color:#cc7832;&quot;&gt;, final boolean &lt;/span&gt;hasFocus) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(hasFocus) {&lt;br /&gt;        setClearIconVisible(getText().length() &amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;else &lt;/span&gt;{&lt;br /&gt;        setClearIconVisible(&lt;span style=&quot;color:#cc7832;&quot;&gt;false&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;onFocusChangeListener &lt;/span&gt;!= &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;onFocusChangeListener&lt;/span&gt;.onFocusChange(view&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;hasFocus)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;이 EditText에 포커스가 있는경우는 텍스트의 길이에 따라서 X버튼의 표시여부를 결정합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;포커스가 없는경우는 X버튼을 보여주지 않습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;위의 터치리스너와 마찬가지로 포커스리스너 또한 이 EditText에 추가될수 있으므로 설정할수 있는 함수를 제공하고 포커스변화값을 넘겨주어야 합니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setOnFocusChangeListener&lt;/span&gt;( OnFocusChangeListener onFocusChangeListener) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;onFocusChangeListener &lt;/span&gt;= onFocusChangeListener&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;'아몰랑 그냥 전체 소스코드만 알려줘'&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;라는 분들을 위해 ClearEditText&amp;nbsp;전체 소스코드를 준비했습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 350px; width: 350px; height: 148px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/244C2D42570BCC6B09&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F244C2D42570BCC6B09&quot; width=&quot;350&quot; height=&quot;148&quot; filename=&quot;impatient.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 350px; height: 148px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/ParkSangGwon/931e7ae515be258b08697bee7054febe.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이것도 귀찮으시다면?&amp;nbsp;&lt;a href=&quot;https://github.com/ParkSangGwon/ClearEditText&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Github&lt;/a&gt;에서 프로젝트를 다운받아서 바로 테스트해보세요.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;(내용이 유용하셨다면 Github&amp;nbsp;오른쪽위의&amp;nbsp;[Star]버튼을 눌러주시면 감사하겠습니다&lt;/p&gt;&lt;p&gt;저에게는 별풍선 주시는 효과가 있어요!)&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;600&quot; width=&quot;600&quot; exif=&quot;{}&quot; id=&quot;tx_entry_51030_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/2625B4395917C42F09&quot; height=&quot;304&quot; title=&quot;더블클릭을 하시면 이미지를 수정할 수 있습니다&quot; style=&quot;width: 150px; height: 76px;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;여기에&amp;nbsp;추가할&amp;nbsp;유용한 기능들을 생각해볼 수 있습니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;- xml에서 X버튼 이미지를 지정해서&amp;nbsp;추가해줄수 있도록 하기&lt;/p&gt;&lt;p&gt;- 현재 입력된 글자수를 표시해주는 EditText만들기&lt;/p&gt;&lt;p&gt;- EditText의 내용이 유효하지 않은경우 빨간밑줄 혹은 EditText Shake해주기&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;'CustomView만들기'에 대해서 좀더 궁금하시다면 아래 글을 참고하세요&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/38&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드]CustomView를 만들어서 재사용하기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이글은&amp;nbsp;&lt;a href=&quot;https://medium.com/engineering-at-depop/giving-your-edit-texts-the-all-clear-8ad2579a11ff#.hsbmzfmrk&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Giving your Edit Texts the All Clear&lt;/a&gt; 에서 영감을 받아 작성되었습니다.&lt;/p&gt;&lt;p&gt;&lt;strike&gt;(사실 거의 대부분 갖다 썼...)&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;strike&gt;&lt;br /&gt;&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;감사합니다.&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <category>안드로이드</category>
      <category>커스텀뷰</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/56</guid>
      <comments>https://gun0912.tistory.com/56#entry56comment</comments>
      <pubDate>Tue, 12 Apr 2016 14:05:47 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]6.0 마시멜로우 권한체크하고 최적화하기</title>
      <link>https://gun0912.tistory.com/55</link>
      <description>&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px; line-height: 1.5; width: 500px; height: 264px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/253C363856C66C7512&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F253C363856C66C7512&quot; width=&quot;500&quot; height=&quot;264&quot; filename=&quot;635850530891320980971791703_android-marshmallow.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;line-height: 1.5; width: 500px; height: 264px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;지난 2015년 5월에 열린 Google I/O에서 안드로이드&amp;nbsp;6.0&amp;nbsp;마시멜로우가 공개되었습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://googledevkr.blogspot.kr/2015/06/m.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;여러가지 개선사항들&lt;/a&gt;중 우리 개발자들에게&amp;nbsp;큰 영향력을 끼칠수 있는 권한획득 방식이 변경되었습니다.&lt;/p&gt;&lt;p&gt;물론, 2016년 2월을 기준으로 현재 마시멜로우이상의 기기는 1.2%밖에 되지 않지만 앞으로 그 비율은 점점 늘어날 것입니다.&lt;a href=&quot;http://developer.android.com/intl/ko/about/dashboards/index.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot; style=&quot;line-height: 1.5;&quot;&gt;(안드로이드 OS&amp;nbsp;점유율)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;(2018년 1월기준으로는 55.6%까지 올라왔습니다)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;현재 운영중인 앱에서 안드로이드 6.0 M(MarshMellow)버전과&amp;nbsp;관련된 오류가 없을수도 있지만&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;해당버전에 대해서 대응해 놓지 않을경우 점점 수많은 오류를 맞이하게 될것입니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;이번 포스팅에서는 Permission획득 방식과 어떻게하면 좀더 효율적이게 사용할수 있을지에 대해 알아 보겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;Runtime Permission&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;이전까지 우리는 안드로이드의 권한을 관리하는것에 대해서 큰 어려움을 느끼지 않았습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;사용하는 권한들을 AndroidManifest.xml에 선언해두고 사용자가&amp;nbsp;&lt;b&gt;앱을 설치하는 시점에 한번만 동의를 받으면 그 이후에는 문제없이 해당 권한들을 사용할 수 있었기 때문&lt;/b&gt;입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/231B3A3756C675731F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F231B3A3756C675731F&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_2016-02-18-20-22-27.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용자가 해당 권한을 이 앱에서 사용하는것에 대해서 꺼림직해 하거나 맘에 안든다면 앱을 사용하지 않는 방법밖에 없습니다.&lt;/p&gt;&lt;p&gt;그로인해 수많은 피싱앱이 생기기도 했고 일부 앱에서는 과도한 권한을 요구하는경우도 있었습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://news.naver.com/main/read.nhn?mode=LSD&amp;amp;mid=sec&amp;amp;sid1=105&amp;amp;oid=277&amp;amp;aid=0003573684&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;(앱하나 다운받았더니 '접근권한' 44개 요구…'유리폰' 방지법 발의)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 164px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/236B143556C6757F1F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F236B143556C6757F1F&quot; width=&quot;250&quot; height=&quot;164&quot; filename=&quot;thief.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 250px; height: 164px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만 이제부터 안드로이드 6.0 마시멜로우버전 이상에서는 설치할때 권한허용 여부를 묻지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;앱에서 해당 권한이 필요할때마다 사용자로부터 권한을 허가받도록 변경&lt;/span&gt;되었습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;또한, 사용자가&amp;nbsp;권한을 허가했더라도 사용자는&amp;nbsp;설정화면(설정 &amp;gt; 애플리케이션 &amp;gt; 앱이름 &amp;gt; 권한)을 통해&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;언제든지 권한을 허용/거부&amp;nbsp;할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;그래서 우리는 해당 권한이 실행될때마다 권한을 사용할 수 있는지 확인해야하고, 권한을 사용할 수 없는경우에는 사용자로부터 권한을 허가받는 기능을 추가해주어야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/253B783A56C675AF21&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F253B783A56C675AF21&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_20160218-215821.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&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;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; line-height: 1.5;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2508513A56C675B40E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2508513A56C675B40E&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_20160218-233104.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;line-height: 1.5;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;아직 마시멜로우에&amp;nbsp;대응할&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;마음의 준비가 안되셨나요?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 176px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2363253956C675F42C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2363253956C675F42C&quot; width=&quot;176&quot; height=&quot;134&quot; filename=&quot;embarrassed.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금 마시멜로우 폰에서&amp;nbsp;플레이스토어에 있는 내 앱을 설치하면 오류가 발생할까요?&lt;/p&gt;&lt;p&gt;그렇지 않습니다.&lt;/p&gt;&lt;p&gt;안드로이드에서&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;targetSdkVersion가 23버전보다 아래라면 앱이 설치되면 모든 권한이 허용되어있는 상태에서 시작합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;아직 마음의 준비가 안되셨다면 targetSdkVersion을 22로 두고 개발하세요.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;단, 이미&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;targetSdkVersion을 23으로 올리셨다면 22로 내릴수 없습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;저는 이사실도 모르고 23으로 바로 올려버려서&amp;nbsp;마시멜로대응을 최대한 빨리 하는 상황을 맞이하였습니다..&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;하지만 위에서 언급한것처럼 사용자가 직접 설정페이지에서 해당 권한을 거부할 수도 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;사용자가 수동으로 설정페이지에서 권한을 없애버리면&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;내 앱은 오류가 발생할까요?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;앱이 오류가 발생해서 죽지는 않습니다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;해당 권한을 사용하는 기능을 사용하지 못할뿐입니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;현재 배포되어있는 앱은 오류를 방지하기위한 최소한의 장치로 생각하고&amp;nbsp;우리는 최대한 빨리 마시멜로우 권한획득에 관한 대응을 해&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;놓아야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;모든 권한에 대해서 체크해야 할까요?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그렇지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;당연히 AndroidManifest.xml에서 선언한 모든 권한에 대해서 허가를 받아올 필요는 없습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;구글이 정의한 Normal Permission과 Dangerous Permission중 Dangerous Permission에 대해서만 권한을 체크해주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://developer.android.com/intl/ko/guide/topics/security/permissions.html#normal-dangerous&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Normal and Dangerous Permissions&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래 표는 꼭 Permission을 체크하고 허가를 받아야 하는 Dangerous permissions와 permissions groups입니다.&lt;/p&gt;&lt;p&gt;이외의 Permission들은 체크하지 않으셔도 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;table style=&quot;font-size: 14px; margin: 0.5em 1em 1em 0px; border-collapse: collapse; border-spacing: 0px; border: 0px; width: 699px; color: rgba(0, 0, 0, 0.682353); font-family: Roboto, sans-serif; line-height: 24px; -webkit-user-select: auto !important; background-color: rgb(247, 247, 247);&quot;&gt;&lt;tbody style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;tr style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;th scope=&quot;col&quot; style=&quot;padding: 4px 12px; vertical-align: top; color: rgb(255, 255, 255); border: 1px solid rgb(221, 221, 221); font-weight: normal; -webkit-user-select: auto !important; background-color: rgb(153, 153, 153);&quot;&gt;&lt;p&gt;Permission Group&lt;/p&gt;&lt;/th&gt;&lt;th scope=&quot;col&quot; style=&quot;padding: 4px 12px; vertical-align: top; color: rgb(255, 255, 255); border: 1px solid rgb(221, 221, 221); font-weight: normal; -webkit-user-select: auto !important; background-color: rgb(153, 153, 153);&quot;&gt;Permissions&lt;/th&gt;&lt;/tr&gt;&lt;tr style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission_group.html#CALENDAR&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;CALENDAR&lt;/a&gt;&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;ul style=&quot;padding: 0px; margin: 0px 0px 15px 20px; -webkit-user-select: auto !important;&quot;&gt;&lt;li style=&quot;margin: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#READ_CALENDAR&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;READ_CALENDAR&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul style=&quot;padding: 0px; margin: 0px 0px 0px 20px; -webkit-user-select: auto !important;&quot;&gt;&lt;li style=&quot;margin: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#WRITE_CALENDAR&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;WRITE_CALENDAR&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission_group.html#CAMERA&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;CAMERA&lt;/a&gt;&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;ul style=&quot;padding: 0px; margin: 0px 0px 0px 20px; -webkit-user-select: auto !important;&quot;&gt;&lt;li style=&quot;margin: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#CAMERA&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;CAMERA&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission_group.html#CONTACTS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;CONTACTS&lt;/a&gt;&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;ul style=&quot;padding: 0px; margin: 0px 0px 0px 20px; -webkit-user-select: auto !important;&quot;&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#READ_CONTACTS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;READ_CONTACTS&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#WRITE_CONTACTS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;WRITE_CONTACTS&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#GET_ACCOUNTS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;GET_ACCOUNTS&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission_group.html#LOCATION&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;LOCATION&lt;/a&gt;&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;ul style=&quot;padding: 0px; margin: 0px 0px 0px 20px; -webkit-user-select: auto !important;&quot;&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#ACCESS_FINE_LOCATION&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;ACCESS_FINE_LOCATION&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#ACCESS_COARSE_LOCATION&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;ACCESS_COARSE_LOCATION&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission_group.html#MICROPHONE&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;MICROPHONE&lt;/a&gt;&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;ul style=&quot;padding: 0px; margin: 0px 0px 0px 20px; -webkit-user-select: auto !important;&quot;&gt;&lt;li style=&quot;margin: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#RECORD_AUDIO&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;RECORD_AUDIO&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission_group.html#PHONE&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;PHONE&lt;/a&gt;&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;ul style=&quot;padding: 0px; margin: 0px 0px 0px 20px; -webkit-user-select: auto !important;&quot;&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;READ_PHONE_STATE&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#CALL_PHONE&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;CALL_PHONE&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#READ_CALL_LOG&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;READ_CALL_LOG&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#WRITE_CALL_LOG&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;WRITE_CALL_LOG&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#ADD_VOICEMAIL&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;ADD_VOICEMAIL&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#USE_SIP&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;USE_SIP&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#PROCESS_OUTGOING_CALLS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;PROCESS_OUTGOING_CALLS&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission_group.html#SENSORS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;SENSORS&lt;/a&gt;&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;ul style=&quot;padding: 0px; margin: 0px 0px 0px 20px; -webkit-user-select: auto !important;&quot;&gt;&lt;li style=&quot;margin: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#BODY_SENSORS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;BODY_SENSORS&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission_group.html#SMS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;SMS&lt;/a&gt;&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;ul style=&quot;padding: 0px; margin: 0px 0px 0px 20px; -webkit-user-select: auto !important;&quot;&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#SEND_SMS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;SEND_SMS&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#RECEIVE_SMS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;RECEIVE_SMS&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#READ_SMS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;READ_SMS&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#RECEIVE_WAP_PUSH&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;RECEIVE_WAP_PUSH&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#RECEIVE_MMS&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;RECEIVE_MMS&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission_group.html#STORAGE&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;STORAGE&lt;/a&gt;&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;padding: 4px 12px; vertical-align: top; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; background-color: inherit;&quot;&gt;&lt;ul style=&quot;padding: 0px; margin: 0px 0px 0px 20px; -webkit-user-select: auto !important;&quot;&gt;&lt;li style=&quot;margin: 0px 0px 12px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#READ_EXTERNAL_STORAGE&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;READ_EXTERNAL_STORAGE&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;li style=&quot;margin: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE&quot; style=&quot;color: rgb(3, 155, 229); margin-bottom: 0px; -webkit-user-select: auto !important;&quot;&gt;WRITE_EXTERNAL_STORAGE&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;a name=&quot;declaring&quot; style=&quot;color: rgb(3, 155, 229); font-family: Roboto, sans-serif; font-size: 14px; line-height: 24px; -webkit-user-select: auto !important;&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2 id=&quot;defining&quot; style=&quot;color: rgba(0, 0, 0, 0.870588); clear: left; font-size: 28px; font-weight: 400; line-height: 32px; margin: 24px 0px 0px; font-family: Roboto, sans-serif; -webkit-user-select: auto !important;&quot;&gt;&lt;br /&gt;&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;권한 체크하고&amp;nbsp;요청하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;우리는 이제 권한을 체크하고 사용자에게 요청한뒤 다시 해당 결과값을 받아와야합니다.&lt;/p&gt;&lt;p&gt;이러한 과정에서 우리는 아래 함수들을 사용해야&amp;nbsp;합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;-권한을 가지고있는지 체크하기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; -webkit-user-select: auto !important; background-color: rgb(247, 247, 247);&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/support/v4/content/ContextCompat.html#checkSelfPermission(android.content.Context, java.lang.String)&quot; style=&quot;color: rgb(3, 155, 229); -webkit-user-select: auto !important;&quot;&gt;ContextCompat.checkSelfPermission()&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre style=&quot;font-size: 9pt; color: rgb(169, 183, 198); font-family: NanumGothicCoding; background-color: rgb(43, 43, 43);&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 10pt;&quot;&gt;int &lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;permissionCheck = ContextCompat.&lt;/span&gt;&lt;span style=&quot;font-style: italic; font-size: 10pt;&quot;&gt;checkSelfPermission&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;this,&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;Manifest.permission.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-size: 10pt;&quot;&gt;WRITE_CALENDAR&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 10pt;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;(permissionCheck== PackageManager.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-size: 10pt; line-height: 1.5;&quot;&gt;PERMISSION_DENIED&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; line-height: 1.5;&quot;&gt;){&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;// 권한 없음&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 10pt;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;// 권한 있음&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;- 해당 권한이 필요한 이유 설명해야하는 경우인지 알아오기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; -webkit-user-select: auto !important; background-color: rgb(247, 247, 247);&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#shouldShowRequestPermissionRationale(android.app.Activity, java.lang.String)&quot; style=&quot;color: rgb(3, 155, 229); -webkit-user-select: auto !important;&quot;&gt;shouldShowRequestPermissionRationale()&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;FragmentCompat와&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;ActivityCompat 클래스에서 이 함수를 사용해서 체크할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;해당 함수가 true를 리턴하는경우 우리는 왜 해당 권한이 필요한지를 설명해주고나서 권한 허가를 요청해야 합니다.&lt;/p&gt;&lt;p&gt;만약 권한허가요청 다이어로그에서&amp;nbsp;사용자가 [다시 묻지 않기]를 체크했다면 이 함수는 항상 false를 리턴합니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;처음 권한을 요청하는경우에 이 함수는 항상 false를 요청합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;즉 사용자가 [다시 묻지 않기]를 체크하지 않고, 1번이상 권한요청에 대해 거부한 경우에만 true를 리턴해주고 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;왜 처음 권한을 요청할때 true를 리턴하지 않는지 이해가 가지 않습니다.&lt;/p&gt;&lt;p&gt;아래에서 설명하겠지만 저는 이 함수를 활용하지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;- 권한 허가 요청하기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; -webkit-user-select: auto !important; background-color: rgb(247, 247, 247);&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#requestPermissions(android.app.Activity, java.lang.String[], int)&quot; style=&quot;color: rgb(3, 155, 229); -webkit-user-select: auto !important;&quot;&gt;requestPermissions()&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;FragmentCompat와&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;ActivityCompat 클래스에서 이 함수를 사용해서 사용자에게 권한허가를 요청하는 다이어로그를 띄울수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;(READ_CONTACTS 권한허가를 요청할때의 예제)&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;color: rgb(169, 183, 198); font-family: NanumGothicCoding; background-color: rgb(43, 43, 43);&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;&lt;span style=&quot;font-size: 13.3333px; line-height: 20px;&quot;&gt;// Activity에서 실행하는경우&lt;/span&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(204, 120, 50);&quot;&gt;if &lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;(ContextCompat.&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-style: italic;&quot;&gt;checkSelfPermission&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(204, 120, 50);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;this,&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;Manifest.permission.&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(152, 118, 170); font-style: italic;&quot;&gt;READ_CONTACTS&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;!= PackageManager.&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(152, 118, 170); font-style: italic;&quot;&gt;PERMISSION_GRANTED&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;) {&lt;/span&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(128, 128, 128);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;// 이 권한을 필요한 이유를 설명해야하는가?&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(128, 128, 128);&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(204, 120, 50);&quot;&gt;if &lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;(ActivityCompat.&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-style: italic;&quot;&gt;shouldShowRequestPermissionRationale&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(204, 120, 50);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;this,&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;Manifest.permission.&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(152, 118, 170); font-style: italic;&quot;&gt;READ_CONTACTS&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;)) {&lt;/span&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(128, 128, 128);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(128, 128, 128);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;        // 다이어로그같은것을 띄워서 사용자에게 해당 권한이 필요한 이유에 대해 설명합니다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(128, 128, 128);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;        // 해당 설명이 끝난뒤 requestPermissions()함수를 호출하여 권한허가를 요청해야 합니다&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(128, 128, 128);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(128, 128, 128);&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(204, 120, 50);&quot;&gt;else &lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(128, 128, 128);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(128, 128, 128);&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;ActivityCompat.&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-style: italic;&quot;&gt;requestPermissions&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(204, 120, 50);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;this,&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(204, 120, 50);&quot;&gt;                new &lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;String[]{Manifest.permission.&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(152, 118, 170); font-style: italic;&quot;&gt;READ_CONTACTS&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(204, 120, 50);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(204, 120, 50);&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;MY_PERMISSIONS_REQUEST_READ_CONTACTS)&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(204, 120, 50);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(204, 120, 50);&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(128, 128, 128);&quot;&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;// 필요한 권한과 요청 코드를 넣어서 권한허가요청에 대한 결과를 받아야 합니다&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 9pt; color: rgb(128, 128, 128);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; color: rgb(128, 128, 128);&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;font-size: 9pt;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;-&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;권한허가 요청후 결과 가져오기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; -webkit-user-select: auto !important; background-color: rgb(247, 247, 247);&quot;&gt;&lt;a href=&quot;http://developer.android.com/reference/android/support/v4/app/ActivityCompat.OnRequestPermissionsResultCallback.html#onRequestPermissionsResult(int, java.lang.String[], int[])&quot; style=&quot;color: rgb(3, 155, 229); -webkit-user-select: auto !important;&quot;&gt;onRequestPermissionsResult()&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;이 함수는 Activity의&amp;nbsp;onActivityResult()와 비슷한 개념입니다.&lt;/p&gt;&lt;p&gt;위의 예제에서&amp;nbsp;MY_PERMISSIONS_REQUEST_READ_CONTACTS로 보낸 요청코드에 대해서 결과값을 가져오고 그에대한 처리를 해주어야 합니다.&lt;/p&gt;&lt;pre style=&quot;font-size: 9pt; color: rgb(169, 183, 198); font-family: NanumGothicCoding; background-color: rgb(43, 43, 43);&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(187, 181, 41);&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 198, 109);&quot;&gt;onRequestPermissionsResult&lt;/span&gt;(&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;int &lt;/span&gt;requestCode&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;                                       &lt;/span&gt;String permissions[]&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;, int&lt;/span&gt;[] grantResults) {&lt;br /&gt;    &lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;switch &lt;/span&gt;(requestCode) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;case &lt;/span&gt;MY_PERMISSIONS_REQUEST_READ_CONTACTS: &lt;br /&gt;            &lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;if &lt;/span&gt;(grantResults.&lt;span style=&quot;color: rgb(152, 118, 170);&quot;&gt;length &lt;/span&gt;&amp;gt; &lt;span style=&quot;color: rgb(104, 151, 187);&quot;&gt;0&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(104, 151, 187);&quot;&gt;                    &lt;/span&gt;&amp;amp;&amp;amp; grantResults[&lt;span style=&quot;color: rgb(104, 151, 187);&quot;&gt;0&lt;/span&gt;] == PackageManager.&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic;&quot;&gt;PERMISSION_GRANTED&lt;/span&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        &lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;// 권한 허가&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;                // 해당 권한을 사용해서 작업을 진행할 수 있습니다&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;/span&gt;} &lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;else &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;       &lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;// 권한 거부&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;                // 사용자가 해당권한을 거부했을때 해주어야 할 동작을 수행합니다&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;            &lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;return;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;    &lt;/span&gt;}&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128);&quot;&gt; &lt;/span&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;최적화하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; line-height: 1.5;&quot;&gt;&lt;b&gt;- Intent를 활용하자&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용자에게 하는 권한허가요청을 줄이는것이&amp;nbsp;사용자와 개발자 모두의 정신건강에&amp;nbsp;좋습니다.&lt;/p&gt;&lt;p&gt;그래서 꼭 해당 권한을 사용하지 않고 intent로 대체해서 사용할 수 있다면 그렇게 해주는것이 좋습니다.&lt;/p&gt;&lt;p&gt;만약 카메라로 사진을 찍고 이미지를 가져와야하는경우 카메라뷰를 커스텀해서 사용하는것이 아니라면 CAMERA권한을 허가요청할 필요 없이 ACTION_IMAGE_CAPTURE를 이용해 intent를 날리면 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;Intent중 권한이 필요없는 것들을 살펴보시고 권한허가를 요청하지 않고&amp;nbsp;구현해보시기 바랍니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://developer.android.com/intl/ko/guide/components/intents-common.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;안드로이드에서 제공하는 Intent목록&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;+2016.06.30&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;그런데 이것은 100% 맞는 상황이 아니었습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;만약 Manifest에 아래와 같이 카메라권한을 추가한 경우라면 ACTION_IMAGE_CAPTURE를 사용하더라도 카메라권한을 허가받아야 합니다...&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;uses-permission &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.permission.CAMERA&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;다른 부분에서 사용되는 카메라권한인데도 선언되어있다는 이유만으로 허가를 받아야 하다니 이상한 부분입니다...&lt;/p&gt;&lt;p&gt;Manifest에 카메라권한이 선언되어있지 않다면 위에 쓰여진대로 권한허가 없이 ACTION_IMAGE_CAPTURE 인텐트만 날려도 사용할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;- 안드로이드 4.4 킷캣(API 19)이상이라면 READ_EXTERNAL_STORAGE 권한이 필요 없습니다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;4.4 이전버전에서는 파일을 읽어오려면&amp;nbsp;READ_EXTERNAL_STORAGE 권한이 꼭 필요 했었습니다.&lt;/p&gt;&lt;p&gt;권한이 없다면&amp;nbsp;getExternalStoragePublicDirectory()를 사용할 수 없었습니다.&lt;/p&gt;&lt;p&gt;하지만 4.4 킷캣이상부터는 권한이 필요 없이 getExternalFilesDir(String),&amp;nbsp;getExternalCacheDir()를 통해 파일을 가져올 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://developer.android.com/intl/ko/about/versions/android-4.4.html#Behaviors&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Android 4.4 APIs&amp;nbsp;&lt;/a&gt;&lt;a href=&quot;http://developer.android.com/intl/ko/about/versions/android-4.4.html#Behaviors&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Important Behavior Changes&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;- 필요한 시점에만 권한을 요청하자&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;네 맞습니다. 사실 귀찮습니다.&lt;/p&gt;&lt;p&gt;개발자 입장에서 생각해보면 권한을 사용할때마다 권한을 체크하고, 사용자로부터 허가를 요청하고 또 그에대한 처리를 해주는 과정이 너무 복잡하고 귀찮습니다.&lt;/p&gt;&lt;p&gt;그래서 일부 앱에서는 앱을 시작할때부터 모든 권한을 요구하는 경우도 있습니다.&lt;/p&gt;&lt;p&gt;가장 많은 사용자가 있을것 같은데&amp;nbsp;[올레 고객센터]앱은 이렇게 만들어져 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/241A623756C6762621&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F241A623756C6762621&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_20160219-005041.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;앱을 시작하자마자 사용자로부터 6개의 권한허용을 요구합니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;개발자 입장에서는 앱 처음에만 권한을 검사해서 처리하면 편하지만, 사용자입장에서는 굉장이 불쾌하고 불편하게 만듭니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;왜 각각 6개의 권한이 여기서 쓰이는지에 대한 설명도 없을뿐더러, 아직 사용하지도 않았고 사용하지 않을지도 모르는 권한들을 애초에 요청한다는것 자체가 좋지 않은 방법 이기 때문입니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;그렇기 때문에 우리는 해당권한을 사용하게 되는 시점에 해당 권한 허가여부를 체크하고 사용자에게 권한허가를 요청해야합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;- 왜 이 권한이 필요한지 알려주자&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위에서 말씀드린것처럼&amp;nbsp;shouldShowRequestPermissionRationale()를 이용하면 이유를 알려줘야 하는 시점을 알 수 있습니다.&lt;/p&gt;&lt;p&gt;하지만 맨처음 권한을 요청하는경우에 이 함수는 항상 false를 리턴하기때문에 사용자에게 권한이 필요한 이유를 설명하는데 이 함수는 필요 없다고 판단했습니다.&lt;/p&gt;&lt;p&gt;그래서 사용자가 해당 권한을 거부했을때 왜 이 권한이 필요한지 알려주고,&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;이미 거부를 했더라도 사용자가 권한을 허가해주길 원하는경우 직접 [설정]에 들어가서 권한을 추가해줄 수 있도록 다이얼로그를 만들어주었습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/233D433C56C6766B14&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F233D433C56C6766B14&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_20160219-083249.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;- 만약 권한요청을 처음하는데도 권한 요청하는 시스템팝업이 안뜬다면?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;의심 1&lt;/b&gt;&lt;/p&gt;&lt;p&gt;: 권한이 Manifest에 잘 정의되어있고 올바른 권한 이름으로 요청하는지 확인하세요&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;의심 2&lt;/b&gt;&lt;/p&gt;&lt;p&gt;: 라이브러리에서 해당 권한을 Manifest에 android:maxSdkVersion로 넣어두는경우, 해당 버전보다 디바이스 버전이 높다면 시스템팝업이 뜨지 않습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;uses-permission&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:maxSdkVersion=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;19&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;: 이럴경우 해당 권한의 설정을 내 app의 Manifest설정으로 재정의 해줘야 합니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;uses-permission&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;tools&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:node=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;replace&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;그래도 여전히 귀찮습니다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 최적화하기에서 말씀드린것처럼 우리는 권한을 사용하는 시점에 권한을 체크하고 사용자에게 권한허가를 요청해야 합니다.&lt;/p&gt;&lt;p&gt;네 알고 있죠 암요...알고 있습니다.&lt;/p&gt;&lt;p&gt;하지만 우리는 너무 귀찮습니다.&lt;/p&gt;&lt;p&gt;권한체크 이벤트가 발생할때마다&lt;/p&gt;&lt;p&gt;- 권한을 체크해야 하고(checkSelfPermission)&lt;/p&gt;&lt;p&gt;- 권한을 요청해야 하고(requestPermissions)&lt;/p&gt;&lt;p&gt;- 권한요청에 대한 결과를 받아서 판단해야합니다(onRequestPermissionsResult)&lt;/p&gt;&lt;p&gt;- 또한 위의 최적화하기에서&amp;nbsp;사용자가 권한을 허용하지 않았더라도 다이얼로그에서 설정에서 직접가서 권한을 허용할수 있게 안내할수&amp;nbsp;있는데 그러한 경우에 사용자가 설정화면에서 다시 앱으로 돌아온경우(onActivityResult)를 확인해서 권한이 허용되었는지 아닌지를 판단해야만 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;물론 잘하시는 개발자분들은 공통으로 사용하는 부분들을 BaseActivity나 PermissionHelper라는 개념의 클래스를 만들어서 최대한 코딩량을 줄이시려고 노력하고 계실겁니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;하지만 그래도 여전히 뭔가 불편함을 느끼시고 계실겁니다.&lt;/p&gt;&lt;p&gt;어떠한 방법을 쓰더라도 결국엔 BaseActivity와 BaseFragment에 각각&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;onRequestPermissionsResult()를 만들어주어야 할 것이고, 그 외에도 어쩔수 없이 반복해야하는 작업들이 있을겁니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;저도 정말 수많은 고민을 하고 이 귀찮음&amp;nbsp;때문에 잠을 이루지 못했습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;strike&gt;사실 잠은 잘 잤습니다.&lt;/strike&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;다른 개발자분들의 최적화에 대한 고민 담긴 블로그입니다.&lt;/p&gt;&lt;p&gt;-&amp;nbsp;&lt;a href=&quot;http://developer.dramancompany.com/2015/11/%EB%A6%AC%EB%A9%A4%EB%B2%84%EC%9D%98-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-6-0-m%EB%B2%84%EC%A0%84-%EB%8C%80%EC%9D%91%EA%B8%B0/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;리멤버의 안드로이드 6.0 M버전 대응기&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;그래서 TedPermission&lt;/span&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;라이브러리를 만들었습니다&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot; style=&quot;line-height: 1.5;&quot;&gt;TedPermission&lt;/a&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot; style=&quot;line-height: 1.5;&quot;&gt;:&amp;nbsp;Easy check permission library for Android Marshmallow&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용방법은 간단합니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;권한요청에 대한 결과를 받아오는 리스너를 만들고, 권한을 체크하기만 하면 됩니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;TedPermission이 알아서 다 해줍니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/61&quot; target=&quot;_blank&quot;&gt;[IT/Android-TIP (한글)] - [안드로이드/Android]유용한 라이브러리 - TedPermission(마시멜로우 권한체크)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;font-size: 9pt; color: rgb(169, 183, 198); font-family: NanumGothicCoding; background-color: rgb(43, 43, 43);&quot;&gt;&lt;pre style=&quot;background-color: rgb(43, 43, 43); font-family: NanumGothicCoding; font-size: 9pt;&quot;&gt;&lt;p&gt;PermissionListener permissionlistener = &lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;new &lt;/span&gt;PermissionListener() {&lt;br /&gt;    &lt;span style=&quot;color: rgb(187, 181, 41);&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(187, 181, 41);&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 198, 109);&quot;&gt;onPermissionGranted&lt;/span&gt;() {&lt;br /&gt;        Toast.&lt;span style=&quot;font-style: italic;&quot;&gt;makeText&lt;/span&gt;(Activity1.&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;this, &lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;권한 허가&quot;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;, &lt;/span&gt;Toast.&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic;&quot;&gt;LENGTH_SHORT&lt;/span&gt;).show()&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(187, 181, 41);&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(187, 181, 41);&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 198, 109);&quot;&gt;onPermissionDenied&lt;/span&gt;(ArrayList&amp;lt;String&amp;gt; deniedPermissions) {&lt;br /&gt;        Toast.&lt;span style=&quot;font-style: italic;&quot;&gt;makeText&lt;/span&gt;(Activity1.&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;this, &lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;권한 거부&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot; &lt;/span&gt;+ deniedPermissions.toString()&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;, &lt;/span&gt;Toast.&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic;&quot;&gt;LENGTH_SHORT&lt;/span&gt;).show()&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;TedPermission.with(&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;this&lt;/span&gt;)&lt;br /&gt;        .setPermissionListener(permissionlistener)&lt;br /&gt;        .setRationaleMessage(&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;구글 로그인을 하기 위해서는 주소록 접근 권한이 필요해요&quot;&lt;/span&gt;)&lt;br /&gt;        .setDeniedMessage(&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;&quot;왜 거부하셨어요...&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: rgb(106, 135, 89);&quot;&gt;하지만 [설정] &amp;gt; [권한] 에서 권한을 허용할 수 있어요.&quot;&lt;/span&gt;)&lt;br /&gt;        .setPermissions(Manifest.permission.&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic;&quot;&gt;READ_CONTACTS&lt;/span&gt;)&lt;br /&gt;        .check()&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;경우의수&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래내용은 TedPermission에서 사용하는 권한체크 Workflow입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/25320A3356C6767F0C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F25320A3356C6767F0C&quot; width=&quot;820&quot; height=&quot;645&quot; filename=&quot;Screenshot at 2월 18 19-44-11.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;1. Permission 체크 &amp;gt; 권한이 허용되어 있는 경우&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;: onPermissionGranted()를&amp;nbsp;호출합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;2.&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;Permission 체크 &amp;gt; 권한이 허용되어 있지 않은 경우&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;: 권한허가를 요청하는 다이얼로그가 실행됩니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 355px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2662883356C676BD20&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2662883356C676BD20&quot; width=&quot;200&quot; height=&quot;355&quot; filename=&quot;Screenshot_20160218-165011.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 355px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;3. 권한허가 다이얼로그 &amp;gt; 허용&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;:&amp;nbsp;onPermissionGranted()를 호출합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;4. 권한허가 다이얼로그 &amp;gt; 거부&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;: 권한이 거부되는경우 위에서 설명한대로&amp;nbsp;해당 권한이 필요한 이유와 함께 사용자가 설정에서 수동으로 권한을 추가해줄수 있도록 [설정]버튼을 함께 보여줍니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 356px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2365B93956C676D12F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2365B93956C676D12F&quot; width=&quot;200&quot; height=&quot;356&quot; filename=&quot;Screenshot_20160218-165356.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 356px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;5. 권한거부 및&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;권한이유설명&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;다이얼로그 &amp;gt; 닫기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;:&amp;nbsp;onPermissionDenied()를 호출합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;6. 권한거부 및 권한이유설명 다이얼로그 &amp;gt; 설정&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;: 앱의 설정페이지로 이동합니다. 이때 startActivityForResult()로 실행해주기 때문에 다시 앱으로 돌아올때는 onActivityResult()에서 받을 수 있습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 356px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/255A493456C676F62B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F255A493456C676F62B&quot; width=&quot;200&quot; height=&quot;356&quot; filename=&quot;Screenshot_20160218-165602.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 356px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;7. 설정 액티비티 &amp;gt;&amp;nbsp;onActivityResult()&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;: 해당권한이 허용되어있는지를 체크합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;8. 해당권한 허용여부 체크 &amp;gt; 허용되어있음&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;:&amp;nbsp;onPermissionGranted()를 호출합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;9.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;해당권한 허용여부 체크 &amp;gt; 허용되어있지 않음&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;:&amp;nbsp;onPermissionDenied()를 호출합니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;TedPermission 라이브러리의 상세 구현방법에 대해는 다음번 포스팅에서 다뤄보도록 하겠습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;물론&amp;nbsp;&lt;a href=&quot;https://github.com/ParkSangGwon/TedPermission&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;GitHub&lt;/a&gt;에서 데모 프로젝트를 다운받으신뒤에 구조를 파악하셔도 좋습니다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;strike&gt;사실 여기에 다 올리려고 했으나 체력적인 한계로 인해 다음포스팅으로 미룹니다.&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금까지 안드로이드 6.0 마시멜로우버전에서 변경된 권한획득 방법에 대해 포스팅 해보았습니다.&lt;/p&gt;&lt;p&gt;어때요 참 쉽죠?&lt;/p&gt;&lt;p style=&quot;clear: none; float: none; text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 141px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2660123456C6770C2B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2660123456C6770C2B&quot; width=&quot;250&quot; height=&quot;141&quot; filename=&quot;sad.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 250px; height: 141px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;권한체크 방식으로 인해 소스코드 대부분을 뒤집어 엎어야 하는 상황이 발생할수도 있지만 구글형이 까라면 까야죠..&lt;/p&gt;&lt;p&gt;사실 마시멜로우에서 변경된 Doze모드에 대한 대응도 아직 하지 않았죠.&lt;/p&gt;&lt;p&gt;아직도 갈길이 머네요..&lt;/p&gt;&lt;p&gt;앞으로의 버전에서는 또 어떻게 바뀔지 기대&lt;strike&gt;(걱정)&lt;/strike&gt;됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 개발자끼리 소통하기위한 오픈채팅방을 만들었습니다.&lt;/p&gt;&lt;p&gt;안드로이드 관련 Q&amp;amp;A및 팁을 공유하는 곳입니다.&lt;/p&gt;&lt;p&gt;관심있으신분들은 참여해보세요.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://open.kakao.com/o/g8rSGB&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://open.kakao.com/o/g8rSGB&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/55</guid>
      <comments>https://gun0912.tistory.com/55#entry55comment</comments>
      <pubDate>Fri, 19 Feb 2016 10:12:31 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]오류 리포팅 서비스 비교(Google Analytics, URQA, Userhabit, Fabric)</title>
      <link>https://gun0912.tistory.com/53</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 272px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2448593956AF3D170C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2448593956AF3D170C&quot; width=&quot;272&quot; height=&quot;218&quot; filename=&quot;Screenshot at 2월 01 20-10-01.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;학교 과제 제출용이든, 회사 테스트 프로젝트든, 스타트업 서비스를 운영하시든 각자 여러가지 이유로 안드로이드 앱을 개발하고 계실겁니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;strike&gt;(저는 스타트업하는 불효자식입니다...)&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;strike&gt;&lt;br /&gt;&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;그렇게 안드로이드 앱을 개발하고나면&amp;nbsp;드디어 플레이스토어에 배포할&amp;nbsp;날이 옵니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;저는 개발자 콘솔에 배포용 APK를 처음 올리던 감격을 아직도 잊을수가 없습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 150px; width: 150px; height: 138px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/237A0E3D56AF306127&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F237A0E3D56AF306127&quot; width=&quot;150&quot; height=&quot;138&quot; filename=&quot;nice.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 150px; height: 138px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;축하드립니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;드디어 플레이스토어에 앱이 올라갔습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;하지만,&lt;/span&gt; 사실 진짜 문제는 지금부터 시작입니다.&lt;/p&gt;&lt;p&gt;분명히 내가 테스트했을때는 잘되던것들이 사용자들은 안되기 시작하고&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;생각지도 못했던 부분에 문제가 발생하는 일이 생길겁니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;더 큰 문제는 이러한 문제들을 우리가 알 수 없다는 것입니다..&lt;/p&gt;&lt;p&gt;가끔 아주 착하거나 의욕적인 사용자분들은 개발자 이메일로 보내서 오류를 알려주시기도 하고&amp;nbsp;해당 어플 리뷰에 오류가 난다고 도배되는 현상이 발생하게 됩니다.&lt;/p&gt;&lt;p&gt;물론 개발자콘솔의 '다운및 ANR'이 있긴하지만 사용자가 보고를 하지 않는이상 우리는 절대 알길이 없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;그래서 우리는 오류를 추적하고 해결해야만 합니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;제가 사용해본 오류 리포팅 서비스(혹은 그에 준하는 기능을 제공하는&amp;nbsp;서비스)는 Google Analytics, URQA&lt;/span&gt;, Userhabit, Fabric Crashlytics입니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;그외에 New Relic, ACRA등이 있지만 제가 사용해본 서비스가 아니기때문에 제외하였습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;결론적으로 제가 가장 만족스러웠던 리포팅&amp;nbsp;툴은&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;F&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;abric Crashlytics입니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;p&gt;Google Analytics(GA)&lt;/p&gt;&lt;/h2&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.google.com/analytics/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;홈페이지&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://developers.google.com/analytics/devguides/collection/android/v4/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;연동&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://developers.google.com/analytics/devguides/collection/android/v4/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;방법&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;엄밀히 말하면 에러 리포팅만을 위한&amp;nbsp;툴은 아닙니다. 오류분석보다는 더 많은 다양한 용도로 쓰이는게 GA입니다.&lt;/p&gt;&lt;p&gt;오류분석외에 다른 용도로는 정말 좋은기능들이 많아서 실제 서비스를 운영하신다면 꼭 추가하셔서 사용하시길 추천합니다.&lt;/p&gt;&lt;p&gt;(일별 다운로드/사용자 숫자, 실시간 사용자, utm source를 이용한 플레이스토어 다운로드 경로, custom event를 통한 사용자 이용패턴 분석, 사용자 성별/나이/관심분야 등등)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;물론 [충돌 및 예외]에서 사용자의 오류를 확인해볼 수 있지만 아래 그림처럼 단순히 어떤 오류가 몇번째 줄에서 발생 했는지밖에 알 수 없습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;오류별로 그룹화 되어있는것이 아니라 앱 버전별로 묶여 있기때문에 제가 느끼기에는 불편해보였습니다. (fabric은 오류별로 묶여있고 그안에서 버전별로 나뉩니다)&lt;/p&gt;&lt;p&gt;또한 오류가 발생한 사용자들의 기기정보/버전정보/메모리정보 등 오류가 발생한 상황에 대해서 전혀 알수 없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;말하다보니 GA가 엄청 안좋은 서비스인것처럼 묘사되어있는것 같지만 이 기능을 제외하고 나머지는 너무나도 편리하고 유용한 기능을 제공해 줍니다.&lt;/p&gt;&lt;p&gt;(구글님 사랑합니다)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px; width: 1000px; height: 579px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/265BE24956AF39A81E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F265BE24956AF39A81E&quot; width=&quot;1000&quot; height=&quot;579&quot; filename=&quot;Screenshot at 2월 01 19-54-46.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 1000px; height: 579px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;p&gt;URQA&lt;/p&gt;&lt;/h2&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://www.urqa.io/urqa/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;홈페이지&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://docs.google.com/document/d/10ZR7Rken21j8c3WZTiPSBi5-pXlYSQHJfsc3h7QCHaE/edit#heading=h.gaomkc6r7w71&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;연동방법&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;URQA는 우리나라 회사에서 만든 서비스입니다.&lt;/p&gt;&lt;p&gt;서비스 이름에서도 볼수있듯이(Your QA겠죠?) 모바일을 위한 오류분석 서비스입니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;아래 이미지는 URQA홈페이지에 소개되어있는 간단한 소개입니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2520114056AF3EDF0F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2520114056AF3EDF0F&quot; width=&quot;1000&quot; height=&quot;484&quot; filename=&quot;Screenshot at 2월 01 20-17-23.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;URQA에서 GA보다는 좀더 나은 오류보고서를 확인할 수 있습니다.&lt;/p&gt;&lt;p&gt;하나의 오류에 대해서 Exception&amp;nbsp;Stack을 보여줄뿐만 아니라, &amp;nbsp;오류가 발생한 사용자들의 통계를 확인해 볼수도 있습니다.&lt;/p&gt;&lt;p&gt;(OS버전별 / 앱버전별 / 기기별 / 국가별)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2336C73A56AF41261B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2336C73A56AF41261B&quot; width=&quot;1000&quot; height=&quot;687&quot; filename=&quot;Screenshot at 2월 01 20-26-35.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또한 각 사용자별로 어떤 상황에서 오류가 발생했는지 알수 있도록 기기정보다 OS버전정보는 물론이고 GPS, 배터리, 와이파이등의 상세한 정보를 살펴볼 수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 350px; width: 350px; height: 345px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/265E253956AF41F119&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F265E253956AF41F119&quot; width=&quot;350&quot; height=&quot;345&quot; filename=&quot;Screenshot at 2월 01 20-30-25.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 350px; height: 345px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;전체적으로 제가 원하는 기능에 근접한 오류리포팅을 제공했지만 그리고 실제로 한동안 운영하는 서비스에 적용하기도 했었지만 &lt;b&gt;현재는 사용하지 않고 있습니다.&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;URQA 개발자분들께는 죄송하지만 리포팅 UI가 별로 이쁘지&amp;nbsp;않았습니다...(단순...)&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 151px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2416F44756B0893811&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2416F44756B0893811&quot; width=&quot;300&quot; height=&quot;151&quot; filename=&quot;ugly.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 300px; height: 151px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그리고 연동방법이 Android Studio기반이 아닌 Eclipse기반으로 설명되어있고&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;라이브러리를 gradle에 추가하는 방식이 아닌 jar파일을 추가하는 방식이어서 뭔가&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&amp;nbsp;'관리가 안되고있는건가?' 라는 느낌을 받기도 하였습니다..&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;유저해빗&lt;/p&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://userhabit.io/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;홈페이지&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://dashboard.userhabit.io/informations&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;연동방법&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;유저해빗 또한 GA와 마찬가지로 오류분석만을 위한 서비스는 아닙니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;아래 이미지는 유저해빗&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;홈페이지에 소개되어있는 서비스&amp;nbsp;소개입니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/241F384456B065971B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F241F384456B065971B&quot; width=&quot;1000&quot; height=&quot;305&quot; filename=&quot;Screenshot at 2월 02 17-14-54.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;유저해빗에서 제공하는&amp;nbsp;다양한 기능들은 &lt;a href=&quot;http://userhabit.io/ko/features&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;여기&lt;/a&gt;에서 확인해 볼 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;흥미로운 기능은 &lt;b&gt;히트맵&lt;/b&gt;과 &lt;b&gt;세션리플레이&lt;/b&gt; 입니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;히트맵은 우리가 만든 화면에서 사용자들이 어느위치를 터치를 가장 많이 했는지 등의 터치 히트맵 정보와 그와 관련된 정보들을 확인 해 볼수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;예를들면 5개의 선택버튼중 사용자들이 어디를 가장 많이 누르는지를 확인해 볼 수도 있고,&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;리스트에서 아이템을 선택하는것과 검색창을통해 선택하는 경우에 사용자들이 어떤방식의 선택을 더 선호하는지도 살펴볼 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 946px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/230F604556B066B231&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F230F604556B066B231&quot; width=&quot;946&quot; height=&quot;589&quot; filename=&quot;Screenshot at 2월 02 17-18-13.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;오류와 관련된 부분은 세션리플레이 입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;세션 리플레이에서 [크래쉬 세션]만을 필터링해서 살펴볼수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;단순히 에러로그 스택이 아닌 사용자가 앱을 사용한 영상을 보듯이 세션을 리플레이하여 어느상황에서 어떻게 오류가 났는지 확인해볼 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 963px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/267F2D3D56B067F531&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F267F2D3D56B067F531&quot; width=&quot;963&quot; height=&quot;808&quot; filename=&quot;Screenshot at 2월 02 17-20-45.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;유저해빗은 에러리포팅에 특화된 서비스가 아니기때문에 오류 리포팅관련해서는 다른 서비스에 비해서 강하지는 않습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;오류 리포팅과 함께 사용한다면 오류리포팅에서 채워지지않는 부분들을 좀더 다양한 시선으로 확인할 수 있을것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;현재는 서비스가 무료로 제공되고 있지만 얼마전 있었던 '정식출시 기능 설명회'에 따르면 조만간 유료화가 될 예정인것 같습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;과금은 스크린뷰수에 따라서 과금될 예정이며 물론 일정수준의 스크린뷰까지는 무료로 제공됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;정식출시되면서 확정된 과금방식을 참고해볼 필요가 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;참 좋은 서비스이기도 하고 유저해빗쪽 이사님과도 친분이 있어서 피드백이나 오류에대해서 즉각 반영해주는편이십니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;지금까지 유저해빗을 사용하면서 두번의 중대한 서비스 오류가 있었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 187px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2310A14756B0896913&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2310A14756B0896913&quot; width=&quot;250&quot; height=&quot;187&quot; filename=&quot;error.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 250px; height: 187px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;1. 'ShowcaseView' 라이브러리를 사용하고 있던중에 유저해빗과의 충돌로 앱이 실행하자마자 죽는현상이 발생해서 모든 사용자가 앱을 사용하지 못하였습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2. 저는 View에 setTag(),getTag()개념을 많이 사용하는데 유저해빗 라이브러리의 일부 기능에서&amp;nbsp;setTag(),getTag()하는 부분이 있어서 충돌로 인해 앱이 의도치않은 실행을 한적이 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아직 정식서비스가 아니기도 하고 이전에 발생했던 두번의 중대한 오류때문에 현재는 제가 운영하는 서비스에서 &lt;b&gt;유저해빗을 사용하지 않고 있는 상황입니다.&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;+2017.03.18&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2016년 3월 정식출시이후에는 위의 2가지문제가 해결되었다고 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;현재는 위와관련된 오류는 없다고 하니 착오 없이 사용하시기 바랍니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Fabric&amp;nbsp;Crashlytics&lt;/p&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://get.fabric.io/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;홈페이지&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://docs.fabric.io/android/fabric/migration/android-studio.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;연동방법&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위에서 결론적으로는 fabric이 제일 좋았다고 해놓고 너무 오래 기다리셨죠?&lt;/p&gt;&lt;p&gt;&lt;strike&gt;(원래 주인공은 항상 나중에 등장하는법)&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;strike&gt;&lt;br /&gt;&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;이 서비스는 트위터에서&amp;nbsp;Crashlytics를 인수해서 현재 Fabric&amp;nbsp;Crashlytics라는 서비스로 제공되고 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;blockquote cite=&quot;http://ko.wikipedia.org/wiki/HTML5&quot;&gt;
&lt;p&gt;
모든 앱에는 충돌이 존재하고, 이런 충돌들은 실제로 앱의 사용에 큰 영향을 미칩니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;전세계엔 수백만 개의 앱들이 있고, 사람들은 낮은 평가를 받은 앱을 선택하지 않습니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;당신의 앱에 왜 충돌이 일어나는지, 얼마나 많은 사용자들이 불편을 겪고 있는지, 무엇이 문제인지 알아내는 것은 앱의 성공을 위한 필수요소지만 동시에 매우 어려운 일입니다.&amp;nbsp;
&lt;/p&gt;&lt;p&gt;크래시리틱스(Crashlytics)는 이런 문제를 해결하기 위해 존재합니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;크래시리틱스는 오류를 감지해 찾아내고 버그를 수정하는 데에 필요한 시간을 절약해주어 개발자가 디버깅에 시간을 쓰는 대신 더 좋은 앱을 만드는 데에 집중할 수 있게 해줍니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;겨우 지난 30일 동안에 크래시리틱스가 찾아낸 충돌은 5억 5천만 건입니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;크래시리틱스는 충돌을 찾아내는 데에 그치지 않고 어떤 코드가 문제를 일으키는지 찾아주기 때문에 버그를 수정하고 업데이트를 제공하는 데 드는 시간을 아낄 수 있습니다.
&lt;/p&gt;
&lt;br /&gt;
&lt;cite&gt;&lt;a href=&quot;https://blog.twitter.com/ko/2014/introducing-fabric-kr&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;트위터 공식계정 Fabric 소개글에서&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;br /&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;연동방법은 정말 미친듯이 쉽습니다.&lt;/p&gt;&lt;p&gt;안드로이드 스튜디오에서 Fabric IDE만 설치하시면 됩니다.&lt;/p&gt;&lt;p&gt;그다음부터는 [Next],[Next] 만 눌러주시면 끝입니다.&lt;/p&gt;&lt;p&gt;Manifest에 추가하고 Application class에 추가하고 하는 등의 작업들을 알아서 다 해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 150px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/224B684D56B089F816&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F224B684D56B089F816&quot; width=&quot;300&quot; height=&quot;150&quot; filename=&quot;reaction.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 300px; height: 150px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사실 여기서 뿅가버렸습니다.&lt;/p&gt;&lt;p&gt;사실 오류리포팅 서비스를 연동하는게 그렇게 어려운 작업은 아니지만 정말 다음,다음만 누르면 설정이 끝나는것에 매료되어 버렸습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래 이미지는 메인 오류리포팅 화면입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2118B24856B0844635&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2118B24856B0844635&quot; width=&quot;1000&quot; height=&quot;688&quot; filename=&quot;Screenshot at 2월 02 19-25-48.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;오류 유형별로 묶여서 정렬되어 있고 몇명의 사용자로부터 몇개의 오류가 있었는지 파악할 수 있습니다.&lt;/p&gt;&lt;p&gt;각 오류를 선택하면 해당 오류에대한 상세 정보들을 표시해줍니다.&lt;/p&gt;&lt;p&gt;발생빈도를 차트별로 보거나 URQA에서 제공되었던 OS별,디바이스별로 살펴볼수도 있습니다.&lt;/p&gt;&lt;p&gt;또한 각각 세션에 대해서 오류가 발생했던 디바이스의 상태정보에대해서도 살펴볼 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2307734A56B084EF01&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2307734A56B084EF01&quot; width=&quot;1000&quot; height=&quot;698&quot; filename=&quot;Screenshot at 2월 02 19-28-05.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/247DB84A56B084F341&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F247DB84A56B084F341&quot; width=&quot;1000&quot; height=&quot;696&quot; filename=&quot;Screenshot at 2월 02 19-28-18.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금까지 제가 사용했었던 오류 리포팅 서비스와 후기에 대해서 포스팅 해보았습니다.&lt;/p&gt;&lt;p&gt;물론 위의 서비스들을 모두 사용하셔도 상관없습니다.&lt;/p&gt;&lt;p&gt;하지만 너무 많이 분산하는것또한 체크해야할부분들이 많아지고 관리포인트가 많아지는 부분에서는 좋지 않을수도 있을겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또한 가끔 알수없는 오류이거나 오류분석툴 자체의 오류가 발생하기도 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 955px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/224DDB3A56B0861908&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F224DDB3A56B0861908&quot; width=&quot;955&quot; height=&quot;146&quot; filename=&quot;Screenshot at 2월 02 19-32-47.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 977px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/275D563A56B0861A03&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F275D563A56B0861A03&quot; width=&quot;977&quot; height=&quot;75&quot; filename=&quot;Screenshot at 2월 02 19-33-44.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위에서 소개해드린 오류 리포팅서비스들을 모두 살펴보시고 직접 체험해보시면서 장단점을 느껴보시길 권합니다.&lt;/p&gt;&lt;p&gt;그중에서 본인에게 가장 잘 맞는 것들을 적용하셔서&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;마지막 오류 하나까지도 끝까지 찾아가서 없애버리는 평온한 앱을 만드시길 기원합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/53</guid>
      <comments>https://gun0912.tistory.com/53#entry53comment</comments>
      <pubDate>Tue, 2 Feb 2016 19:55:32 +0900</pubDate>
    </item>
    <item>
      <title>[셀폰x잔디]잔디커넥트를 이용해 셀폰서버에서 잔디로 메세지 보내기</title>
      <link>https://gun0912.tistory.com/51</link>
      <description>&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;잔디가 뭐에요?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;잔디라고 하니 혹시 넓은 벌판에 펼쳐져 있는 잔디를 상상하셨나요??&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 188px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/233CA33A56AADBD22A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F233CA33A56AADBD22A&quot; width=&quot;250&quot; height=&quot;188&quot; filename=&quot;wksel.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 188px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;잔디는 회사나 팀에서 이용할수있는 유용한 협업툴 입니다.&lt;/p&gt;&lt;p&gt;단체채팅방과 비슷한개념의 토픽들을 이용해서 주제별로 직원들과 업무에 관련된 이야기나 자료들을 공유할 수 있습니다.&lt;/p&gt;&lt;p&gt;PC, 안드로이드. 아이폰앱을 제공해주고 있어서 언제든지 업무에 필요한 소통을 나눌수도 있습니다.&lt;/p&gt;&lt;p&gt;&lt;strike&gt;(물론 퇴근후나 주말에는 꺼두셔도 좋습니다..)&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.jandi.com/landing/#/kr&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;JANDI - 업무를 위한 팀 커뮤니케이션, 잔디&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 200px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/260ECD3956AAECBA13&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F260ECD3956AAECBA13&quot; width=&quot;200&quot; height=&quot;200&quot; filename=&quot;blog_800x800_v002_150507.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 200px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;(잔디 홍보대사&amp;nbsp;아님..&lt;/span&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;저희 직원들도 이전에&amp;nbsp;슬랙을 사용하다가 얼마전 잔디로 옮겨서 열심히 적응중에 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://blog.jandi.com/ko/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;잔디 블로그&lt;/span&gt;&lt;/a&gt;에 나와있는 각종 팁들과 다른 회사들의 잔디활용법을 참고하면서 어떻게하면 효율적으로 사용할 수 있을지 생각하고 환경을 구성해 나아가고 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;어느정도 적응해 나아가면서 기존에 우리가 슬랙에서 사용했던&amp;nbsp;Trello나 Github과의 연동이 있으면 좀 편할것 같다는 생각을 하기도 했었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;그런데 그일이 실제로 일어 났습니다&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 180px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/23696B3956B0590726&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F23696B3956B0590726&quot; width=&quot;180&quot; height=&quot;162&quot; filename=&quot;awesome.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;바로 어제 (1월28일) 잔디에서 '잔디커넥트'를 오픈했습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://blog.jandi.com/ko/2016/01/28/jandi-update-news-jan-21/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;잔디 업데이트: 잔디 커넥트로 트렐로, 깃헙, 지라, 구글 캘린더를 연동해보세요!&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;잔디에서도 '잔디커넥트'를 이용해서 외부서비스와 연동해서 사용할 수 있게된것이죠.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;거기에 더불어 잔디커넥트에는&lt;b&gt; '웹훅(Webhook) 수신'&lt;/b&gt; 이라는 기능도 포함되어 있었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(140, 140, 140); background-color: rgb(255, 255, 255);&quot;&gt;(잔디 블로그 웹훅(Webhook) 수신 소개글 캡쳐)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 600px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/265CD94456AAEF472D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F265CD94456AAEF472D&quot; width=&quot;600&quot; height=&quot;399&quot; filename=&quot;Screenshot at 1월 29 13-48-39.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;쉽게 말하면 &lt;b&gt;'서버에서 잔디로 메세지를 보낼수 있다'&lt;/b&gt;는 것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;저는 이 '웹훅(Webhook) 수신' 기능이 매력적으로 느껴졌고 이를 우리 서비스에 적용시켜서 좀더 잔디를 효과적으로 사용하고 싶다는 생각이 들었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;셀폰에서 이루어지는 이벤트 메세지들을 잔디로 보내자&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;저는 현재 '셀폰'이라는 서비스를 운영하고 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;셀폰서비스는 중고폰 거래를 쉽게 도와주는 플랫폼 서비스&lt;/b&gt; 입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;셀폰을 통해서 아래 서비스들을 경험해볼 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;- 매입업체들의 매입가격 비교해서&amp;nbsp;중고폰/깨진액정 판매하기&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;- 중고폰 개인거래 판매하기/구매하기&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;- 셀폰이 보증하는 중고폰 구매하기&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;- 수리업체 위치 및 정보 확인하기&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;- IT관련 기사 및 정보를 제공하는 '셀폰 읽을거리'&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;홈페이지:&amp;nbsp;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;&lt;a href=&quot;http://www.selphone.co.kr/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;http://www.selphone.co.kr/&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;안드로이드앱:&amp;nbsp;&lt;a href=&quot;https://play.google.com/store/apps/details?id=kr.co.selphone&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;https://play.google.com/store/apps/details?id=kr.co.selphone&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아이폰앱: &lt;strike&gt;(열심히 개발중입니다..)&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;strike&gt;&lt;br /&gt;&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;셀폰은 고객용 앱 뿐만 아니라 제휴업체용,&amp;nbsp;직원용 앱이 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;직원용앱은&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;신고나 고객문의, 셀폰보증 중고폰 결제 등&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;셀폰을 운영하는데 필요한 모든것들을 조회하고 처리하기위한 기능들을 포함하고 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그중에서 셀폰보증 중고폰 결제와 관련된 내용에 대해서 포스팅 해보겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;기존에 저희가 구축해놓은 시스템은 아래와 같습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;만약 &lt;b&gt;고객이 저희가 판매하고 있는 중고휴대폰을 결제하는경우 직원용 앱과 직원 이메일로 알림이 오도록&lt;/b&gt; 환경이 구성되어있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 356px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2752E34756AAF2762F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2752E34756AAF2762F&quot; width=&quot;200&quot; height=&quot;356&quot; filename=&quot;Screenshot_2016-01-29-12-04-07.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 356px;&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 700px; line-height: 1.5;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/21201A4A56AAF29C31&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F21201A4A56AAF29C31&quot; width=&quot;700&quot; height=&quot;345&quot; filename=&quot;Screenshot at 1월 29 12-04-51.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;line-height: 1.5;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;물론 현재도 이중으로 알림이 오도록 되어있고 앱에서 주문과 관련된 처리들을 할수 있는 환경입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 현재 직원용앱은 안드로이드버전만 있기도 하고 해당 주문과 관련되서 재고나 발송 등 운영직원들끼리의 의사소통이 필요한 경우가 많습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그러한 경우 &lt;b&gt;의사소통은 잔디에서 이루어지고 처리나 기타 정보들은 따로 조회해야하는 번거로움이 존재합니다.&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;잔디에서 셀폰 보증폰 결제 알림메세지를 받아보자&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;직원용앱의 기능중 일부인 셀폰보증폰 결제와&amp;nbsp;관련된 기능을 '잔디 커넥트'와 연동해 보겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;1. 잔디 커넥트에서 Webhook 수신의 [연동 항목 추가하기]를 선택합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;물론 Webhook 수신기능은 2개이상도 가능합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 800px; width: 800px; height: 497px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2613C23556AAF3AB09&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2613C23556AAF3AB09&quot; width=&quot;800&quot; height=&quot;497&quot; filename=&quot;Screenshot at 1월 29 09-37-58.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 800px; height: 497px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2. 셀폰에서부터 결제알림 메세지를 받을 토픽을 생성해주고 메세지를 보내주는 봇(?)의 이미지와 이름을 설정해줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Webhook URL은 자동으로 할당되어 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;[설정방법 보기]를 누르시면 상세한 설정방법과 예제를 확인해 보실 수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 800px; width: 800px; height: 451px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/243F124656AAF4122A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F243F124656AAF4122A&quot; width=&quot;800&quot; height=&quot;451&quot; filename=&quot;Screenshot at 1월 29 09-38-32.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 800px; height: 451px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;3. 이제 서버에서 잔디로 메세지를 보내도록 신나게 코딩을 해줄 차례입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;셀폰서버는 현재 AWS플랫폼 위에서 Node.js 언어로 구성되어 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;(셀폰 서버 구성도)&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 800px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2617284056AAF4D913&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2617284056AAF4D913&quot; width=&quot;800&quot; height=&quot;452&quot; filename=&quot;Screenshot at 1월 28 20-28-08.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;잔디에서 예제로 보여준 코드를&amp;nbsp;node.js 테스트코드로 작성해 보았습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아래 소스를 이용해서 테스트 해보셔도 좋습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/b0388daf7e992e15cc14.js&quot;&gt;&lt;/script&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;options의 url에 여러분이 할당 받으신 webhook url을 넣어주시면 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;서버언어가 node.js가 아니신분들은 각자의 서버언어에 맞게 처리를 해주시면 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그렇게 테스트를 마치고 테스트 서버에서 고객의 결제가 이루어지는경우 메세지를 보낼수 있도록 코딩을 해줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;기존에 이메일,푸시알림을 보내는 부분에 잔디메세지를 전송하도록 코드를 추가해주었습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;이제부터는 고객이 결제를 하면 잔디로 메세지가 도착합니다&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아래 이미지에서 보시는것처럼 결제가 완료되면 서버에서 잔디로 결제와 관련된 정보들을 보내줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;물론 [결제정보 보기]버튼을 통해 직원용 웹페이지로 이동해서 좀더 상세한 업무처리를 할 수 있게 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 800px; width: 800px; height: 546px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2407133956AAFA6909&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2407133956AAFA6909&quot; width=&quot;800&quot; height=&quot;546&quot; filename=&quot;Screenshot at 1월 29 11-10-38.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 800px; height: 546px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;우선 테스트로 결제관련된 기능들을 잔디 메세지로 보내보았습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이후에는 고객의 게시물신고 혹은 사기꾼 신고와 관련된 기능, 고객문의에 관련된 기능들도 잔디에서 받아볼 수 있도록 연동시킬 생각입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;물론 일별/월별 KPI도 서버가 정기적으로 보내줄수 있게 만들수 있으며, 서버장애 발생시 메세지로 알림이 오거나 전일 오류로그들도 잔디에서 받아 볼 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;잔디님에게 바랍니다&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2314FE3456B059662B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2314FE3456B059662B&quot; width=&quot;300&quot; height=&quot;163&quot; filename=&quot;robot.gif&quot; filemime=&quot;image/gif&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;추후에는 실제 봇처럼 사용할수 있는 기능이 추가되었으면 좋겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&quot;현재 접속 고객수?&quot; 라고 했을때 &quot;260명!&quot; 이라고 나올수 있도록&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;서버에서 잔디로 메세지를 보내는 기능뿐만 아니라&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;잔디에서도 서버로 메세지를 보낼수 있게된다면 잔디의 사용법은 좀더 다양하고 편리해 질것 같습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이상 잔디 커넥트의 웹훅(Webhook) 수신 기능을 보고나서 흥분해서 셀폰에 적용해본 후기를 마치겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;감사합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/기타정보</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/51</guid>
      <comments>https://gun0912.tistory.com/51#entry51comment</comments>
      <pubDate>Fri, 29 Jan 2016 14:33:16 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]Retrofit에서 Interceptor를 이용해 쿠키/세션 유지하는 방법</title>
      <link>https://gun0912.tistory.com/50</link>
      <description>&lt;p&gt;Retrofit은 우리가 해주어야할 귀찮은 네트워크 통신 작업을 대신해주는 정말 유용한 라이브러리입니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/30&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;[안드로이드]유용한 라이브러리 - Retrofit(REST API 통신)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;REST API통신을 할때 정말 유용하고 편하게 사용할 수 있습니다.&lt;/p&gt;&lt;p&gt;안드로이드 앱을 개발하시면서 로그인을 필요로 하는 서비스를 만들어야 하는 경우가 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;로그인을 하는경우 로그인 유지를 위해서 클라이언트는 쿠키를, 서버는 세션을 이용하게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 169px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2109A9425694ED4927&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2109A9425694ED4927&quot; width=&quot;300&quot; height=&quot;169&quot; filename=&quot;c0055612_50c5d19384373.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 169px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;strike&gt;(쿠...쿠키 땡긴다...)&lt;/strike&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;안드로이드에서 CookieStore를 이용하면 처음에 앱을 실행하고 로그인한뒤 이루어지는 모든 Request에 대해서 쿠키를 유지해서 계속 로그인된 사용자임을 알려줄 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만&amp;nbsp;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;CookieStore는 앱을 다시 실행하면 새로운 cookie를 생성하기때문에 다시 로그인해야하고&lt;/span&gt;,&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;그렇게 된다면 매번 실행시마다 로그인을 해주어야 하는 작업을 해주어야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/275CF24F5694F1DD26&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F275CF24F5694F1DD26&quot; width=&quot;300&quot; height=&quot;219&quot; filename=&quot;again.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;로그인횟수집계나 기타 로그인시 필요한 정보나 데이터를 받기위해서&amp;nbsp;실행시마다 로그인이 필요한 경우도 있겠지만,&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;어쨌든 실행할때마다 새로운 쿠키값이 생기는것은 클라이언트에게나 서버에게나 좋지 않은 방식일 것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;같은 사용자가 사용함에도 불구하고 쿠키가 새로 만들어지기때문에 서버는 계속 새로운 세션을 생성하게 되고 이는 나중에 의도하지 않은 문제를 야기시킬 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Retrofit에서 사용하는 Okhttp를 이용하여 &lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;실행시마다 항상 같은 쿠키값을 유지하는 방법&lt;/span&gt;&lt;/b&gt;에 대해서 포스팅 해보겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;요약&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;1. 로그인한뒤 받은 Response에서 쿠키정보를 가져온다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2. 가져온 쿠키정보를 안드로이드의 SharedPreferences에 저장해둔다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;3. 이후 수행되는 Request마다&amp;nbsp;SharedPreferences에서&amp;nbsp;쿠키를 가져와서 Header에 추가해서 보낸다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 400px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/263275425694F7BF12&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F263275425694F7BF12&quot; width=&quot;400&quot; height=&quot;365&quot; filename=&quot;Screenshot at 1월 12 21-32-20.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;구현 방법은 생각보다 간단합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Response로부터 &lt;b&gt;쿠키정보를 가져와서 Preference에 저장&lt;/b&gt;하는&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;ReceivedCookiesInterceptor&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;클래스를 만들어 줍니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Request마다&amp;nbsp;&lt;b&gt;Preference에 저장되어있는 쿠키값을 함께 Header에 넣어&lt;/b&gt;주는&amp;nbsp;AddCookiesInterceptor클래스를 만들어 줍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2개의&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;ReceivedCookiesInterceptor,&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&amp;nbsp;AddCookiesInterceptor&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;클래스는 아래 소스에서 확인 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;(SharedPreferences 에 쿠키정보를 저장하고 가져오는 부분은 원하시는 방법으로 편하게 만드시면 됩니다)&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


&lt;script src=&quot;https://gist.github.com/ParkSangGwon/ceb7d5c58b030516b9c5.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;그다음&amp;nbsp;Retrofit을&amp;nbsp;build해줄때 Custom하게 OkHttpClient를 만들고 이 클라이언트를 Retrofit의 클라이언트로 지정해줍니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;OkHttpClient client = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;OkHttpClient()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// 쿠키를 Prefreence에 저장하고 가져옴&lt;br /&gt;&lt;/span&gt;client.interceptors().add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;AddCookiesInterceptor())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;client.interceptors().add(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ReceivedCookiesInterceptor())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2.0 이전의 버전을 사용하고 계신다면 위에서 만든 client를 가지고 OkClient 클래스를 만들어주고 이 클라이언트를 RestAdapter에 설정해주시면 됩니다.&lt;/p&gt;&lt;div&gt;&lt;pre style=&quot;color: rgb(169, 183, 198); font-family: Menlo; font-size: 9pt; background-color: rgb(43, 43, 43);&quot;&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;OkClient serviceClient = &lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;new &lt;/span&gt;OkClient(client)&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;어때요? 참 쉽죠?&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 400px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2518F9455694F73A19&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2518F9455694F73A19&quot; width=&quot;400&quot; height=&quot;223&quot; filename=&quot;4.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이상으로 Retrofit에서 Interceptor를 이용해 쿠키/세션 유지하는 방법&lt;strike&gt;(쿠키를 빼돌리기)&lt;/strike&gt;에 대해 포스팅 해보았습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;감사합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/50</guid>
      <comments>https://gun0912.tistory.com/50#entry50comment</comments>
      <pubDate>Tue, 12 Jan 2016 21:58:10 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]MFA를 이용하여 계정의 보안을 강화하는 방법(OTP방식)</title>
      <link>https://gun0912.tistory.com/49</link>
      <description>&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 175px; line-height: 1.5;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/275BD83C56925CF304&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F275BD83C56925CF304&quot; width=&quot;175&quot; height=&quot;175&quot; filename=&quot;icon175x175.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;line-height: 1.5;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;AWS를 이용하기위해서는 당연히 아이디와 비밀번호를 입력해서 로그인을 해야합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;비밀번호를 관리하는 방법은 정말 다양하게 자신이 원하는대로 하고 계실겁니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;모든 사이트/서비스를 같은 비밀번호로 설정하는분도 계실것이고, 각각 다르게 설정하시는분도 계실겁니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 200px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/241F9A3656925CC314&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F241F9A3656925CC314&quot; width=&quot;300&quot; height=&quot;200&quot; filename=&quot;password.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 300px; height: 200px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;어찌되었든 만약 내 비밀번호를 누가 알게되었다면 큰일 이겠죠.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;특히 AWS같은경우 바로 돈과 직결되는 부분이기에, 또한 회사계정으로 사용하고 계실경우 비밀번호가 유출되면 심각한 위험에 빠질 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 226px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2512463C56925DC728&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2512463C56925DC728&quot; width=&quot;300&quot; height=&quot;226&quot; filename=&quot;burn_cash.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 300px; height: 226px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;비밀번호를 알게된 누군가가 마음대로 instance를 수없이 만들거나,&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;반대로 삭제해버린다면 우리는 막대한 재정적 손해를 입을수 밖에 없습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그래서 우리는&amp;nbsp;비밀번호뿐만 아니라 MFA(Multi-Factor Authentication)를&amp;nbsp;활용하여&amp;nbsp;2중보안을 설정할 필요가 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이 방식은 은행에서 사용하는 OTP방식과 동일합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;AWS계정에서 MFA설정방법에 대해 알아 보겠습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1. [AWS Management Console에 로그인] - [오른쪽 위 탭&amp;nbsp;Security Credentials]&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 156px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2150D73E56925B7F05&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2150D73E56925B7F05&quot; width=&quot;300&quot; height=&quot;156&quot; filename=&quot;Screenshot at 1월 10 22-07-36.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 156px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2. [MFA 선택] - [Activate MFA]&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 600px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/263FF53E56925B8317&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F263FF53E56925B8317&quot; width=&quot;600&quot; height=&quot;270&quot; filename=&quot;Screenshot at 1월 10 22-08-29.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;3. [A virtual MFA device 선택 (기본값)] - [Next Step]&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px; width: 500px; height: 235px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2131D23E56925B8918&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2131D23E56925B8918&quot; width=&quot;500&quot; height=&quot;235&quot; filename=&quot;Screenshot at 1월 10 22-08-39.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 500px; height: 235px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;4. [Next Step]&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px; width: 500px; height: 185px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2733AD3E56925B8B19&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2733AD3E56925B8B19&quot; width=&quot;500&quot; height=&quot;185&quot; filename=&quot;Screenshot at 1월 10 22-08-48.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 500px; height: 185px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;5. 아래에 나와있는 QR코드를 이용해서 OTP승인번호를 입력해야합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px; width: 500px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2630BC3E56925B8D19&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2630BC3E56925B8D19&quot; width=&quot;500&quot; height=&quot;445&quot; filename=&quot;Screenshot at 1월 10 22-08-58.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 500px; height: 445px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;플레이스토어(Android) 혹은 앱스토어(iOS)에서 'Google OTP'를 다운받습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;안드로이드의 경우,&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;[설정 시작하기] - [바코드 스캔]으로 위의 QR코드를 스캔합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 355px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2321D74956925FE22D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2321D74956925FE22D&quot; width=&quot;200&quot; height=&quot;355&quot; filename=&quot;Screenshot_2016-01-10-22-16-33.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 355px;&quot;/&gt;&lt;/span&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;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; line-height: 1.5; width: 200px; height: 355px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/257D844956925FE622&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F257D844956925FE622&quot; width=&quot;200&quot; height=&quot;355&quot; filename=&quot;Screenshot_2016-01-10-22-16-42.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;line-height: 1.5; width: 200px; height: 355px;&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;바코드 스캔이 완료되면 아래와 같이 6자리 코드가 나오고 일정시간뒤에 또 다른 코드로 바뀌게 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;QR코드 아래에 입력하는 [&lt;span style=&quot;line-height: 1.5;&quot;&gt;Authentication Code 1]를 입력해준뒤, 다시 코드가 바뀌면 바뀐값을 [&lt;/span&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;Authentication Code 2]에 입력해줍니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; line-height: 1.5; width: 200px; height: 355px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/21455C4956925FE829&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F21455C4956925FE829&quot; width=&quot;200&quot; height=&quot;355&quot; filename=&quot;Screenshot_2016-01-10-22-17-03.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;line-height: 1.5; width: 200px; height: 355px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;6. 성공적으로 MFA인증이 추가 되었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 194px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/216E513E56925B9111&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F216E513E56925B9111&quot; width=&quot;300&quot; height=&quot;194&quot; filename=&quot;Screenshot at 1월 10 22-11-46.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 194px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제부터 로그인시 아이디/비밀번호를 입력하고 난뒤에 아래 그림처럼 MFA를 이용한 인증을 실행해야 합니다.&lt;/p&gt;&lt;p&gt;만약 비밀번호가 유출되었더라도 6자리의 OTP비밀번호를 입력해야하기때문에 계정을 안전하게 보호 할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 700px; width: 700px; height: 344px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/24544D3D56925B9527&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F24544D3D56925B9527&quot; width=&quot;700&quot; height=&quot;344&quot; filename=&quot;Screenshot at 1월 10 22-12-25.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 700px; height: 344px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/AWS</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/49</guid>
      <comments>https://gun0912.tistory.com/49#entry49comment</comments>
      <pubDate>Sun, 10 Jan 2016 22:50:08 +0900</pubDate>
    </item>
    <item>
      <title>String types not allowed</title>
      <link>https://gun0912.tistory.com/48</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;xml 어딘가에 안드로이드에서 인식할수 없는 오타가 포함되어 있는 현상.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;예를들어 아래와 같은 오류문구 인경우&lt;/p&gt;&lt;p&gt;String types not allowed (at 'id' with value ...)&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;@+id 혹은 @id 로 xml에서 시작해서 View의 id를 지정해주어야 하는데 +@id 같은 오타 때문에 발생하는 에러.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;b&gt;Edit &amp;gt; Find &amp;gt; Find in path 를 통해서 오류가 발생한 해당 텍스트를 검색해서 오류를 수정해준다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-ERROR&amp;amp;SOLVE</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/48</guid>
      <comments>https://gun0912.tistory.com/48#entry48comment</comments>
      <pubDate>Thu, 7 Jan 2016 21:04:10 +0900</pubDate>
    </item>
    <item>
      <title>java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to</title>
      <link>https://gun0912.tistory.com/47</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Fatal Exception: java.lang.RuntimeException&lt;/p&gt;&lt;p&gt;java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to android.support.design.widget.CoordinatorLayout$SavedState&lt;/p&gt;&lt;p&gt;java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to android.support.v7.widget.Toolbar$SavedState&lt;/p&gt;&lt;p&gt;java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to...&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;하나의 xml에 같은 id가 중복으로 정의되어 있는 문제&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;문제가 발생한 View와 같은 id가 선언되어 있는지 체크해보면 된다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Don't&amp;nbsp;use same id / layout names multiple times.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Check your view id in layout&lt;/b&gt;&lt;/p&gt;</description>
      <category>IT/Android-ERROR&amp;amp;SOLVE</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/47</guid>
      <comments>https://gun0912.tistory.com/47#entry47comment</comments>
      <pubDate>Mon, 21 Dec 2015 09:57:52 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]전화수신시 전화번호 가져와서 팝업으로 띄우는 방법</title>
      <link>https://gun0912.tistory.com/46</link>
      <description>&lt;p&gt;저는 모르는 전화번호로 걸려오는 전화는 잘 받지 않습니다.&lt;/p&gt;&lt;p&gt;하지만 중고거래를 하기위해&amp;nbsp;중고물건을 여러 사이트에 올려두었을때는 혹시 구매자가 전화한것일수도 있기때문에 그 시기에는 걸려오는 전화를 꼭꼭 받습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=kr.co.selphone&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;셀폰이라는 중고폰 거래중개서비스&lt;/span&gt;&lt;/a&gt;에서는 내가 올려둔 중고폰 판매글을 보고 구매자가 전화하는경우 아래 이미지처럼 정보를 알려줍니다.&lt;/p&gt;&lt;p&gt;이러한 경우 &lt;b&gt;모르는 번호이더라도 내 판매글을 보고 연락한 사람임을 알 수 있기 때문에 안심하고 전화를 받을 수 있습니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 444px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/220F6F3A5672046717&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F220F6F3A5672046717&quot; width=&quot;250&quot; height=&quot;444&quot; filename=&quot;전화번호확인.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 444px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;요즘 많이 쓰고있는 후후나 후스콜 같은 경우도 이와 비슷하게 전화가 걸려오는경우를 감지해서 해당전화번호가 스팸인지 아닌지를 확인할 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;여기서 이용되는 안드로이드에서의 기능은&amp;nbsp;BroadcastReceiver,&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;Service 입니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;b&gt;대부분 이러한 서비스들의 동작순서는 아래와 같습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;1. 전화가 오는경우 감지를 위한&amp;nbsp;&lt;/span&gt;BroadcastReceiver 생성 및 등록&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;2. 앱이 실행중이지 않은경우에도 기능을 실행하기위한 Service 생성 및 등록&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;3. 띄워줄 화면의 레이아웃 생성 및 추가&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그럼 BroadcastReceiver,&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;Service를 이용해서 전화가 걸려오는 경우 걸려온 전화번호를 팝업으로 띄워서 보여주는 예제를 만들어 보겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5; font-size: 24pt;&quot;&gt;&lt;b&gt;BroadcastReceiver&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;전화가 오는상황을 감지하기 위해 전화상태를 읽을수있는 권한을 Manifest에&amp;nbsp;추가해주어야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;uses-permission &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.permission.READ_PHONE_STATE&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또한, receiver도 추가해 줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;receiver &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;.IncomingCallBroadcastReceiver&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;intent-filter&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &amp;lt;action &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;android.intent.action.PHONE_STATE&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;/intent-filter&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/receiver&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;BroadcastReceiver의&amp;nbsp;onReceive()에서 전화가 오는경우를 감지하고 Service를 실행하는 부분을 만들어 줍니다.&lt;/p&gt;&lt;p&gt;여기서는 통화벨이 울리는 경우 걸려온 전화번호를 알아낸뒤, 그 전화번호를 Service로 넘겨주면서 Service를 실행하도록 하겠습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(TelephonyManager.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTRA_STATE_RINGING&lt;/span&gt;.equals(state)) {&lt;br /&gt;    String incomingNumber = intent.getStringExtra(TelephonyManager.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTRA_INCOMING_NUMBER&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    final &lt;/span&gt;String phone_number = PhoneNumberUtils.&lt;span style=&quot;font-style:italic;&quot;&gt;formatNumber&lt;/span&gt;(incomingNumber)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;Intent serviceIntent = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Intent(context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;CallingService.&lt;span style=&quot;color:#cc7832;&quot;&gt;class&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;serviceIntent.putExtra(CallingService.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTRA_CALL_NUMBER&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;phone_number)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;context.startService(serviceIntent)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;(참고)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;TelephonyManager.EXTRA_STATE_IDLE:&lt;/b&gt; 통화종료 혹은 통화벨 종료&lt;/p&gt;&lt;p&gt;&lt;b&gt;TelephonyManager.EXTRA_STATE_RINGING:&lt;/b&gt; 통화벨 울리는중&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;TelephonyManager.EXTRA_STATE_OFFHOOK:&lt;/b&gt; 통화중&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;#주의&lt;/span&gt;&lt;/p&gt;&lt;p&gt;정확한 이유는 알 수 없지만 실제&amp;nbsp;&lt;span style=&quot;line-height: 1.5;&quot;&gt;BroadcastReceiver가 여러번 호출되는 경우를 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;구글링을 해보면 저뿐만 아니라 많은 사람들이 이러한 문제로 어려움을 겪고 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;line-height: 1.5;&quot;&gt;이렇게되면 우리가 의도한대로 되지않고 서비스가 여러번 호출되는 상황을 발생시키기도 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;이를 해결하기 위해 static 변수를 하나 두고나서 해당 변수의 상태가 변경될때에만 실제 변경됨을 감지하고 다음동작을 실행하도록 해주었습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private static &lt;/span&gt;String &lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;mLastState&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(state.equals(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;mLastState&lt;/span&gt;)) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;return;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;else &lt;/span&gt;{&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;mLastState &lt;/span&gt;= state&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;(참고:&amp;nbsp;&lt;a href=&quot;http://mmarvick.github.io/blog/blog/lollipop-multiple-broadcastreceiver-call-state/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;http://mmarvick.github.io/blog/blog/lollipop-multiple-broadcastreceiver-call-state/&lt;/span&gt;&lt;/a&gt; )&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/c254676ecac3e4c0c3a9.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;Layout&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;팝업으로 보여줄 layout xml을 만들어줍니다.&lt;/p&gt;&lt;p&gt;여기서는 간단하게 걸려온&amp;nbsp;전화번호를보여주고&amp;nbsp;팝업창을 종료할수 있는 X버튼을 만들어 두겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/b2fc21968b3361a69185.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;Service&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Manifest에 Service를 추가해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;service &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;.CallingService&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Service의 onCreate()에서&amp;nbsp;팝업의 크기와 각종 팝업과 관련된 설정들을 세팅해줍니다.&lt;/p&gt;&lt;p&gt;여기서는 팝업크기의 가로가 화면의 90%만 채우도록 설정해주었습니다.&lt;/p&gt;&lt;p&gt;그리고 위에서 만들어둔 popup layout xml을 가져옵니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onCreate&lt;/span&gt;() {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.onCreate()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;windowManager &lt;/span&gt;= (WindowManager) getSystemService(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;WINDOW_SERVICE&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;Display display = &lt;span style=&quot;color:#9876aa;&quot;&gt;windowManager&lt;/span&gt;.getDefaultDisplay()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    int &lt;/span&gt;width = (&lt;span style=&quot;color:#cc7832;&quot;&gt;int&lt;/span&gt;) (display.getWidth() * &lt;span style=&quot;color:#6897bb;&quot;&gt;0.9&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;//Display 사이즈의 90%&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;params &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;WindowManager.LayoutParams(&lt;br /&gt;            width&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;WindowManager.LayoutParams.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;WRAP_CONTENT&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;WindowManager.LayoutParams.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TYPE_SYSTEM_ERROR&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;WindowManager.LayoutParams.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;FLAG_NOT_FOCUSABLE&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;                    &lt;/span&gt;| WindowManager.LayoutParams.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;FLAG_SHOW_WHEN_LOCKED&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;                    &lt;/span&gt;| WindowManager.LayoutParams.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;FLAG_DISMISS_KEYGUARD&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;                    &lt;/span&gt;| WindowManager.LayoutParams.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;FLAG_TURN_SCREEN_ON&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;PixelFormat.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TRANSLUCENT&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;LayoutInflater layoutInflater = (LayoutInflater) getSystemService(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;LAYOUT_INFLATER_SERVICE&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;rootView &lt;/span&gt;= layoutInflater.inflate(R.layout.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;call_popup_top&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;ButterKnife.&lt;span style=&quot;font-style:italic;&quot;&gt;inject&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;this, &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;rootView&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;setDraggable()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;setDragable()함수에서는&amp;nbsp;팝업View에&amp;nbsp;setOnTouchListener를 추가해서 이동시킬 수 있도록 설정해줍니다.&lt;/p&gt;&lt;p&gt;팝업View를 누르고&amp;nbsp;움직일때마다 이동거리만큼 같이 움직여 줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setDraggable&lt;/span&gt;() {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;rootView&lt;/span&gt;.setOnTouchListener(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;View.OnTouchListener() {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;private int &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;initialX&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        private int &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;initialY&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        private float &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;initialTouchX&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        private float &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;initialTouchY&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public boolean &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onTouch&lt;/span&gt;(View v&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;MotionEvent event) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;switch &lt;/span&gt;(event.getAction()) {&lt;br /&gt;                &lt;span style=&quot;color:#cc7832;&quot;&gt;case &lt;/span&gt;MotionEvent.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ACTION_DOWN&lt;/span&gt;:&lt;br /&gt;                    &lt;span style=&quot;color:#9876aa;&quot;&gt;initialX &lt;/span&gt;= &lt;span style=&quot;color:#9876aa;&quot;&gt;params&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;initialY &lt;/span&gt;= &lt;span style=&quot;color:#9876aa;&quot;&gt;params&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;y&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;initialTouchX &lt;/span&gt;= event.getRawX()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;initialTouchY &lt;/span&gt;= event.getRawY()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    return true;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                case &lt;/span&gt;MotionEvent.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ACTION_UP&lt;/span&gt;:&lt;br /&gt;                    &lt;span style=&quot;color:#cc7832;&quot;&gt;return true;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                case &lt;/span&gt;MotionEvent.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ACTION_MOVE&lt;/span&gt;:&lt;br /&gt;                    &lt;span style=&quot;color:#9876aa;&quot;&gt;params&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;x &lt;/span&gt;= &lt;span style=&quot;color:#9876aa;&quot;&gt;initialX &lt;/span&gt;+ (&lt;span style=&quot;color:#cc7832;&quot;&gt;int&lt;/span&gt;) (event.getRawX() - &lt;span style=&quot;color:#9876aa;&quot;&gt;initialTouchX&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;params&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;y &lt;/span&gt;= &lt;span style=&quot;color:#9876aa;&quot;&gt;initialY &lt;/span&gt;+ (&lt;span style=&quot;color:#cc7832;&quot;&gt;int&lt;/span&gt;) (event.getRawY() - &lt;span style=&quot;color:#9876aa;&quot;&gt;initialTouchY&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;rootView &lt;/span&gt;!= &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;)&lt;br /&gt;                        &lt;span style=&quot;color:#9876aa;&quot;&gt;windowManager&lt;/span&gt;.updateViewLayout(&lt;span style=&quot;color:#9876aa;&quot;&gt;rootView&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;params&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    return true;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;return false;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;    })&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;onStartCommand()에서 세팅해놓음 팝업View를 WindowManager에 추가해줍니다.&lt;/p&gt;&lt;p&gt;넘겨받은 전화번호 정보를 가져와서 팝업View의 TextView에도 세팅해줍니다.&lt;/p&gt;&lt;p&gt;onStartCommand()에서 START_REDELIVER_INTENT로 설정하는경우 Service가 강제종료 되더라도 다시 시작해주고 이전에 넘겨받았던 intent를 그대로 넘겨받을 수 있습니다.&lt;/p&gt;&lt;p&gt;여기서는 STICKY로 해주어도 크게 상관없을것 같습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://arabiannight.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9CAndroid-Service-%EC%82%AC%EC%9A%A9%EB%B2%95&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;(Android Service 사용법)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;만약 intent가 null인경우엔 팝업View를 없애줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public int &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onStartCommand&lt;/span&gt;(Intent intent&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;flags&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;startId) {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;windowManager&lt;/span&gt;.addView(&lt;span style=&quot;color:#9876aa;&quot;&gt;rootView&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;params&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;setExtra(intent)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    if &lt;/span&gt;(!TextUtils.&lt;span style=&quot;font-style:italic;&quot;&gt;isEmpty&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;call_number&lt;/span&gt;)) {&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;tv_call_number&lt;/span&gt;.setText(&lt;span style=&quot;color:#9876aa;&quot;&gt;call_number&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;START_REDELIVER_INTENT&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setExtra&lt;/span&gt;(Intent intent) {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(intent == &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;        removePopup()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        return;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;call_number &lt;/span&gt;= intent.getStringExtra(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTRA_CALL_NUMBER&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;서비스가 종료되거나 팝업View의 X버튼이 눌리는경우 팝업View를 없애줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onDestroy&lt;/span&gt;() {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.onDestroy()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;removePopup()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@OnClick&lt;/span&gt;(R.id.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;btn_close&lt;/span&gt;)&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;removePopup&lt;/span&gt;() {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;rootView &lt;/span&gt;!= &lt;span style=&quot;color:#cc7832;&quot;&gt;null &lt;/span&gt;&amp;amp;&amp;amp; &lt;span style=&quot;color:#9876aa;&quot;&gt;windowManager &lt;/span&gt;!= &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) &lt;span style=&quot;color:#9876aa;&quot;&gt;windowManager&lt;/span&gt;.removeView(&lt;span style=&quot;color:#9876aa;&quot;&gt;rootView&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/34abc6c01e9b8551afad.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그렇게 완성된 화면은 아래와 같습니다.&lt;/p&gt;&lt;p&gt;전화가 걸려올경우 상대방의 전화번호를 넘겨받아서 팝업으로 보여주게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 444px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/217430385673DB8530&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F217430385673DB8530&quot; width=&quot;250&quot; height=&quot;444&quot; filename=&quot;CallingService.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 444px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이를 잘 활용해서 가져온 전화번호를 운영중인 서비스의 서버에 요청해서 각종 정보를 가져오는 기능을 만들 수도 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;여러가지 응용된 방식으로 사용자에게 의미있는 정보를 노출해주길 바랍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이것저것 다 귀찮으신분들을 위해 Github에 프로젝트를 올려두었습니다.&lt;/p&gt;&lt;p&gt;Github에서 다운받으셔서 테스트프로젝트 실행해보셔도 좋습니다.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;&lt;a href=&quot;https://github.com/ParkSangGwon/IncomingCallMarketBroadcastReceiver&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Github에서 전체프로젝트&amp;nbsp;보기&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;(내용이 유용하셨다면 Github&amp;nbsp;오른쪽위의&amp;nbsp;[Star]버튼을 눌러주시면 감사하겠습니다&lt;/p&gt;&lt;p&gt;저에게는 별풍선 주시는 효과가 있어요!)&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;600&quot; width=&quot;600&quot; exif=&quot;{}&quot; id=&quot;tx_entry_51030_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/2625B4395917C42F09&quot; height=&quot;304&quot; title=&quot;더블클릭을 하시면 이미지를 수정할 수 있습니다&quot; style=&quot;width: 150px; height: 76px;&quot;&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/46</guid>
      <comments>https://gun0912.tistory.com/46#entry46comment</comments>
      <pubDate>Fri, 18 Dec 2015 19:17:04 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]프리티어사용시 요금발생(폭탄)을 막기위한 팁</title>
      <link>https://gun0912.tistory.com/45</link>
      <description>&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 223px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/212CEE3B56662F2C04&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F212CEE3B56662F2C04&quot; width=&quot;250&quot; height=&quot;223&quot; filename=&quot;fi_aws_free_tier.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 250px; height: 223px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;프리티어로 AWS서비스를 체험하면서 프리티어로 사용할 수 있는 자원의 할당량만 사용한다면 요금이 청구될 일은 없습니다.&lt;/p&gt;&lt;p&gt;하지만 프리티어를 사용하면서 혹시 요금이 발생할 수도 있는 부분에 대해서 체크해보고&amp;nbsp;청구되는&amp;nbsp;요금을 줄이시기 바랍니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://aws.amazon.com/ko/free/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;AWS프리티어 사용가능 리소스&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;Elastic IP&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Elastic IP주소는 ip주소를 고정으로 사용할 수 있도록 해주는 서비스입니다.&lt;/p&gt;&lt;p&gt;EC2가 stop/start 되는경우 ip주소가 매번 변경되는데 이를 EC2에 연결 해두고 Elastic ip주소로 접근하면 항상 같은 주소로 접근할 수 있게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;http://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;프리티어에서 Elastic IP&amp;nbsp;1개를 무료로&amp;nbsp;사용할 수 있습니다.&lt;/p&gt;&lt;p&gt;하지만 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Elastic IP는 EC2에 연결해두지&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&amp;nbsp;않으면 요금이 청구&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;됩니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;ip가 부족한 상황에서 Elastic ip를 만들어두고 EC2에 연결하지 않으면 ip가 만들어져 있지만&amp;nbsp;사용되지 않고 있으므로 요금이 청구됩니다.&lt;/p&gt;&lt;p&gt;또한, &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;EC2에 연결해두었더라도 EC2가 stop되어있는 상태라면 요금이 청구됩니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;만약 Elastic ip를 만들어두고 할당을 하지 않은 상태라면 실행중인 EC2에 할당 혹은 Elastic ip 삭제를 하시길 바랍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;RDS&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;RDS도 1개는 프리티어에서 무료로 사용할 수 있습니다.&lt;/p&gt;&lt;p&gt;다만, &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;RDS생성시 Multi-AZ와 고성능 I/O인&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Provisioned IOPS Storate를 사용하지 않도록 설정해야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;기본설정으로 [Yes]가 선택되어 있기때문에 많이 실수하는 부분입니다.&lt;/p&gt;&lt;p&gt;물론 돈을 내고서라도 이런 기능이 필요하시다면 선택을 하시면 되지만, 온전히 프리티어로 사용하고자 하신다면 [No]로 체크하시고 RDS를 생성하셔야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 739px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/275B37485666253716&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F275B37485666253716&quot; width=&quot;739&quot; height=&quot;402&quot; filename=&quot;Screenshot at 12월 08 09-30-24.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;ElastiCache&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;프리티어에서&amp;nbsp;ElastiCache 1개는 무료로 사용할 수 있습니다.무료사용 대상은 t2.micro 입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아래 그림은&amp;nbsp;ElastiCache Redis를 생성할때 기본적으로 세팅되어있는 것들입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;[Node Type]에서 프리티어대상인&amp;nbsp;t2.micro를 선택하려고하면 비활성화되서 선택되지 않는것을 확인할 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;[Multi-AZ]가 체크해제해야 t2.micro를 선택할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 700px; width: 700px; height: 572px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2353083D5666277719&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2353083D5666277719&quot; width=&quot;700&quot; height=&quot;572&quot; filename=&quot;Screenshot at 12월 08 09-42-12.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 700px; height: 572px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;EBS&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;EBS는 프리티어에서 30GB까지 무료로 사용할 수있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;EC2생성시 기본세팅을 조정하지 않으셨다면 EC2 1개당 8GB의 EBS가 생성될 것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;프리티어사용자라면 EC2를 1개만 사용할 것이기때문에 전혀 문제가 되지 않을것이라고 생각할 수 있습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 문제는 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;EC2를 stop하면 요금은 청구되지않지만 EBS는 여전히 사용중인 것으로 됩니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;예를들어보겠습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;오전 10시에 EC2 1개를 생성하고 나서 30분뒤에 stop시켰습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;오전 11시에 EC2 1개를 생성하고 나서 40분뒤에 stop시켰습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;그렇게 반복적으로 총 6시간동안 6개의 EC2를 생성하고 1시간안에 stop할 경우 프리티어로서 EC2사용시간은 총 750시간에 전혀 영향을 미치지 않습니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;총 6개의 EC2를 생성했지만 1시간에 1개의 EC2만 사용했으므로 문제가 없는것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 문제는 EC2를 terminate시키지않고 stop만 시켰다는것입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;EC2를 terminate시킬경우 함께만들어진 EBS도 없어지게 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/267C995056662A8A19&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F267C995056662A8A19&quot; width=&quot;1000&quot; height=&quot;296&quot; filename=&quot;Screenshot at 12월 08 09-51-20.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;하지만 위의 경우처럼 EC2&amp;nbsp;6개를 생성하고 stop만 해두었다면 6개의 EBS볼륨은 그대로 남아있게 됩니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;8GB x 6개 = 48GB를 사용하고 있으므로 프리티어 30GB를 초과하게되어 요금이 발생합니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;사용하지 않는 EC2가 있다면 stop이 아닌 terminate를 시켜주어 EBS 사용량 초과로 요금이 발생하는것을 막아주시길 바랍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이외에 추가적으로 프리티어를 사용하면서 알아두어야할 사항들이 있다면 댓글로 알려주시기 바랍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;프리티어 사용하면서 현재 사용량을 알고싶은경우나 내가설정한 요금이상으로 요금이 발생할경우 알림을 받고싶을때 아래 포스팅을 참고하시기 바랍니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://gun0912.tistory.com/35&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;[AWS]프리티어(Free Tier)사용량 확인하는 방법&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;&lt;/span&gt;&lt;a href=&quot;http://gun0912.tistory.com/11&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;[AWS]예상 청구요금 알림 받는 방법&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/AWS</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/45</guid>
      <comments>https://gun0912.tistory.com/45#entry45comment</comments>
      <pubDate>Tue, 8 Dec 2015 10:16:43 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]Security Group 접속가능한 IP대역 설정하는 방법</title>
      <link>https://gun0912.tistory.com/44</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 244px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/27662133565E3E3F1C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F27662133565E3E3F1C&quot; width=&quot;300&quot; height=&quot;244&quot; filename=&quot;firewall_man.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 244px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;서버를 운영하면서 기능을 개발하는것만큼 중요한것도 보안이라 할 수 있습니다.&lt;/p&gt;&lt;p&gt;AWS서비스를 이용하면서&amp;nbsp;보안과 관련해서는 로그인시 OTP를 이용하는 방법부터 여러가지 체크해야할 부분이 있는데요.&lt;/p&gt;&lt;p&gt;이번에는 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;허용된 ip에서만 해당 EC2나 RDS에 접근할 수 있도록 설정하는 방법&lt;/span&gt;에 대해 포스팅 해보겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;EC, RDS, ElastiCache 등을 이용하면서 우리는 Security Group이라는걸 이용합니다.&lt;/p&gt;&lt;p&gt;Security Group에 명시되어있는 port와 ip대역대만 해당 리소스에 접근할 수 있는 방식입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;기본으로 생성되어있는Security Group은 아래와 같이 모든 port/ip에서 접근할 수 있도록 세팅되어 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 750px; width: 750px; height: 138px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/231D7937565E3FFE24&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F231D7937565E3FFE24&quot; width=&quot;750&quot; height=&quot;138&quot; filename=&quot;Screenshot at 12월 02 09-48-50.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 750px; height: 138px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;EC2의 경우 특별한 경우를 제외하고는 2개의 Port만 열어주면 됩니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;- HTTP: &amp;nbsp;80Port&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;- SSH: 22Port&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 700px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/235F053C565E40AF21&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F235F053C565E40AF21&quot; width=&quot;700&quot; height=&quot;81&quot; filename=&quot;Screenshot at 12월 02 09-51-42.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;80번 포트는 일반 사용자들이 http로 접속을 해야하므로 ip를 지정할 필요가 없으므로&amp;nbsp;Anywhere의 개념인 0.0.0.0/0 으로 Source를 세팅해주면 됩니다.&lt;/p&gt;&lt;p&gt;하지만&lt;b&gt; 서버로의 터미널접속이나 파일전송을 위해 사용하는 22번 포트는 개발자 ip(혹은 해당회사의 ip)에서만 접근할 수 있게 해주는것이 보안적으로 좋습니다.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;h1&gt;IP접속제한 설정하기&lt;/h1&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;1. IP주소&amp;nbsp;및 서브넷마스크 확인&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;고정ip를 사용하신다면 정말 간단합니다.&lt;/p&gt;&lt;p&gt;자신의 ip주소만 허용가능한 ip로 적어주면 됩니다.&lt;/p&gt;&lt;p&gt;하지만 회사나 집에서 대부분 공유기를 사용하고 계시기때문에 ip가 변경된다거나 회사의 경우는 해당 공유기를 사용하는 ip대역대의 사람들만 접속하도록 설정하고 싶은경우가 있을겁니다.&lt;/p&gt;&lt;p&gt;우선 기준이 되는 IP주소와 서브넷마스크를 알아둡니다.&lt;/p&gt;&lt;p&gt;이정보는 보통 공유기의 [고급설정]-[네트워크관리]같은 곳에서 확인할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;2. Mask bit확인하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;IP주소가 218.123.255.11&amp;nbsp;이고 서브넷 마스크가 255.255.255.224 라고 가정해보겠습니다.&lt;/p&gt;&lt;p&gt;이럴경우 IP대역은&amp;nbsp;218.123.255.1 - 218.123.255.30 입니다.&lt;/p&gt;&lt;p&gt;즉, 해당 공유기에서&amp;nbsp;내가 받을수있는 IP범위는 218.123.255.1 - 218.123.255.30라는것입니다.&lt;/p&gt;&lt;p&gt;그리고 마스크Bit는 27 입니다.&lt;/p&gt;&lt;p&gt;정확한 이해를 위해서는 서브넷마스크에 대해서 좀더 공부해보셔야 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이것저것 다 귀찮은경우는 아래 사이트를 이용하시면됩니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;a href=&quot;http://www.subnet-calculator.com/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;http://www.subnet-calculator.com/&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;우리에게 필요한것은 IP주소 그리고 마스크 Bit입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 373px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/23131D4056618CFE49&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F23131D4056618CFE49&quot; width=&quot;373&quot; height=&quot;406&quot; filename=&quot;Screenshot_3.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;3. 정보입력&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;우리가 가져온정보 218.123.255.11 과 마스크Bit 27을 &lt;b&gt;218.123.255.11/27&lt;/b&gt; 의 형태로 넣어줍니다.&lt;/p&gt;&lt;p&gt;그렇게 넣어주면 아래 그림처럼 자동으로 서브넷ID를 설정해주고 마스크Bit까지 설정해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 700px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2574593F56618E2C25&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2574593F56618E2C25&quot; width=&quot;700&quot; height=&quot;79&quot; filename=&quot;Screenshot_4.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제 우리는 218.123.255.1 - 218.123.255.30 범위의 ip에서만 해당 리소스에 접근할 수 있도록 설정해두었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;여러가지 리소스에 해당 정보를 활용해서 접속가능한 ip대역을&amp;nbsp;설정해두시면 안전하게 서버를 운영하시는데 도움이 되실겁니다.&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/AWS</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/44</guid>
      <comments>https://gun0912.tistory.com/44#entry44comment</comments>
      <pubDate>Fri, 4 Dec 2015 22:02:52 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]Fragment에서 Activity의 onActivityForResult 받는 방법</title>
      <link>https://gun0912.tistory.com/43</link>
      <description>&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 400px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/250B0C3B565C18BD0D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F250B0C3B565C18BD0D&quot; width=&quot;400&quot; height=&quot;236&quot; filename=&quot;fragment_activity.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Fragment를 사용하면서 startActivity나 startActivityForResult를 사용하는 경우가 있습니다.&lt;/p&gt;&lt;p&gt;startActivity가 문제되는경우는 없지만 &lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;startActivityForResult에서 가끔 onActivityResult가 오지 않는 경우가 있습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;Nested Fragment구조로 되어있는 Fragment에서는 startActivirtyForResult의 결과가 Fragment가 아닌 Activity로 오게 됩니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Activity에 넘어온 결과를 Fragment로 넘겨주기위하여 Fragment내부에 함수를 만들어 해당 instance의 함수를 호출하거나 static 함수로 만들어두어 해당 함수를 호출하곤 하는데요.&lt;/p&gt;&lt;p&gt;이와 비슷한 방식이지만 event bus방식의 otto를 사용해서&amp;nbsp;좀더 심플하고 직관적으로 구현해보도록 하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/4&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;[안드로이드]유용한 라이브러리 - Otto(Event Bus)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;동작순서&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;- 부모 Activity에서 Fragment로 알려줄 Event클래스를 생성합니다.&lt;/p&gt;&lt;p&gt;- Fragment에서 Event를 받았을때 실행할 함수를 만들어 두고 해당 Event를 모니터링합니다.&lt;/p&gt;&lt;p&gt;- Fragment에서 startActivityForResult()를 호출합니다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;(이때 Fragment의&amp;nbsp;startActivityForResult를 실행하는것이 아닌 부모 Activity의 startActivityForResult를 실행해야 합니다)&lt;/p&gt;&lt;p&gt;- 실행된 Activity가 종료되면서 Fragment의 부모 Activity로 결과값을 리턴해줍니다&lt;/p&gt;&lt;p&gt;- 결과를 받은 Activity에서 Event를 생성해서 Fragment로 알려주면서 결과값을 보내줍니다.&lt;/p&gt;&lt;p&gt;- Fragment는 해당 Event를 받아서 1번에서 만들어준&amp;nbsp;동작을 수행합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;h1&gt;Fragment에서 Activity의 onActivityForResult 받기&lt;/h1&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;1. Event Class생성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;onActivityResult의 parameter들을 그대로 받아서 Fragment로 넘겨주기위해 해당 값들을 가지고 있는 Event Class를 생성해줍니다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;ActivityResultEvent {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;private int &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;requestCode&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    private int &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;resultCode&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    private &lt;/span&gt;Intent &lt;span style=&quot;color:#9876aa;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    public &lt;/span&gt;ActivityResultEvent(&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;requestCode&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;resultCode&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Intent data) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;requestCode &lt;/span&gt;= requestCode&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;resultCode &lt;/span&gt;= resultCode&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;data &lt;/span&gt;= data&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public int &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;getRequestCode&lt;/span&gt;() {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;requestCode&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setRequestCode&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;requestCode) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;requestCode &lt;/span&gt;= requestCode&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public int &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;getResultCode&lt;/span&gt;() {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;resultCode&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setResultCode&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;resultCode) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;resultCode &lt;/span&gt;= resultCode&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public &lt;/span&gt;Intent &lt;span style=&quot;color:#ffc66d;&quot;&gt;getData&lt;/span&gt;() {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;setData&lt;/span&gt;(Intent data) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;data &lt;/span&gt;= data&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;2. Event 함수 생성 및 모니터링&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1번에서 만들어둔 Event를 받았을때 실행할 함수를 만들어 줍니다.&lt;/p&gt;&lt;p&gt;저같은 경우는 Fragment의 onActivityResult로 데이터들을 바로 넘겨주는 방식으로 구현해 두었습니다.&lt;/p&gt;&lt;p&gt;onActivityResult함수에서 받은&amp;nbsp;결과값을 가지고 동작을 해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#629755;font-style:italic;&quot;&gt;/**&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#629755;font-style:italic;&quot;&gt; * NestedFragment에서 startactivityForresult실행시 fragment에 들어오지 않는 문제&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#629755;font-style:italic;&quot;&gt; *&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#629755;font-style:italic;&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;color:#629755;font-weight:bold;font-style:italic;&quot;&gt;@param &lt;/span&gt;&lt;span style=&quot;color:#8a653b;font-style:italic;&quot;&gt;activityResultEvent&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#8a653b;font-style:italic;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color:#629755;font-style:italic;&quot;&gt;*/&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Subscribe&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onActivityResult&lt;/span&gt;(ActivityResultEvent activityResultEvent){&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;onActivityResult(activityResultEvent.getRequestCode()&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;activityResultEvent.getResultCode()&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;activityResultEvent.getData())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또한, 이 Event를 받기위해서 register/unregister작업을 해주어야 합니다.&lt;/p&gt;&lt;p&gt;저는 BaseFragment를 만들어두고 거기에 register/unregister작업을 해둔뒤 모든 Fragment가 이 BaseFragment를 상속받아서 사용하도록 해두고 있습니다.&lt;/p&gt;&lt;p&gt;그렇게 만들어두면 Fragment를 생성할때마다 귀찮은 작업을 해주는걸 줄일 수 있습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onViewCreated&lt;/span&gt;(View view&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Nullable &lt;/span&gt;Bundle savedInstanceState) {&lt;br /&gt;   &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.onViewCreated(view&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;savedInstanceState)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;   &lt;/span&gt;BusProvider.&lt;span style=&quot;font-style:italic;&quot;&gt;getInstance&lt;/span&gt;().register(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onDestroyView&lt;/span&gt;() {&lt;br /&gt;   BusProvider.&lt;span style=&quot;font-style:italic;&quot;&gt;getInstance&lt;/span&gt;().unregister(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;      super&lt;/span&gt;.onDestroyView()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;3. Fragment에서 startActivityForResult 함수 실행&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;startActivityForResult함수를 실행할때 주의할점은 Fragment의 함수가 아닌 &amp;nbsp;Activity의 함수를 이용해주어야 한다는것입니다.&lt;/p&gt;&lt;p&gt;그래야 부모 Activity에서 결과값을 받았을때 동일한 requestCode값을 받아올 수 있습니다.&lt;/p&gt;&lt;p&gt;그렇지 않은경우 Fragment에서 실행했던 requestCode와 부모Activity에서 받은 requestCode가 달라서 해당 결과값을 받아올수 없는 문제가 발생합니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;getActivity().startActivityForResult(intent&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Constant.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;REQ_CODE_CONTENT_DETAIL&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;4. 부모 Activity에서 Event생성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;실행된 Activity가 종료되면 부모 Activity의 onActivityResult가 실행됩니다.&lt;/p&gt;&lt;p&gt;이때 1번에서 만들어둔 ActivityResultEvent를 생성해주면서 Fragment에서 이 이벤트를 받을수 있도록 해줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;protected void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onActivityResult&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;requestCode&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;resultCode&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Intent data) {&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    super&lt;/span&gt;.onActivityResult(requestCode&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;resultCode&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;data)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;BusProvider.&lt;span style=&quot;font-style:italic;&quot;&gt;getInstance&lt;/span&gt;().post(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ActivityResultEvent(requestCode&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;resultCode&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;data))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이렇게되면 2번에서 해당 Event를 받았을때 동작할 함수를 만들어두었기때문에 Fragment에서 일을 처리할 수 있게됩니다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;이를 잘 응용한다면 onBackPressed()이벤트도 충분히 Fragment에서 받아서 처리할 수 있게됩니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;이뿐만 아니라 여러가지 상황을 간단하게 otto를 활용해서 구현해보시면 훨씬 간단하고 직관적인 코드를 만드실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/43</guid>
      <comments>https://gun0912.tistory.com/43#entry43comment</comments>
      <pubDate>Mon, 30 Nov 2015 18:43:03 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]CoordinatorLayout Behavior를 이용해 FooterView 숨기기/보여주기</title>
      <link>https://gun0912.tistory.com/42</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 270px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2714BB4156559D3D10&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2714BB4156559D3D10&quot; width=&quot;270&quot; height=&quot;480&quot; filename=&quot;JiGlH.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래 화면처럼 ScrollView나 RecyclerView가 스크롤시 아래에 있는 배너나 기타&amp;nbsp;Footer버튼을&amp;nbsp; 없애주고 보여주는 기능을 보여주고 싶은때가 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 250px; width: 250px; height: 445px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/246D02475655009E1C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F246D02475655009E1C&quot; width=&quot;250&quot; height=&quot;445&quot; filename=&quot;2015_11_25_09_21_511.gif&quot; filemime=&quot;image/gif&quot; style=&quot;width: 250px; height: 445px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;보통 Quick return Header/Footer로 검색하시면 많은 참고자료및 라이브러리를 찾아볼 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;u&gt;&lt;a href=&quot;http://android-developers.blogspot.kr/2015/05/android-design-support-library.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Android Support Design Library&lt;/span&gt;&lt;/a&gt;&lt;/u&gt; 이전에는 대부분 라이브러리들이 RecyclerView/ScrollView에 스크롤리스너를 달아서 그 안에 함수를 구현해주고 스크롤되고있는 item위치에 따라서 ShowView()/HideView()의 방식으로 구현되어 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;이제는 각각&amp;nbsp;View에 ScrollLister를 달지말고 Behavior를 사용하면 됩니다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Support Design Library의 등장으로 behavior개념이 생기면서 간단하게 Behavior클래스를 만들어주고 이를 재사용하면 여러군데에서 사용할 수 있게됩니다.&lt;/p&gt;&lt;p&gt;정확히는 &lt;u&gt;&lt;a href=&quot;https://developer.android.com/intl/ko/reference/android/support/design/widget/CoordinatorLayout.Behavior.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);&quot;&gt;C&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://developer.android.com/intl/ko/reference/android/support/design/widget/CoordinatorLayout.Behavior.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);&quot;&gt;oordinatorLayout의&amp;nbsp;&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://developer.android.com/intl/ko/reference/android/support/design/widget/CoordinatorLayout.Behavior.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);&quot;&gt;Behavior&lt;/span&gt;&lt;/a&gt;&lt;/u&gt; 를 활용합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;h1&gt;Custom Behavior만들기&lt;/h1&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;1. Class만들기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;CoordinatorLayout.Behavior&amp;lt;View&amp;gt; 를 상속받은 CustomBehavior클래스를 만들어 줍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;QuickReturnFooterBehavior &lt;span style=&quot;color:#cc7832;&quot;&gt;extends &lt;/span&gt;CoordinatorLayout.Behavior&amp;lt;View&amp;gt; {&lt;br /&gt;    &lt;br /&gt;    &lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;2. 스크롤에 반응하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;가로방향의 스크롤일경우에만 Footer View를 숨기거나 보여줄것이기 때문에 nestedScrollAxes값이 Vertical(세로)방향일 경우에만 true를 리턴해줍니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public boolean &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onStartNestedScroll&lt;/span&gt;(&lt;span style=&quot;color:#bbb529;&quot;&gt;@NonNull &lt;/span&gt;CoordinatorLayout coordinatorLayout&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@NonNull &lt;/span&gt;View child&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@NonNull &lt;/span&gt;View directTargetChild&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@NonNull &lt;/span&gt;View target&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;axes&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;type) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;axes == ViewCompat.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;SCROLL_AXIS_VERTICAL&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;&lt;b&gt;3. Footer View hide/show&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;스크롤 y값의 변화와 현재 Footer View의 상태에 따라서 Footer View를 숨기거나 보여주는 판단을 해줍니다.&lt;/p&gt;&lt;p&gt;onNestedPreScroll안의 hide/show 판단은 기존에 ScrollView/RecyclerView에 ScrollLister를 달아준뒤 그 안에서 하던 작업과 비슷한 일을 하게됩니다.&lt;/p&gt;&lt;p&gt;1. 위/아래방향으로 일정한 방향으로 향하던 도중에 방향이 바뀌는경우(원래 진행하던 방향과 현재 진행방향이&amp;nbsp;반대) 모든 작업을 초기화하고 다시 시작합니다.&lt;/p&gt;&lt;p&gt;2. 스크롤방향이 위/아래 방향으로 가는경우 숨기거나 보여주는 작업을 수행합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onNestedPreScroll&lt;/span&gt;(&lt;span style=&quot;color:#bbb529;&quot;&gt;@NonNull &lt;/span&gt;CoordinatorLayout coordinatorLayout&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@NonNull &lt;/span&gt;View child&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@NonNull &lt;/span&gt;View target&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;dx&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;dy&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@NonNull &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;int&lt;/span&gt;[] consumed&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;type) {&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 스크롤이 반대방향으로 전환&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(dy &amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;0 &lt;/span&gt;&amp;amp;&amp;amp; &lt;span style=&quot;color:#9876aa;&quot;&gt;dyDirectionSum &lt;/span&gt;&amp;lt; &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;            &lt;/span&gt;|| dy &amp;lt; &lt;span style=&quot;color:#6897bb;&quot;&gt;0 &lt;/span&gt;&amp;amp;&amp;amp; &lt;span style=&quot;color:#9876aa;&quot;&gt;dyDirectionSum &lt;/span&gt;&amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;) {&lt;br /&gt;        child.animate().cancel()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;dyDirectionSum &lt;/span&gt;= &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;dyDirectionSum &lt;/span&gt;+= dy&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;dyDirectionSum &lt;/span&gt;&amp;gt; child.getHeight()) {&lt;br /&gt;        hideView(child)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;else if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;dyDirectionSum &lt;/span&gt;&amp;lt; -child.getHeight()) {&lt;br /&gt;        showView(child)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;&lt;b&gt;4. hideView/ShowView 구현&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위에서 사용한 hideView와 showView 함수를 구현해줍니다.&lt;/p&gt;&lt;p&gt;이 함수 또한 기존에 사용하던 ScrollLister를 달고 hide/show 하던 함수와 같은 방식으로 만들어주시면 됩니다.&lt;/p&gt;&lt;p&gt;여기서는 hideView 애니메이션이 끝난뒤에 INVISIBLE을 해줍니다.(GONE처리하는경우 Behavior 이벤트를 받지 못하게 됩니다.)&lt;/p&gt;&lt;p&gt;showView 애니메이션이 시작하기전에 VISIBLE을 해주었지만 취향에 맞게 변경하셔도 됩니다.&lt;/p&gt;&lt;p&gt;또한 애니메이션 시간도 원하는대로 변경하고 여기서는 FastOutSlowInInterpolator InterPolator를 사용하였지만 얼마든지 다른것으로 변경하셔도 좋습니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;hideView&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;final &lt;/span&gt;View view) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;isHiding &lt;/span&gt;|| view.getVisibility() != View.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;VISIBLE&lt;/span&gt;) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    ViewPropertyAnimator animator = view.animate()&lt;br /&gt;            .translationY(view.getHeight())&lt;br /&gt;            .setInterpolator(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;INTERPOLATOR&lt;/span&gt;)&lt;br /&gt;            .setDuration(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ANIMATION_DURATION&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;animator.setListener(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Animator.AnimatorListener() {&lt;br /&gt;        &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onAnimationStart&lt;/span&gt;(Animator animator) {&lt;br /&gt;            &lt;span style=&quot;color:#9876aa;&quot;&gt;isHiding &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;true;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onAnimationEnd&lt;/span&gt;(Animator animator) {&lt;br /&gt;            &lt;span style=&quot;color:#9876aa;&quot;&gt;isHiding &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;false;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#b389c5;&quot;&gt;view&lt;/span&gt;.setVisibility(View.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;INVISIBLE&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onAnimationCancel&lt;/span&gt;(Animator animator) {&lt;br /&gt;            &lt;span style=&quot;color:#808080;&quot;&gt;// 취소되면 다시 보여줌&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;isHiding &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;false;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;showView(&lt;span style=&quot;color:#b389c5;&quot;&gt;view&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onAnimationRepeat&lt;/span&gt;(Animator animator) {&lt;br /&gt;            &lt;span style=&quot;color:#808080;&quot;&gt;// no-op&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;    })&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;animator.start()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;showView&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;final &lt;/span&gt;View view) {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;isShowing &lt;/span&gt;|| view.getVisibility() == View.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;VISIBLE&lt;/span&gt;) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    ViewPropertyAnimator animator = view.animate()&lt;br /&gt;            .translationY(&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;)&lt;br /&gt;            .setInterpolator(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;INTERPOLATOR&lt;/span&gt;)&lt;br /&gt;            .setDuration(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;ANIMATION_DURATION&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;animator.setListener(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Animator.AnimatorListener() {&lt;br /&gt;        &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onAnimationStart&lt;/span&gt;(Animator animator) {&lt;br /&gt;            &lt;span style=&quot;color:#9876aa;&quot;&gt;isShowing &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;true;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#b389c5;&quot;&gt;view&lt;/span&gt;.setVisibility(View.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;VISIBLE&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onAnimationEnd&lt;/span&gt;(Animator animator) {&lt;br /&gt;            &lt;span style=&quot;color:#9876aa;&quot;&gt;isShowing &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;false;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onAnimationCancel&lt;/span&gt;(Animator animator) {&lt;br /&gt;            &lt;span style=&quot;color:#808080;&quot;&gt;// 취소되면 다시 숨김&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;isShowing &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;false;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;hideView(&lt;span style=&quot;color:#b389c5;&quot;&gt;view&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onAnimationRepeat&lt;/span&gt;(Animator animator) {&lt;br /&gt;            &lt;span style=&quot;color:#808080;&quot;&gt;// no-op&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;    })&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;animator.start()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;전체 소스코드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/ParkSangGwon/a0abd8247ffb9c00169b.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Behavior를 잘 이용해서 Footer뿐만 아니라 Header도 숨기기/보여주기로도 응용가능합니다.&lt;/p&gt;&lt;p&gt;또한 Google의 여러 앱에서 보여지는 hide/show 방식도 얼마든지 원하는대로 만들 수 있습니다.&lt;/p&gt;&lt;p&gt;좀더 많은 팁이나 정보는 아래 링크들을 참고해보셔도 좋습니다.&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;유용한 링크&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://readme.skplanet.com/?p=11463&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;CoordinatorLayout 을 위한 Custom Behavior 구현&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://saulmm.github.io/mastering-coordinator/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;Mastering the Coordinator Layout&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://alisonhuang-blog.logdown.com/posts/290009-design-support-library-coordinator-layout-and-behavior&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;Design Support Library: Coordinator layout and Behavior&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://medium.com/@bherbst/quick-return-with-recyclerview-e70c8da9b4c1#.en0y9ucsq&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;Quick return with CoordinatorLayout&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/42</guid>
      <comments>https://gun0912.tistory.com/42#entry42comment</comments>
      <pubDate>Wed, 25 Nov 2015 20:33:24 +0900</pubDate>
    </item>
    <item>
      <title>Event bus [Bus &amp;quot;default&amp;quot;] accessed from non-main thread Looper</title>
      <link>https://gun0912.tistory.com/41</link>
      <description>&lt;p&gt;Otto를 사용하는경우 GCM을 위한 intentservice같은 곳곳에서 post를 보내는경우 오류가 발생할 수 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Otto의 Bus클래스를 상속받아서 아래와같은 클래스를 만들고 이 클래스를 사용한다&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;CustomBus &lt;span style=&quot;color:#cc7832;&quot;&gt;extends &lt;/span&gt;Bus {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;private final &lt;/span&gt;Handler &lt;span style=&quot;color:#9876aa;&quot;&gt;mHandler &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Handler(Looper.&lt;span style=&quot;font-style:italic;&quot;&gt;getMainLooper&lt;/span&gt;())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;post&lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;final &lt;/span&gt;Object event) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(Looper.&lt;span style=&quot;font-style:italic;&quot;&gt;myLooper&lt;/span&gt;() == Looper.&lt;span style=&quot;font-style:italic;&quot;&gt;getMainLooper&lt;/span&gt;()) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.post(event)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;else &lt;/span&gt;{&lt;br /&gt;            &lt;span style=&quot;color:#9876aa;&quot;&gt;mHandler&lt;/span&gt;.post(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;Runnable() {&lt;br /&gt;                &lt;span style=&quot;color:#bbb529;&quot;&gt;@Override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;run&lt;/span&gt;() {&lt;br /&gt;                    CustomBus.&lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.post(&lt;span style=&quot;color:#b389c5;&quot;&gt;event&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;}&lt;br /&gt;            })&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-ERROR&amp;amp;SOLVE</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/41</guid>
      <comments>https://gun0912.tistory.com/41#entry41comment</comments>
      <pubDate>Mon, 16 Nov 2015 19:15:05 +0900</pubDate>
    </item>
    <item>
      <title>[Android ERROR&amp;amp;SOLVE]GC overhead limit exceeded</title>
      <link>https://gun0912.tistory.com/40</link>
      <description>&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;현상&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;-&amp;nbsp;Execution failed for task ':app:preDexDebug'.&lt;/p&gt;&lt;p&gt;-&amp;nbsp;com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: .... finished with non-zero exit value 1&lt;/p&gt;&lt;p&gt;-&amp;nbsp;GC overhead limit exceeded &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;이유&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;- heap의 용량을 넘어서면서 오류가 발생&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;해결방법&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1. build.gradle의 dexOptions에 Heap크기 지정&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;br /&gt;dexOptions {&lt;br /&gt;    &lt;span style=&quot;color:#9876aa;&quot;&gt;incremental &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;true&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;javaMaxHeapSize &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;4g&quot;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-ERROR&amp;amp;SOLVE</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/40</guid>
      <comments>https://gun0912.tistory.com/40#entry40comment</comments>
      <pubDate>Fri, 6 Nov 2015 19:58:01 +0900</pubDate>
    </item>
    <item>
      <title>[Android ERROR&amp;amp;SOLVE]org.apache.http does not exist</title>
      <link>https://gun0912.tistory.com/39</link>
      <description>&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;이유&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;- 안드로이드 6.0 버전으로 오면서 Apache http를 지원하지 않음&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://developer.android.com/intl/ko/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;https://developer.android.com/intl/ko/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span id=&quot;behavior-apache-http-client&quot; style=&quot;color: rgba(0, 0, 0, 0.870588); clear: left; font-size: 28px; font-weight: 400; line-height: 32px; margin: 24px 0px 0px; animation-name: glowheader; animation-duration: 0.7s; animation-timing-function: ease-out; font-family: Roboto, sans-serif; -webkit-user-select: auto !important;&quot;&gt;Apache HTTP Client&amp;nbsp;Removal&lt;/span&gt;&lt;hr style=&quot;height: 1px; margin: 7px 0px 12px; border: 0px; color: rgba(0, 0, 0, 0.682353); font-family: Roboto, sans-serif; font-size: 14px; line-height: 24px; -webkit-user-select: auto !important; background: rgb(229, 229, 229);&quot;&gt;&lt;p style=&quot;margin-right: 0px; margin-bottom: 12px; margin-left: 0px; color: rgba(0, 0, 0, 0.682353); font-family: Roboto, sans-serif; font-size: 14px; line-height: 24px; -webkit-user-select: auto !important;&quot;&gt;Android 6.0 release removes support for the Apache HTTP client. If your app is using this client and targets Android 2.3 (API level 9) or higher, use the&amp;nbsp;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; line-height: 18px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; -webkit-user-select: auto !important; background-color: rgb(247, 247, 247);&quot;&gt;&lt;a href=&quot;https://developer.android.com/reference/java/net/HttpURLConnection.html&quot; style=&quot;color: rgb(3, 155, 229); -webkit-user-select: auto !important;&quot;&gt;HttpURLConnection&lt;/a&gt;&lt;/code&gt;&amp;nbsp;class instead. This API is more efficient because it reduces network use through transparent compression and response caching, and minimizes power consumption. To continue using the Apache HTTP APIs, you must first declare the following compile-time dependency in your&amp;nbsp;&lt;code style=&quot;font-size: 13px; color: rgb(0, 102, 0); font-stretch: normal; line-height: 18px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 3px 5px; -webkit-user-select: auto !important; background-color: rgb(247, 247, 247);&quot;&gt;build.gradle&lt;/code&gt;&amp;nbsp;file:&lt;/p&gt;&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 13px; margin-top: 0px; color: rgb(0, 102, 0); font-stretch: normal; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 1em; border: 1px solid rgb(221, 221, 221); -webkit-user-select: auto !important; overflow: auto !important; background: rgb(247, 247, 247);&quot;&gt;&lt;span class=&quot;pln&quot; style=&quot;-webkit-user-select: auto !important; color: rgb(0, 0, 0);&quot;&gt;android &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;-webkit-user-select: auto !important; color: rgb(102, 102, 0);&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;-webkit-user-select: auto !important; color: rgb(0, 0, 0);&quot;&gt;&lt;br style=&quot;-webkit-user-select: auto !important;&quot;&gt;&amp;nbsp; &amp;nbsp; useLibrary &lt;/span&gt;&lt;span class=&quot;str&quot; style=&quot;-webkit-user-select: auto !important; color: rgb(136, 0, 0);&quot;&gt;'org.apache.http.legacy'&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;-webkit-user-select: auto !important; color: rgb(0, 0, 0);&quot;&gt;&lt;br style=&quot;-webkit-user-select: auto !important;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;-webkit-user-select: auto !important; color: rgb(102, 102, 0);&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class=&quot;pun&quot; style=&quot;-webkit-user-select: auto !important; color: rgb(102, 102, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(255, 0, 0);&quot;&gt;해결방법&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;1. /build.gradle파일에 gradle버전 업데이트&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;buildscript {&lt;br /&gt;    ...&lt;br /&gt;    dependencies {&lt;br /&gt;        classpath &lt;span style=&quot;color:#6a8759;&quot;&gt;'com.android.tools.build:gradle:1.3.1'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;       &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;2. /app/build.gradle 파일 수정&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;p&gt;&lt;br /&gt;android {&lt;br /&gt;    compileSdkVersion &lt;span style=&quot;color:#6897bb;&quot;&gt;23&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;    &lt;/span&gt;buildToolsVersion &lt;span style=&quot;color:#6a8759;&quot;&gt;'23.0.1'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// 6.0으로 바뀌면서 apache 없어짐&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;useLibrary &lt;span style=&quot;color:#6a8759;&quot;&gt;'org.apache.http.legacy'&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;span style=&quot;color:#6a8759;&quot;&gt;&lt;br /&gt;&lt;/span&gt;}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-ERROR&amp;amp;SOLVE</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/39</guid>
      <comments>https://gun0912.tistory.com/39#entry39comment</comments>
      <pubDate>Thu, 5 Nov 2015 19:57:36 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]CustomView를 만들어서 재사용하기</title>
      <link>https://gun0912.tistory.com/38</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;이전 포스팅에서 Style테마를 이용하여 일정한 레이아웃의 속성을 만들고 이를 재사용하는 방법에 대해서 알아 보았습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/37&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255); font-family: Dotum, 돋움;&quot;&gt;[안드로이드]style테마 활용으로 노가다코딩 줄이는 방법&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: Dotum, 돋움;&quot;&gt;이 방법보다 좀더 심화된 방식인 Custom View를 만드는 방법&lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;에 대해서 포스팅 해보겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;먼저 아래 사진을 예로 들어보겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;로그인버튼이 각각 3개씩 있는 레이아웃입니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 200px; width: 200px; height: 355px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/272C2635563743330E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F272C2635563743330E&quot; width=&quot;200&quot; height=&quot;355&quot; filename=&quot;로그인1.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 200px; height: 355px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;잘 보면 3개의 버튼이 레이아웃 구성이 똑같은걸 알 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;기본적인 로그인보튼의 형태는 같지만 아이콘, 텍스트, 배경색상, 텍스트 색상등은 서로 다른것을 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;각각의 버튼 layout은 아래와 같을 것입니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 436px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2228563A563744C203&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2228563A563744C203&quot; width=&quot;436&quot; height=&quot;59&quot; filename=&quot;Screenshot at 11월 02 20-10-45.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;xml version=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;1.0&quot; &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;encoding=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;&amp;lt;LinearLayout &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;xmlns:&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@+id/bg&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;match_parent&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;55dp&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:background=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_kakao_bg&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:gravity=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:padding=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;10dp&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#808080;font-style:italic;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;lt;!-- android:background=&quot;@drawable/kakao_login_button_background&quot; --&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;font-style:italic;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;font-style:italic;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(128, 128, 128); font-style: italic; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;lt;ImageView&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@+id/symbol&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;wrap_content&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;32dp&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:layout_gravity=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;center_vertical&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:layout_marginLeft=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;20dp&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:src=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_kakao_symbol&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;    &amp;lt;TextView&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@+id/text&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@style/CustomText_Subhead&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;0dp&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;match_parent&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:layout_weight=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:gravity=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;카카오톡 로그인&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@color/kakao_brown&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:textStyle=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;bold&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;lt;/LinearLayout&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 9pt; line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 9pt; line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;위의 화면처럼 버튼이 3개라면 저 레이아웃 소스코드를 3번 복사/붙여넣기 해서 장문의 레이아웃을 만들겠죠...&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;만약에 버튼이 10개라면? 100개라면??&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;그러다가 padding값을 10dp에서 16dp로 바꾸고싶다면??&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;상상만 해도 끔찍합니다.(복사 붙여넣기보다 더 무서운게 그것들을 전부다 한땀한땀 수정하는 작업이겠죠...)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;이러한 경우는 앞서배운 style테마를 이용하는것보다 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: Dotum, 돋움;&quot;&gt;CustomView를 만들어서 이를 재사용하는것이 좋습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;우리는 로그인버튼의 레이아웃형태는 그대로 유지하고 아이콘과 텍스트만 변경하고 싶습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;결론적으로 만들어진 CustomView를 사용하면 아래와 같이 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;우선 미리 완성된 CustomView의 사용예제를 살펴보겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;lt;kr.co.selphone.welcome.login.CustomLoginButton&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@+id/login_kakao&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@style/LoginButtonStyle&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:bg=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_kakao_bg&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:symbol=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_kakao_symbol&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;카카오톡&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@color/kakao_brown&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;custom하게 만든 속성을 이용해서 배경색, 아이콘 이미지, 텍스트, 텍스트 색상 등을 지정할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;위의&amp;nbsp;3개의 서로다른 로그인버튼을 만들고자 하는경우는 아래와 같이 사용해 주면 됩니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;lt;kr.co.selphone.welcome.login.CustomLoginButton&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@+id/login_kakao&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@style/LoginButtonStyle&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:bg=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_kakao_bg&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:symbol=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_kakao_symbol&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;카카오톡&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@color/kakao_brown&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;lt;kr.co.selphone.welcome.login.CustomLoginButton&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@+id/login_naver&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@style/LoginButtonStyle&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:bg=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_naver_bg&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:symbol=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_naver_symbol&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&amp;nbsp;   &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;네이버&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@color/white&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;lt;kr.co.selphone.welcome.login.CustomLoginButton&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@+id/login_google&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@style/LoginButtonStyle&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:bg=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_google_bg&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:symbol=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_google_symbol&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;구글&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@color/google_red&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;복잡한 레이아웃 구성도 하나의 CustomView로 만들어준뒤 해당 CustomView를 재사용하면 편리하고 유용하게 화면을 구성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;h1&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;CustomView 만들기&lt;/span&gt;&lt;/h1&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(255, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(255, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(255, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(255, 0, 0); font-family: Dotum, 돋움;&quot;&gt;1. layout xml파일 생성&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;CustomView의 기본으로 쓰일 layout xml파일을 만들어 줍니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;

&lt;/span&gt;&lt;script src=&quot;https://gist.github.com/ParkSangGwon/74517d0aa2f4ff3a78fe.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt; font-family: Dotum, 돋움;&quot;&gt;2. attrs.xml 설정&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;custom하게 만들어줄 attribute를 설정해줍니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;value -&amp;gt; attrs.xml 파일에 아래 내용을 추가해줍니다.(만약 해당 파일이 없다면 만드시면 됩니다.)&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;&amp;lt;declare-styleable &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;LoginButton&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &amp;lt;attr &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;bg&quot; &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;format=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;reference|integer&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &amp;lt;attr &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;symbol&quot; &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;format=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;reference|integer&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &amp;lt;attr &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;text&quot; &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;format=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;reference|string&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &amp;lt;attr &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;textColor&quot; &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;format=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;reference|integer&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;lt;/declare-styleable&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;이 attr 속성을 보았을때 4가지를 속성값으로 받아서 적용할 수 있게 할것입니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;color: rgb(169, 183, 198); font-family: Menlo; font-size: 12pt; background-color: rgb(43, 43, 43);&quot;&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &amp;lt;attr &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;text&quot; &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;format=&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;&quot;reference|string&quot; &lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(51, 51, 51); font-family: Dotum, 돋움; font-size: 9pt; line-height: 1.5; background-color: rgb(255, 255, 255);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;이 attr은 나중에 app:text=&quot;.....&quot; 로 쓰일수 있으며 '가나다라' 같은 직접적인 String과 @string/aaaa 같은 reference를 넣어줄 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt; font-family: Dotum, 돋움;&quot;&gt;3. CustomView 만들기&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;(클래스 전체 소스는 아래에 있습니다)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;1) CustomView의 생성자에서 initView, getAttrs 함수를 사용합니다&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;public &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;CustomLoginButton(Context context) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;(context)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;initView()&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;public &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;CustomLoginButton(Context context&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;AttributeSet attrs) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;(context&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;attrs)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;initView()&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;getAttrs(attrs)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;public &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;CustomLoginButton(Context context&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;AttributeSet attrs&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, int &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;defStyle) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;(context&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;attrs)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;initView()&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;getAttrs(attrs&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;defStyle)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;2) initView()에서는 미리 만들어둔 xml 파일을 할당해주고 각각의 View를 설정해줍니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 198, 109); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;initView&lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;() {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;    String infService = Context.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;LAYOUT_INFLATER_SERVICE&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;LayoutInflater li = (LayoutInflater) getContext().getSystemService(infService)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;View v = li.inflate(R.layout.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;welcome_login_button&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;, this, false&lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;addView(v)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;bg &lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;= (LinearLayout) findViewById(R.id.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;bg&lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;symbol &lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;= (ImageView) findViewById(R.id.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;symbol&lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;text &lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;= (TextView) findViewById(R.id.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Dotum, 돋움; font-size: 12pt;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;3) getAttrs() 및 setTypeArray()함수에서는 우리가 attrs.xml 에 선언해둔 attribute를 이용하여 이를 각각의 View에 설정해주는 작업을 합니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'NanumGothicCoding';font-size:9.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 198, 109); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;getAttrs&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;(AttributeSet attrs) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    TypedArray typedArray = getContext().obtainStyledAttributes(attrs&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;R.styleable.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;LoginButton&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;setTypeArray(typedArray)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 198, 109); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;getAttrs&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;(AttributeSet attrs&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, int &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;defStyle) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    TypedArray typedArray = getContext().obtainStyledAttributes(attrs&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;R.styleable.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;LoginButton&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;defStyle&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: rgb(104, 151, 187); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;setTypeArray(typedArray)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;private void &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 198, 109); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;setTypeArray&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;(TypedArray typedArray) {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;int &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;bg_resID = typedArray.getResourceId(R.styleable.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;LoginButton_bg&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;R.drawable.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;login_naver_bg&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;bg&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;.setBackgroundResource(bg_resID)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    int &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;symbol_resID = typedArray.getResourceId(R.styleable.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;LoginButton_symbol&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;R.drawable.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;login_naver_symbol&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;symbol&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;.setImageResource(symbol_resID)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    int &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;textColor = typedArray.getColor(R.styleable.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;LoginButton_textColor&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: rgb(104, 151, 187); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;.setTextColor(textColor)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;String text_string = typedArray.getString(R.styleable.&lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-style: italic; font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;LoginButton_text&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;.setText(text_string)&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(204, 120, 50); font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;typedArray.recycle()&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Dotum, 돋움;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;아래는 CustomLoginButton의 전체 소스코드 입니다&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;

&lt;/span&gt;&lt;script src=&quot;https://gist.github.com/ParkSangGwon/6ab6677f74b22b0b9505.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;이렇게 완성된&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: Dotum, 돋움;&quot;&gt; CustomView를 사용하고자하는 xml에서 아래와 같이 재사용해주면 됩니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;물론 여러번 재사용할때도 CustomView을 사용하고 각각 bg,symbol,text,textColor에 맞는 값을 넣어주시면 됩니다.&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&amp;lt;kr.co.selphone.welcome.login.CustomLoginButton&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(232, 191, 106); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:id=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@+id/login_kakao&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@style/LoginButtonStyle&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:bg=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_kakao_bg&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:symbol=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@drawable/login_kakao_symbol&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:text=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;카카오톡&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: rgb(152, 118, 170); font-family: Dotum, 돋움;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: rgb(186, 186, 186); font-family: Dotum, 돋움;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;&quot;@color/kakao_brown&quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(165, 194, 97); font-family: Dotum, 돋움;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;위의 예재대로 그대로 따라해보시고 CustomView를 만드는 원리에 대해서 이해하셨다면 충분히 이를 응용해서 원하시는 CustomView를 만드실 수 있을겁니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;이상 CustomView를 만들어서 재사용하는 방법에 대해 소개 해드렸습니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum, 돋움;&quot;&gt;감사합니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/38</guid>
      <comments>https://gun0912.tistory.com/38#entry38comment</comments>
      <pubDate>Mon, 2 Nov 2015 21:45:00 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]style테마 활용으로 노가다코딩 줄이는 방법</title>
      <link>https://gun0912.tistory.com/37</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;우리는 안드로이드를 개발하면서 정말 많은 화면을 만들고 그에 맞는 layout xml파일을 만듭니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;가끔 화면을 구성하다보면 View 안에 설정값들이 거의 똑같고 일부만 다른 경우를 볼 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래 화면의 경우 [공지사항],[홈페이지],[페이스북] 등의 메뉴들이 모두 같은 padding,margin,textcolor 등등을 가지고 있고 text내용만 다른것을 확인해 볼 수 있습니다.&lt;/p&gt;&lt;p&gt;이러한경우 보통 우리는 TextView를 만들고 원하는 padding,margin등등을 준 뒤에 해당 코드를 계속 복사/붙여넣기 노가다 작업을 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/22736C4856316BE215&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F22736C4856316BE215&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot_2015-10-29-09-42-12.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;예를들어 각 TextView가 아래와 같이 구성되어있다고 가정해 보겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginLeft=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;5dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginRight=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;10dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginBottom=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;15dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:paddingRight=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;3dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:paddingLeft=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;8dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@color/white&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:background=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@color/custom_main&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;만약 이런 뷰를 여러개 생성해야한다면 우리는 c,v를 이용해 끝없이 복사/붙여넣기를 할것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xml version=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;1.0&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;encoding=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;?&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;LinearLayout &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xmlns:&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:orientation=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;vertical&quot; &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;match_parent&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginLeft=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;5dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginRight=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;10dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginBottom=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;15dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:paddingRight=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;3dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:paddingLeft=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;8dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@color/white&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:background=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@color/custom_main&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginLeft=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;5dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginRight=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;10dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginBottom=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;15dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:paddingRight=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;3dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:paddingLeft=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;8dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@color/white&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:background=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@color/custom_main&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;wrap_content&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginLeft=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;5dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginRight=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;10dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_marginBottom=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;15dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:paddingRight=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;3dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:paddingLeft=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;8dp&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:textColor=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@color/white&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:background=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@color/custom_main&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;.&lt;br /&gt;    .&lt;br /&gt;    .&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/LinearLayout&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이러한 방식의 문제는 효율적이지못한 코드라는것도 있지만 설정값을 수정하는것에 대해서 유연하게 대처할 수 없습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;만약 8dp로 되어있는 paddingLeft값을 변경하고자 하는경우 모든 TextView의 paddingLeft값을 찾아서 한땀한땀 수정해주어야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;b&gt;안드로이드에서 style을 잘 활용하면 이런 노가다작업과 수정작업에 유연하게 대처할 수 있습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;1. style.xml에 원하고자하는 View의 설정값들을 정의&lt;/span&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;해&lt;/span&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;줍니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;style &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;CustomTextView&quot;  &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;parent=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@android:style/Widget.TextView&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;android:layout_width&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;match_parent&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;android:layout_height&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;wrap_content&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;android:layout_marginLeft&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;5dp&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;android:layout_marginRight&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;10dp&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;android:layout_marginBottom&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;15dp&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;android:paddingRight&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;3dp&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;android:paddingLeft&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;8dp&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;android:textColor&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;@color/white&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;item &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;android:background&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;/span&gt;@color/custom_main&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;2. layout의 해당 TextView에서는 이 style을 적용시켜 줍니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xml version=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;1.0&quot; &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;encoding=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;?&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;LinearLayout &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;xmlns:&lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;http://schemas.android.com/apk/res/android&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:orientation=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;vertical&quot; &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_width=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;match_parent&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:layout_height=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;match_parent&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@style/CustomTextView&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@style/CustomTextView&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &amp;lt;TextView&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;style=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@style/CustomTextView&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;.&lt;br /&gt;    .&lt;br /&gt;    .&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;/LinearLayout&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;style.xml에서 정의해둔 설정대로 모든 TextView가 적용받게 됩니다.&lt;/p&gt;&lt;p&gt;만약 일부 설정값들을 변경하고싶은경우 style.xml에서 수정해주기만하면 이를 참조하는 모든 TextView가 변경됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이를 잘 응용하면 기본 Base style을 만들어두고 또 이를 상속받아 각각에서 필요한것들을 style에 정의 해둔뒤 여러 layout에서 활용할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;불필요한 노가다 작업과 설정값 변경작업도중 누락되는것을 막기위해 유용한 방법으로 style.xml을 많이 활용하시기 바랍니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;감사합니다.&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/37</guid>
      <comments>https://gun0912.tistory.com/37#entry37comment</comments>
      <pubDate>Thu, 29 Oct 2015 09:59:34 +0900</pubDate>
    </item>
    <item>
      <title>[Android ERROR&amp;amp;SOLVE]Default Activity Not Found</title>
      <link>https://gun0912.tistory.com/36</link>
      <description>&lt;p&gt;잘되던 프로젝트인데 빌드만 되고 앱이 실행되않는 경우가 있다.&lt;/p&gt;&lt;p&gt;이때 Default Activity Not Found라는 에러를 확인할수 있다.&lt;/p&gt;&lt;p&gt;안드로이드스튜디오에서 IDE cache를 삭제해주면 해결된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class=&quot;default prettyprint prettyprinted&quot; style=&quot;margin-top: 0px; padding: 5px; border: 0px; font-size: 13px; width: 660px; max-height: 600px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; color: rgb(57, 51, 24); word-wrap: normal; -webkit-user-select: auto !important; margin-bottom: 5px !important; overflow: auto !important; background-color: rgb(238, 238, 238);&quot;&gt;&lt;code style=&quot;margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; white-space: inherit; -webkit-user-select: auto !important;&quot;&gt;&lt;span class=&quot;typ&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(43, 145, 175); -webkit-user-select: auto !important;&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0); -webkit-user-select: auto !important;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0); -webkit-user-select: auto !important;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0); -webkit-user-select: auto !important;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(43, 145, 175); -webkit-user-select: auto !important;&quot;&gt;Invalidate&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0); -webkit-user-select: auto !important;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(43, 145, 175); -webkit-user-select: auto !important;&quot;&gt;Caches&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0); -webkit-user-select: auto !important;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0); -webkit-user-select: auto !important;&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;pln&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0); -webkit-user-select: auto !important;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot; style=&quot;margin: 0px; padding: 0px; border: 0px; color: rgb(43, 145, 175); -webkit-user-select: auto !important;&quot;&gt;Restart&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-ERROR&amp;amp;SOLVE</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/36</guid>
      <comments>https://gun0912.tistory.com/36#entry36comment</comments>
      <pubDate>Thu, 22 Oct 2015 10:29:58 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]프리티어(Free Tier)사용량 확인하는 방법</title>
      <link>https://gun0912.tistory.com/35</link>
      <description>&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 400px; font-size: 9pt; line-height: 1.5;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2117994D56243FC424&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2117994D56243FC424&quot; width=&quot;400&quot; height=&quot;200&quot; filename=&quot;AWS.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;font-size: 9pt; line-height: 1.5;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;AWS를 사용하는 용도는 매우 다양하실겁니다.&lt;/p&gt;&lt;p&gt;실제 운영하는 서비스에 적용시키신분도 계실것이고, 테스트용도 혹은 작은 서비스로 Free tier 유저로서만 사용하고 싶으신분들 계실겁니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;AWS의 좋은점은 여러가지 다양하고 획기적인 서비스를 제공해주기도하지만 1년동안 주요 서비스들을 일정부분 무료로 사용할 수 있다는 것일겁니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://aws.amazon.com/ko/free/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;AWS Free Ti&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://aws.amazon.com/ko/free/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;er 혜택보기&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;저는 이런 아마존의 프로모션 전략이 참 마음에 듭니다.&lt;/p&gt;&lt;p&gt;초기사용자를 유입시키고 계속 자사서비스를 사용하게 만들어서 나중에는 추가결제를 하도록 유도하는 방식은 처음부터 결제를 요구하는 서비스보다 효과적으로 느껴집니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만 프리티어 유저로서 무료로 사용하고 싶으신분들이 계실겁니다.&lt;/p&gt;&lt;p&gt;일부 개발자들은 프리티어 이상의 기능을 사용해서 요금이 발생하여 지불하기도 합니다.&lt;/p&gt;&lt;p&gt;그래서 우리는 요금이 청구되면 바로 알려주어서 해당 기능들을 끄도록 할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://gun0912.tistory.com/11&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;예상 청구요금 알림 받는 방법&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하지만 그 이전에 현재 내가 프리티어 서비스 할당량중에 얼마나 쓰고있는지를 파악하고 예측하고 싶은 개발자들이 많을것 입니다.&lt;/p&gt;&lt;p&gt;AWS는 정말 대인배라고 생각됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;&lt;p&gt;Free Tier 사용량 확인하기&lt;/p&gt;&lt;/h1&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt; background-color: rgb(255, 255, 255);&quot;&gt;1. 내 계정에서 [Billing &amp;amp; Cost Management] 클릭&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 233px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2679CD4756243E932C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2679CD4756243E932C&quot; width=&quot;233&quot; height=&quot;209&quot; filename=&quot;Screenshot at 10월 19 09-50-09.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;2. [대시보드]메뉴에서 [사용량별 상위프리티어 서비스] - [모두보기] 클릭&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2504A54756243E9523&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2504A54756243E9523&quot; width=&quot;1000&quot; height=&quot;589&quot; filename=&quot;Screenshot at 10월 19 09-50-27.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(255, 0, 0);&quot;&gt;3. [사용량별 모든 프리 티어 서비스] 사용량 확인&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/257ED14756243E9627&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F257ED14756243E9627&quot; width=&quot;1000&quot; height=&quot;564&quot; filename=&quot;Screenshot at 10월 19 09-50-37.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용량을 확인하셔서 현재 내가 프리티어 사용량중 얼마나 사용하고있는지 확인해볼 수 있습니다.&lt;/p&gt;&lt;p&gt;또한, 이대로 계속 사용할경우 이번달 내가 할당량중 얼마나 사용하게될지도 예상할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;혹시 실수로 인스턴스를 terminate 시키지 않았거나 불필요하게 2개이상 서비스를 사용하고있었다면 이를 확인하고 불필요한 요금청구를 막을 수 있을것입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/AWS</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/35</guid>
      <comments>https://gun0912.tistory.com/35#entry35comment</comments>
      <pubDate>Mon, 19 Oct 2015 10:02:43 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]유용한 라이브러리 - Glide-Transformations(이미지 변형)</title>
      <link>https://gun0912.tistory.com/34</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;우리는 이미지를 사용하면서 여러종류로 이미지를 변형하고 싶을때가 있습니다.&lt;/p&gt;&lt;p&gt;- SNS에서 자주이용되는 원형의 프로필이미지&lt;/p&gt;&lt;p&gt;- 색깔을 넣은 컬러 필터 이미지&lt;/p&gt;&lt;p&gt;- 정사각형 모양의 이미지&lt;/p&gt;&lt;p&gt;- 블러로 느낌있는 배경의 이미지&lt;/p&gt;&lt;p&gt;- 등등등&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;제가 개발해서 운영중인 [셀폰]이라는 앱에도 여러가지형태로 이미지를 변형해서 쓰고있는데요.&lt;/p&gt;&lt;p&gt;그중에서 내 프로필화면에서 쓰인부분을 예시로 보여드리겠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;프로필이미지를 Circle로 만들어주었고&lt;/p&gt;&lt;p&gt;해당 프로필이미지를 블러로 처리하여 배경화면으로 만들어주는 작업을 해주고 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px; width: 300px; height: 533px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/25266A415620481428&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F25266A415620481428&quot; width=&quot;300&quot; height=&quot;533&quot; filename=&quot;Screenshot at 10월 16 09-41-31.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 300px; height: 533px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이러한것처럼 우리는&amp;nbsp;여러가지 방법으로 이미지를 변형할 수 있겠지만 이미지로딩 라이브러리를 사용하고 계신다면 해당 라이브러리에서 제공해주는 기능을 이용하면 좋습니다.&lt;/p&gt;&lt;p&gt;물론 해당 각 이미지로딩 라이브러리에 맞는 Transformation 라이브러리도 존재합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;Transform 적용 예시&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 328px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2560EC45561EF8542A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2560EC45561EF8542A&quot; width=&quot;328&quot; height=&quot;480&quot; filename=&quot;transform.gif&quot; filemime=&quot;image/gif&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;이 라이브러리는 Glide 이미지로딩 라이브러리를 사용하고계신분들에게 유용한 Transformation 라이브러리입니다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://gun0912.tistory.com/17&quot; target=&quot;_blank&quot; class=&quot;tx-link; line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;[안드로이드]유용한 라이브러리 - Glide (이미지 로딩 라이브러리)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br class=&quot;Apple-interchange-newline&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Picasoo나 Fresco 이미지로딩 라이브러리를 사용하신다면 아래 링크를 통해 Transformation을 이용하실 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/wasabeef/picasso-transformations&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;Picasso Transformations&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/wasabeef/fresco-processors&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;Fresco Processors&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h1&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;Glide Transformations&lt;/p&gt;&lt;/h1&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;https://github.com/wasabeef/glide-transformations&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;https://github.com/wasabeef/glide-transformations&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;1. gradle 추가&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;br /&gt;compile &lt;span style=&quot;color:#6a8759;&quot;&gt;'jp.wasabeef:glide-transformations:1.0.6@aar'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-size: 14pt;&quot;&gt;2. bitmapTransform()함수에 transformation 클래스 추가&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;pre style=&quot;font-family: Menlo; font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style=&quot;font-family: Menlo; font-size: 12pt;&quot;&gt;&lt;p&gt;Glide.with(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;).load(R.drawable.ic_selphone)&lt;br /&gt;        .bitmapTransform(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;CropCircleTransformation(context))&lt;br /&gt;        .into(iv_selphone)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;끝!&lt;/p&gt;&lt;p&gt;어때요? 참 쉽죠?&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;bitmapTransform()함수에는 파라미터로 1개의 transformation클래스만이 아니라 여러개의 클래스도 추가해줄수 있습니다.&lt;/b&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;p&gt;&lt;br /&gt;Glide.with(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;).load(R.drawable.ic_selphone)&lt;br /&gt;        .bitmapTransform(&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;BlurTransformation(context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;25&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;2&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;, new &lt;/span&gt;CropCircleTransformation(context))&lt;br /&gt;        .into(iv_selphone)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Transformation 라이브러리에서는 아래와같은 다양한 transformation을 제공합니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;Crop&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 9pt; line-height: 1.5;&quot;&gt;CropTransformation, CropCircleTransformation, CropSquareTransformation, RoundedCornersTransformation&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;Color&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 9pt; line-height: 1.5;&quot;&gt;ColorFilterTransformation, GrayscaleTransformation&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;Blur&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 9pt; line-height: 1.5;&quot;&gt;BlurTransformation&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;Mask&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 9pt; line-height: 1.5;&quot;&gt;MaskTransformation&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그외 GPUImage를 이용한 GPU Filter도 사용할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/34</guid>
      <comments>https://gun0912.tistory.com/34#entry34comment</comments>
      <pubDate>Fri, 16 Oct 2015 09:57:35 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드/Android]Debug/Release에 따라 다른 Google API KEY 넣기</title>
      <link>https://gun0912.tistory.com/33</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 600px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/244C004755E0290805&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F244C004755E0290805&quot; width=&quot;600&quot; height=&quot;238&quot; filename=&quot;google-android-maps.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;구글지도나 기타의 이유로 Google의 API를 사용하는 경우가 많이 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://console.developers.google.com&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;Google API console&lt;/span&gt;&lt;/a&gt;에서 사용하고자하는 기능을 활성화하고 API key를 받을 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;이경우 개발용 keystore와 배포용 keystore가 다르기때문에 각각 2개씩의 API KEY를 발급 받아야 합니다.&lt;/p&gt;
&lt;p&gt;보통 Manifest파일에 아래와같이 선언하실겁니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#808080;font-style:italic;&quot;&gt;&amp;lt;!-- 개발용 KEY --&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;meta-data&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;com.google.android.geo.API_KEY&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:value=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;개발용 KEY&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;font-style:italic;&quot;&gt;&amp;lt;!-- 배포용 KEY --&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;meta-data&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;com.google.android.geo.API_KEY&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:value=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;배포용 KEY&quot; &lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;개발중일경우는 배포용 KEY 코드부분을 주석하고 테스트를 하고 배포 할때는 개발용 KEY 코드부분을 주석처리하고 배포하는 식으로 운영합니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;그런데 만약 깜박하고 배포할때 배포용KEY가 아닌 개발용KEY로 배포해버린다면 실제 서비스에서는 지도나 기타 기능들을 사용할 수가 없습니다..&lt;/p&gt;
&lt;p&gt;개발/배포 버전에 따라 항상 주석을 만들었다가 없앴다가를 반복해주어야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 9pt; line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Android Studio에서 build.gradle의 buildTypes를 이용해 위와같은 번거로운 작업없이 개발/배포 버전에 맞게 API KEY를 설정하는 방법을 포스팅 해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;Debug / Release 모드에 따른 API KEY 설정방법&lt;/h1&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;1. build.gradle의 buildTypes에 아래와 같이 선언해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;p&gt;buildTypes {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;debug &lt;/span&gt;{&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#808080;&quot;&gt;// 개발용 KEY&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        resValue &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;string&quot;&lt;/span&gt;, &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;google_maps_api_key&quot;&lt;/span&gt;, &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;개발용 API KEY&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;release &lt;/span&gt;{&lt;br /&gt;        &lt;span style=&quot;color:#808080;&quot;&gt;// 배포용 KEY&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        resValue &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;string&quot;&lt;/span&gt;, &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;google_maps_api_key&quot;&lt;/span&gt;, &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;배포용 API KEY&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;2. AndroidManifest.xml 에서 아래와 같이 적어줍니다.&lt;/p&gt;
&lt;p&gt;google_maps_api_key라는 변수를 참조하게되는데 이는 debug/release 모드에따라서 각각 다른 key가 들어가게 될것입니다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:12.0pt;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&amp;lt;meta-data&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:name=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;com.google.android.maps.v2.API_KEY&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color:#bababa;&quot;&gt;:value=&lt;/span&gt;&lt;span style=&quot;color:#a5c261;&quot;&gt;&quot;@string/google_maps_api_key&quot;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#e8bf6a;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;1,2번의 방법으로 간단하게 설정해주면 Debug/Release버전에 따라 API KEY를 설정해주어야하는 번거로움을 피할 수 있습니다.&lt;/p&gt;
&lt;p&gt;이 외에도 개발/배포버전에 따라 각각 다른 설정값이 들어가야 하는경우는 build.gradle에 각각 값들을 지정해주면 Debug/Release 에 따라 다르게 값이 입력되도록 지정할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/33</guid>
      <comments>https://gun0912.tistory.com/33#entry33comment</comments>
      <pubDate>Fri, 28 Aug 2015 18:42:51 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드 스튜디오]로그캣(logcat) 색깔 바꾸기</title>
      <link>https://gun0912.tistory.com/31</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 450px; width: 450px; height: 296px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2624624A55D45D5805&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2624624A55D45D5805&quot; width=&quot;450&quot; height=&quot;296&quot; filename=&quot;android-logcat.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 450px; height: 296px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 어플을 개발하시면서 로그캣을 이용해 많은 로그를 확인해 보실겁니다.&lt;/p&gt;&lt;p&gt;기본적으로 안드로이드 스튜디오에서는 로그 레벨에 상관없이 모두 색이 일정합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;레벨별로 로그캣의 색깔을 다르게 표시하고싶은경우에 설정방법에 대해 포스팅해보겠습니다&lt;/p&gt;&lt;p&gt;(매우 간단해서 포스팅하기도 부끄러울정도..)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1. 설정화면에서 [Editor] -&amp;gt; [Colors&amp;amp;Fonts] -&amp;gt; [Android Logcat] 으로 이동합니다.&lt;/p&gt;&lt;p&gt;2. 각 로그레벨별로 지정하고 싶은 색상을 지정합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;로그레벨별 추천하는 색상&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Debug&lt;/b&gt; : 6897BB&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Info&lt;/b&gt; : 6A8759&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Warn&lt;/b&gt; : BBB529&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Error&lt;/b&gt; : FF6B68&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Assert&lt;/b&gt; : 9876AA&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 1000px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/255F005055D45E200A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F255F005055D45E200A&quot; width=&quot;1000&quot; height=&quot;651&quot; filename=&quot;Screenshot at 8월 19 19-44-36.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;아주 간단하지만 로그레벨별로 색상을 다르게줘서 한눈에 보기 쉽게 변경할 수 있습니다.&lt;span style=&quot;font-size: 9pt; line-height: 1.5;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Android-TIP (한글)</category>
      <author>박상권</author>
      <guid isPermaLink="true">https://gun0912.tistory.com/31</guid>
      <comments>https://gun0912.tistory.com/31#entry31comment</comments>
      <pubDate>Wed, 19 Aug 2015 19:48:50 +0900</pubDate>
    </item>
  </channel>
</rss>