<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://songmoolee.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://songmoolee.github.io/" rel="alternate" type="text/html" /><updated>2020-08-19T11:58:28+00:00</updated><id>https://songmoolee.github.io/feed.xml</id><title type="html">SongmooLee`s blog</title><subtitle>well</subtitle><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><entry><title type="html">스터디 20주차</title><link href="https://songmoolee.github.io/study/twentyfourth-post/" rel="alternate" type="text/html" title="스터디 20주차" /><published>2020-08-19T00:00:00+00:00</published><updated>2020-08-19T00:00:00+00:00</updated><id>https://songmoolee.github.io/study/twentyfourth-post</id><content type="html" xml:base="https://songmoolee.github.io/study/twentyfourth-post/">&lt;h3 id=&quot;deep-copy&quot;&gt;deep copy&lt;/h3&gt;

&lt;p&gt;객체는 따로 implements Cloneable 하고, clone 메소드를 오버라이드 하지 않는 이상 클론(deep copy)이 안돼는것(deep copy)을 확인하고 배움&lt;/p&gt;

&lt;p&gt;결국 클론이 쓰이는 객체마다 찾아가서 해당 클래스에 implements하고 override 함.&lt;/p&gt;

&lt;p&gt;Arrays.copyof로 객체를 복사해봤지만 shallow copy가 되는것을 객체의 toString()으로 확인함.&lt;/p&gt;

&lt;p&gt;근데 꼭 deepcopy가 필요하는가의 의문. 그 displayinfo안의 메소드들도 override되는지도 확인이 좀 필요할듯&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MTlfMTcw/MDAxNTk3ODM3MTYxNzc4.ijMzIClFl7pRO5bDWrfWykOy46Siw5oX4Cp3Xv-A7Psg.KBzikAdn3i66yIN9W9t4oYxEtd3rCaHlmYpypnWWvrsg.PNG.goonta96/image.png&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;객체를 deepcopy하는 방법&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MTlfMjQ3/MDAxNTk3ODM3MjIyOTcx.j3KvNWlxdKoo6P7j30aF9m-50hIC2EWnjujIRVMTlaYg.ILJCIpQmjRz0w_14PoSUFOajgz3qbSw0R9G73zb_B6cg.PNG.goonta96/image.png&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이렇게 객체를 복사하는 코드를 작성하니까 성능이 급나빠진다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MTlfNzYg/MDAxNTk3ODM3NDA4NjMw.LRROAYG6S3FtubsItrKIkeeSzzb9Y-uaU3OFZbKBmdog.HcUh0koArSqX5mbHyWZZyg7XJVH-SlaUWc9lbggVnKsg.PNG.goonta96/image.png&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MTlfMjQg/MDAxNTk3ODM3NTUyNDg0.fq4fZP-bRONlXbSmZUm3DPhQFvvqXxYequpECfsHg9Ig.07X6SwGln3ETO84fWusKpilsSa-ejpJB08zVH4gy6YIg.PNG.goonta96/image.png&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MTlfODkg/MDAxNTk3ODM4MTE2MTAw.lmcDLVLdncQxjmfLWuG6DZFGI08mbCENWtM3HLMNTNYg.BnSjU8JM40OMhZKG7RGZw-ivF7danar7JA8-Rqw_KXYg.PNG.goonta96/image.png&quot; alt=&quot;5&quot; /&gt;&lt;/p&gt;

&lt;p&gt;리포트를 작성중이다.
작성하고 있는 리포트 일부&lt;/p&gt;

&lt;p&gt;//string concat 쓰이는 부분 찾고 논문 쓰고 displayinfo 자체를 shallowcopy가 가능한지 확인하기, final class?&lt;/p&gt;</content><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><summary type="html">deep copy</summary></entry><entry><title type="html">스터디 19주차</title><link href="https://songmoolee.github.io/study/twentythird-post/" rel="alternate" type="text/html" title="스터디 19주차" /><published>2020-08-12T00:00:00+00:00</published><updated>2020-08-12T00:00:00+00:00</updated><id>https://songmoolee.github.io/study/twentythird-post</id><content type="html" xml:base="https://songmoolee.github.io/study/twentythird-post/">&lt;h3 id=&quot;concat&quot;&gt;concat()&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MTJfMTcw/MDAxNTk3MjMwOTk3Mzc2.2ts6MV6QX5Jb6wQb6czto3DgBcU6NCUMkPa8OUD9-KUg.V3HmZpKI9WAxmlHfxvd4BKMc0_2rUfvv3ouScuX10QYg.JPEG.goonta96/1.JPG&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;String 기본연산자 + 를 이용한 문자열 연결 필드들 발견&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MTJfMjYy/MDAxNTk3MjMwOTk3Mzc2.GwDheisQefVOF1zUBfbfaZHSGF2JTrlJOeRWCNxtj9gg.24uAd6RKHfUQ_7Fk3EYUPT8Stb921DkibImz-lqLJ7kg.JPEG.goonta96/0.JPG&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;임포트 되는 필드들의 위치를 찾아 복붙을 했다&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MTJfNTcg/MDAxNTk3MjMwOTk3NDEx.fVx-2zx2L0P0S02zcpvQEBdh8MAxBlwmWBmEMXkX7Wsg.5SdSMZx9rEl8cmzarBTNcHnJdnICB2EyVON0KcT4H5Eg.JPEG.goonta96/2.JPG&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;String 기본연산자 +를 쓴 경우를 백만번씩 열번 돌렸을 때 걸린 시간&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MTJfMTQ4/MDAxNTk3MjMwOTk3NDIx.LaCcg5pgfku-5fH5gcqoOTft2wzQYO5ywdFmkJUjYd4g.wXHqKIDELy4F98uplXZzcuxK40KuDUqOcbvPvG5Rl1cg.JPEG.goonta96/3.JPG&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;StringBuilder나 StringBuffer 메소드는 main메소드안에 없어서 사용불가&lt;/p&gt;

&lt;p&gt;concat메소드를 이용하여 바꾼 후 백만번씩 열번 돌렸을 때 시간&lt;/p&gt;

&lt;p&gt;몇번을 돌려도 concat이 더 좋게 나온다.&lt;/p&gt;

&lt;p&gt;다른 파일에 String 기본연산자인 +가 많이 존재하는 곳 찾아보기&lt;/p&gt;</content><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><summary type="html">concat()</summary></entry><entry><title type="html">스터디 18주차</title><link href="https://songmoolee.github.io/study/twentysecond-post/" rel="alternate" type="text/html" title="스터디 18주차" /><published>2020-08-05T00:00:00+00:00</published><updated>2020-08-05T00:00:00+00:00</updated><id>https://songmoolee.github.io/study/twentysecond-post</id><content type="html" xml:base="https://songmoolee.github.io/study/twentysecond-post/">&lt;h3 id=&quot;copyfrom&quot;&gt;copyFrom&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MDVfMTkg/MDAxNTk2NjI3ODc3MzAw.b2_Vdu_t7j2VinLWtsi0-04WPqNts8O2uEgMlsRF8-Eg.I-Q1aetBvPBzDH_Z-k3o7jybwUPO1oIs_D3_MRu-Ai8g.JPEG.goonta96/01.JPG&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;수정된 copyFrom 메소드, implements Cloneable 포함&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MDVfNTcg/MDAxNTk2NjI3ODc3MzAx.8q7xLk5s77iovc_VwvmjbeDAV16gUhOS5Mi8h4Qlx8og.mnE4XmCY_7I4rlTnrSoKRXXx7BVOH45LVWF7u6ox7HMg.JPEG.goonta96/02.JPG&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;수정한 copyFrom이 쓰이는 다른 클래스의 수정 예시 1&lt;/p&gt;

&lt;h3 id=&quot;math&quot;&gt;Math&lt;/h3&gt;

&lt;p&gt;Math가 많이 쓰이는 파일 중 호출이 자주되는 메소드를 찾아서 Math.max나 min대신 삼항연산자와 혼합해서 쓴것으로 구현하여 시간 측정을 함&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MDVfMzAw/MDAxNTk2NjI3ODc3MzIz.Y5jmV0DymOGEup9lRbwMEwOYhwv5-1XeCfsZJGAOMlsg.GvM4dI6X_e2rIca0-TOXWcH-oc131L5fiCi20zkUhwUg.JPEG.goonta96/11.JPG&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Math만&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MDVfNDQg/MDAxNTk2NjI3ODc3MzQz.PSAW4Gv5Jstu28SsUL6mxQthS8kX5Ko5ZgVd8CucNdcg.T8Uyu3esFFIxXkfIpg-OXshgNtQ6XsvkD6DvA2EsKF4g.JPEG.goonta96/12.JPG&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;삼항연산자만&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MDVfMzAw/MDAxNTk2NjI3ODc3MzE4._S6mj-AE6sB8oqq3JN54k6vQ7xwYTlgC5WPxv3-KCbAg.I5G4ZORDYZcTR9uUBbFleRqXbFkNQLZyeYaoP6h21tMg.JPEG.goonta96/13.JPG&quot; alt=&quot;5&quot; /&gt;&lt;/p&gt;

&lt;p&gt;혼합 후 사용&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MDVfMTAy/MDAxNTk2NjI3ODc3NTI0.k7cv7JKtP2TDHUcEK8XkZ1hQrOAR1zbw9xKCOgEukccg.CnEMB9Y7Eipms8qjzXZyOtog_d1A8cOaWi3YFncuqeQg.JPEG.goonta96/14.JPG&quot; alt=&quot;6&quot; /&gt;&lt;/p&gt;

&lt;p&gt;천만번씩 10세트씩 돌려봤다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MDVfMTI4/MDAxNTk2NjI3ODc3MjU4.k3IVsTkxYqS476dwXErHemprERLlBCHTux4dfwTDjF0g.t6u9OkIOTDMYRUwtSFDcFBJMKuIMr47rqmYxNLcLGZAg.JPEG.goonta96/10.JPG&quot; alt=&quot;7&quot; /&gt;&lt;/p&gt;

&lt;p&gt;몇번을 해도 Math클래스만 쓴것이 제일 빠름…&lt;/p&gt;

&lt;h3 id=&quot;많은-import&quot;&gt;많은 import&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MDVfMTE0/MDAxNTk2NjI3ODc3NTc2.3__G3DS_eVoRxOU8aJUPL_vlmsGvCdpsEVUPw32lmnQg.oVPf8uFwzU1rdrxm_2rg3ogKFCo-IxBecMuRdS1Ex7Eg.JPEG.goonta96/20.JPG&quot; alt=&quot;8&quot; /&gt;&lt;/p&gt;

&lt;p&gt;대부분 boolean이며 대부분은 WindowManagerService.java에서 많이 import 되어 쓰인다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA4MDVfMjE1/MDAxNTk2NjI3ODc3Njcx.ORuQQEh-AtGDwnsvNTXaok2DiM549JpC_wOl-Ug7axkg.ynhuGcCdX9HqCjuFDiNKEhiyUxfPB48xn3Po7YN3lLMg.JPEG.goonta96/21.JPG&quot; alt=&quot;9&quot; /&gt;&lt;/p&gt;

&lt;p&gt;몇 개의 변수를 제외하고 몇번 안쓰이는데 이런것들을 false로 그대로 다 바꿔쓴다면 성능 향상이 있을까?&lt;/p&gt;</content><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><summary type="html">copyFrom</summary></entry><entry><title type="html">스터디 17주차</title><link href="https://songmoolee.github.io/study/twentyoneth-post/" rel="alternate" type="text/html" title="스터디 17주차" /><published>2020-07-29T00:00:00+00:00</published><updated>2020-07-29T00:00:00+00:00</updated><id>https://songmoolee.github.io/study/twentyoneth-post</id><content type="html" xml:base="https://songmoolee.github.io/study/twentyoneth-post/">&lt;h3 id=&quot;temp&quot;&gt;temp&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjlfODIg/MDAxNTk2MDIzMDc0NTA0.l-YH0WUGaoHnRg9FkDjKKUirglt6TN6_YTxtB6YtrJQg.QsZeEE2ZJDdmAdsTp6DoF4urORBZp5iN7os2lcv39ncg.JPEG.goonta96/3.JPG&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjlfMTcy/MDAxNTk2MDIzMTM4MjUy.PIOWrp44AsKz9k37o4kJguX1I-T_IstA3lbtyVqTvAQg.HZetDc6xBw9tY3HzHXJZ2s5qUW0V9LF3I-R3KGzWL58g.JPEG.goonta96/0.JPG&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;다른 객체들도 포함시킨 결과이다, 약간의 성능개선이다…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjlfODgg/MDAxNTk2MDIzMDc0NDc1.OsQHB_5DaaXSXZ5UPzIynIrjCHVq_-pLDzNxYBZM7W4g.LSg4MhsEqpYnYAZ8F6kR9MJhLA0CxWy9BrE2K744Jzwg.JPEG.goonta96/2.JPG&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Displayinfo.java에서 생성자 중 하나밖에 호출되지않는 생성자를 주석처리하고 호출되는곳에서 따로 처리하도록함&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjlfMjA2/MDAxNTk2MDIzMDc0NTEz.TqFZe1DhSyop1ThUkxI8pUfNkZsP37tVRDZ7Ui5Irv8g.ijNsS_c3DCLuKvPn3ikNtRl6GkNFfQ-4X-TmykTNePEg.JPEG.goonta96/4.JPG&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;호출되는 파일들을 찾아, 수정한후, 주석처리로 위치를 적었다.
위에 탭에 있는 파일들이 호출되는 파일들.&lt;/p&gt;

&lt;p&gt;김재현 팀원분께 전송해서 빌드를 해볼 예정이다.&lt;/p&gt;</content><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><summary type="html">temp</summary></entry><entry><title type="html">스터디 16주차</title><link href="https://songmoolee.github.io/study/twentieth-post/" rel="alternate" type="text/html" title="스터디 16주차" /><published>2020-07-21T00:00:00+00:00</published><updated>2020-07-21T00:00:00+00:00</updated><id>https://songmoolee.github.io/study/twentieth-post</id><content type="html" xml:base="https://songmoolee.github.io/study/twentieth-post/">&lt;h3 id=&quot;temp&quot;&gt;temp&lt;/h3&gt;

&lt;p&gt;전의 displayinfo.java &lt;a href=&quot;https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/DisplayInfo.java&quot;&gt;링크&lt;/a&gt; 에서 발견했던 boolean equals메소드와 copyfrom 메소드를 수정할 예정&lt;/p&gt;

&lt;h4 id=&quot;equals&quot;&gt;equals&lt;/h4&gt;

&lt;p&gt;먼저 equals 메소드는 자주 틀릴 수 있는 필드나, 자료형의 비교 빠르기 등을 개선하면 될듯함.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/23559526/performance-many-if-statements-vs-long-logical-expression&quot;&gt;참조링크&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/34428952/if-with-multiple-conditions-evaluation-in-java/34429054&quot;&gt;참조링크2&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;copyfrom&quot;&gt;copyfrom&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjFfMjky/MDAxNTk1MzMyNDMwNDA1.6bTIRYNBJrxDLz24V7uQOcfzQ5t0gy_-p62UvfMUsWgg.AloQPVglG3kFBmzyVLUBBDn_jQi5hBEuFzleKJG_VDQg.JPEG.goonta96/3.JPG&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjFfMjky/MDAxNTk1MzMyNDMwNDQ0.--Zsp2AwwyYKtfYDuMbc5lJU9dXvNvC9u6pGvYvEAfMg.5_mE6Hv5SWAXDBeAWlrPssabfAcWlKk_4Pu9lAqogPMg.JPEG.goonta96/1.JPG&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjFfMjEw/MDAxNTk1MzMyNDMwNDA1.1eaewk3giSwU8XH1yeRvJTBr2szzJowLvKcrR65niB8g.96W_x2qqT-i-_VPC4Jeg2vuS1g8G6fkdOpQM2Z62QQMg.JPEG.goonta96/2.JPG&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;호출되는 형식을 확인&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjJfMjQ1/MDAxNTk1NDE0OTcyMjA2.wBUwsgcFL3QaWFd5kDpQPpx3f_wUzpPL3tEBQD4LCmEg.wgEunj8fHDWMAALZuyNzLRmeu_Kw8hPDComUVqukvxog.JPEG.goonta96/%EC%97%AC%EB%9F%AC%ED%98%B8%EC%B6%9C%ED%99%95%EC%9D%B8.JPG&quot; alt=&quot;35&quot; /&gt;&lt;/p&gt;

&lt;p&gt;호출되는 곳 확인가능&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjFfNzYg/MDAxNTk1MzMyNDMwNTIw.phowVFnxxo6_a7Bv-3HZPwv4gKLwX9thck5S5wMXe3Ig.-rYkDdg7L0A6uFkXWieJeZfEgSU1PpL9DkCGqsMwHPIg.JPEG.goonta96/11.JPG&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;diplayinfo.java의 필드들 만을 그대로 (copyfrom 메소드에 있는 변수들 모두) 옮겨적음
Display 관련 변수는 일단 주석처리 했다.&lt;/p&gt;

&lt;p&gt;이후에 aosp의 displayinfo.java에 있는 메소드들을 똑같이 복사하여, 최대한 비슷하게 구현하도록 노력하기 위해, (그래도 주석처리된게 몇 개 있다) 성능비교를 시작함&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjFfMjQg/MDAxNTk1MzMyNDMwNTIw.DeIj6pgdLjhoJkwkqoATHvIN5UfhR7IbgkoSRy2LlA8g.mMlb5yKaTCp2m9MHSiQn2dFOyOCv1NOTLzf4Z1H3oqIg.JPEG.goonta96/22.JPG&quot; alt=&quot;5&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjFfMTM5/MDAxNTk1MzMyNTU0OTQz.TFCmdOTWqzbqcdROjX7V5XKwhmeoXT1i_km8P9znzq8g.h1--Z4HpuabUlgqE5yOMbyHWnXs71ETo9YskEBzIXHog.JPEG.goonta96/33.JPG&quot; alt=&quot;6&quot; /&gt;&lt;/p&gt;

&lt;p&gt;clone()과 copyfrom()을 비교하기 위한 테스트 클래스이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjFfMTI4/MDAxNTk1MzMyODE0ODI5.3zu75v2tsJ-JZnGrxRSDE2RejV6ERytaPAY57M6aY4wg.Qtfs_OO0g4ddBYd6UiSFkJibx-IDk8aUbxYBd_lwUnog.JPEG.goonta96/44.JPG&quot; alt=&quot;7&quot; /&gt;&lt;/p&gt;

&lt;p&gt;각 clonetest 객체 t1, t2의 변수들에 임의로 대입시킴.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjFfMjE4/MDAxNTk1MzMyOTM3ODgx.Po5-2nKg84djOD0IrzXKPjrf_PcSbvTlGY6ewOO8VFMg.gIgQSUIo4qf1PlAJwRnO0E7fGzUlvzw0YfULB_FfGUUg.JPEG.goonta96/55.JPG&quot; alt=&quot;8&quot; /&gt;&lt;/p&gt;

&lt;p&gt;시간 비교를 했다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MjJfNjYg/MDAxNTk1NDE1MzQ2NTE3.k_CjBsD8D0KPClKERK0eSJsk_9Q_PCg9LW12NEIpRAMg.83QLmgwkfPpoqi7kcq9T5pIM3mQFBfSUh6DC7ErCOk4g.JPEG.goonta96/15%EB%B2%88%EC%A7%84%ED%96%89.JPG&quot; alt=&quot;9&quot; /&gt;&lt;/p&gt;

&lt;p&gt;15번실행을 하였다&lt;/p&gt;

&lt;p&gt;clone메소드가 성능이 우세하게 나왔다
문제는 실상황 아니면 주석처리를 한 메소드나 필드가 영향을 미칠 수 있다
빌드를 해보면 결과가 달라지나?&lt;/p&gt;

&lt;p&gt;나중에 wm 서버쪽에서 다른 성능의심구문을 찾아보자.&lt;/p&gt;</content><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><summary type="html">temp</summary></entry><entry><title type="html">스터디 15주차</title><link href="https://songmoolee.github.io/study/nineteenth-post/" rel="alternate" type="text/html" title="스터디 15주차" /><published>2020-07-15T00:00:00+00:00</published><updated>2020-07-15T00:00:00+00:00</updated><id>https://songmoolee.github.io/study/nineteenth-post</id><content type="html" xml:base="https://songmoolee.github.io/study/nineteenth-post/">&lt;h3 id=&quot;temp&quot;&gt;temp&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MTVfNDcg/MDAxNTk0ODA1NjYwMTUy.IFZjm8pbcyVEeE0KJM-2D2YxxyQ3Rghj14MD8x18kI8g.SEB_y70deJ9kLJ3yYBtlUkVPNLeyDs5Wc8HO8Pcmzfgg.PNG.goonta96/image.png&quot; alt=&quot;그림1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MTVfOSAg/MDAxNTk0ODA1Njk3NjY5.4jUqbDrk-XLYBm-KRCRxT_QxxL3jn4e3Cncb3OxLbtUg.2kuu36_f_goEgxYVXCgEwohEWdivHoJnE-TbWhpMr5Eg.PNG.goonta96/image.png&quot; alt=&quot;그림2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MTVfODcg/MDAxNTk0ODA1NzMyOTM5._zPMnbArsAX8kMsKRlRNVCEyDbRolqtunm4swSgg1UIg.dsa0US_OaOBkNbp4rqm3pLuSZEqPV4xQbuowTsKlAB8g.PNG.goonta96/image.png&quot; alt=&quot;그림3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MTVfMjk5/MDAxNTk0ODA1NzcxMjQ2.AtZSuYNtJH8wsaFipOWvEdTtCZfLkjq7CSxT_p5KJ58g.6IDDw3hus-wFcG5pEooipn0EAWNbtRSlULMCpbzZ5Rog.PNG.goonta96/image.png&quot; alt=&quot;그림4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MTVfMTA2/MDAxNTk0ODA2NDIxMDkw.1SSxAGXl9ydsJ3MrgrJ1dV_rQPKpXlb-3g4TxgzGxb0g.-zS03x3EaqURrTwDDQJbWUA-gbs8mzx1NUpc2si68x8g.PNG.goonta96/image.png&quot; alt=&quot;그림5&quot; /&gt;&lt;/p&gt;

&lt;p&gt;더 안좋은 결과가 나온것 같다.. if문을 건드려야 겠다.&lt;/p&gt;

&lt;p&gt;기존에 찾았던 다른 if문 같은 것들을 개선할 필요가 있을것 같다.&lt;/p&gt;

&lt;p&gt;javap -c 로 바이트코드를 봤지만 무슨 방법으로 봐야될지를 모르겠다. 의논필요&lt;/p&gt;

&lt;h4 id=&quot;기존에-찾았던것들&quot;&gt;기존에 찾았던것들&lt;/h4&gt;

&lt;p&gt;frameworks/base/core/java/android/view/WindowManager.java 의 2895 줄 –&amp;gt; if else 구문은 없으나 한번 비교해볼 필요성은 있을듯, 호출횟수 보기&lt;/p&gt;

&lt;p&gt;frameworks/base/core/java/android/view/Window.java의 781줄 –&amp;gt; if else는 많으나 비교적 조금 짧음, 직접 짜서 분석해볼 필요성은 있을듯, 호출횟수 보기&lt;/p&gt;

&lt;p&gt;아니면 다른 팀원들이 지적했던 곳 다시 확인하기. ex) LayoutParams&lt;/p&gt;

&lt;p&gt;이건 무슨 코드인가&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MTVfMjgg/MDAxNTk0ODEzMDk2NjM5.u-hkRZ7Ztd8dXn-qFltxrSyNNYtkPAsw2wZn9XG3tk4g.WOupoehcCMy6fAazwGjbUBFrEn9ZFKr6jqMkgn79Xs8g.PNG.goonta96/image.png&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MTVfMTQx/MDAxNTk0ODEzMTM5MDgw.s_tjsB0pY-GTw6HQWcW1feUKlNVTh0U59Pwq3nL4yvUg.eAEq8GqguMbzEVZmUTK8fUWjo6T5RSmPYFJPVyNa3EIg.PNG.goonta96/image.png&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;</content><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><summary type="html">temp</summary></entry><entry><title type="html">스터디 14주차</title><link href="https://songmoolee.github.io/study/eighteenth-post/" rel="alternate" type="text/html" title="스터디 14주차" /><published>2020-07-07T00:00:00+00:00</published><updated>2020-07-07T00:00:00+00:00</updated><id>https://songmoolee.github.io/study/eighteenth-post</id><content type="html" xml:base="https://songmoolee.github.io/study/eighteenth-post/">&lt;h3 id=&quot;temp&quot;&gt;temp&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://android.googlesource.com/platform/frameworks/base/+/refs/heads/oreo-security-release/core/java/android/view/View.java&quot;&gt;오레오 뷰링크&lt;/a&gt;
4725번째 줄&lt;/p&gt;

&lt;h3 id=&quot;진행상황&quot;&gt;진행상황&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MDhfMjI3/MDAxNTk0MjAyNzU0MjE3.grLdYFBweVW8bmW_pfG4rLF6L7Oloqzv9ObEi2_TTAMg.532BIBJ0fi0Qzzem4tTyd8WDbWgMr2z-G6BNeXQPOWEg.PNG.goonta96/11.PNG&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MDhfMjE2/MDAxNTk0MjAyOTIxMzM4.gKnSy4Rokfl6OavFlnN9ctyRcH3mEEEcG-u0GcLHuCEg.UxgZ8seZaO9KAjfyjXIwhRrrYyvAFTNe7ptLisxbXewg.PNG.goonta96/13.PNG&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;성능개선이 가능해보이는 코드 (전 게시물 마지막의 뷰링크)를 복사해서 작동을 하도록 구현을 함. 총 86개의 case문과 많은 변수들을 확인 가능하다. 실행시간을 확인 가능.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MDhfNDIg/MDAxNTk0MjAyODU4NDY3.JTNpr7T1sBvoHf7avYjqql979onuafct70YsZoWd2J4g.d_bdEYndai07rv1R5IxfpmbmRll5sUc5Lz4QSIeg3kAg.PNG.goonta96/12.PNG&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;기존 코드와 비슷하게 다른 패키지에서 상수를 가져오록 했음&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogfiles.pstatic.net/MjAyMDA3MDhfMTMy/MDAxNTk0MjAzMTMxOTc3.WQwt3GJoa-PZGHDI8JJ77P-1KJ24RcPEMBIwKjVYCvgg.iWiz2DO3GulJDxVe7tFGj1FvVbdpTgbtUy5HD2py5sMg.PNG.goonta96/14.PNG&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;문제는 Enummap구현이 이런 많은 switchcase문에 적용여부의 적합성 여부를 잘 모르겠다.
Enummap의 예시들을 보니 String key들에게 다른 특정 value들을 부여하는 식으로 쓰임.
애초의 기존코드는 integer로 switchcase문이 구성되있고 다른 성능향상 여부가 있는지를 모르겠다.&lt;/p&gt;</content><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><summary type="html">temp</summary></entry><entry><title type="html">스터디 13주차</title><link href="https://songmoolee.github.io/study/seventeenth-post/" rel="alternate" type="text/html" title="스터디 13주차" /><published>2020-07-02T00:00:00+00:00</published><updated>2020-07-02T00:00:00+00:00</updated><id>https://songmoolee.github.io/study/seventeenth-post</id><content type="html" xml:base="https://songmoolee.github.io/study/seventeenth-post/">&lt;h3 id=&quot;temp&quot;&gt;temp&lt;/h3&gt;

&lt;h4 id=&quot;1번째&quot;&gt;1번째&lt;/h4&gt;

&lt;p&gt;frameworks/base/core/java/android/view/WindowManager.java 의 2895 줄&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/WindowManager.java;l=78?q=windowmanager&amp;amp;sq=&quot;&gt;링크&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public final int copyFrom(LayoutParams o) {
            int changes = 0;

            if (width != o.width) {
                width = o.width;
                changes |= LAYOUT_CHANGED;
            }
            if (height != o.height) {
                height = o.height;
                changes |= LAYOUT_CHANGED;
            }
            if (x != o.x) {
                x = o.x;
                changes |= LAYOUT_CHANGED;
            }
            if (y != o.y) {
                y = o.y;
                changes |= LAYOUT_CHANGED;
            }
            if (horizontalWeight != o.horizontalWeight) {
                horizontalWeight = o.horizontalWeight;
                changes |= LAYOUT_CHANGED;
            }
            if (verticalWeight != o.verticalWeight) {
                verticalWeight = o.verticalWeight;
                changes |= LAYOUT_CHANGED;
            }
            if (horizontalMargin != o.horizontalMargin) {
                horizontalMargin = o.horizontalMargin;
                changes |= LAYOUT_CHANGED;
            }
            if (verticalMargin != o.verticalMargin) {
                verticalMargin = o.verticalMargin;
                changes |= LAYOUT_CHANGED;
            }
            if (type != o.type) {
                type = o.type;
                changes |= TYPE_CHANGED;
            }
            if (flags != o.flags) {
                final int diff = flags ^ o.flags;
                if ((diff &amp;amp; (FLAG_TRANSLUCENT_STATUS | FLAG_TRANSLUCENT_NAVIGATION)) != 0) {
                    changes |= TRANSLUCENT_FLAGS_CHANGED;
                }
                flags = o.flags;
                changes |= FLAGS_CHANGED;
            }
            if (privateFlags != o.privateFlags) {
                privateFlags = o.privateFlags;
                changes |= PRIVATE_FLAGS_CHANGED;
            }
            if (softInputMode != o.softInputMode) {
                softInputMode = o.softInputMode;
                changes |= SOFT_INPUT_MODE_CHANGED;
            }
            if (layoutInDisplayCutoutMode != o.layoutInDisplayCutoutMode) {
                layoutInDisplayCutoutMode = o.layoutInDisplayCutoutMode;
                changes |= LAYOUT_CHANGED;
            }
            if (gravity != o.gravity) {
                gravity = o.gravity;
                changes |= LAYOUT_CHANGED;
            }
            if (format != o.format) {
                format = o.format;
                changes |= FORMAT_CHANGED;
            }
            if (windowAnimations != o.windowAnimations) {
                windowAnimations = o.windowAnimations;
                changes |= ANIMATION_CHANGED;
            }
            if (token == null) {
                // NOTE: token only copied if the recipient doesn't
                // already have one.
                token = o.token;
            }
            if (packageName == null) {
                // NOTE: packageName only copied if the recipient doesn't
                // already have one.
                packageName = o.packageName;
            }
            if (!Objects.equals(mTitle, o.mTitle) &amp;amp;&amp;amp; o.mTitle != null) {
                // NOTE: mTitle only copied if the originator set one.
                mTitle = o.mTitle;
                changes |= TITLE_CHANGED;
            }
            if (alpha != o.alpha) {
                alpha = o.alpha;
                changes |= ALPHA_CHANGED;
            }
            if (dimAmount != o.dimAmount) {
                dimAmount = o.dimAmount;
                changes |= DIM_AMOUNT_CHANGED;
            }
            if (screenBrightness != o.screenBrightness) {
                screenBrightness = o.screenBrightness;
                changes |= SCREEN_BRIGHTNESS_CHANGED;
            }
            if (buttonBrightness != o.buttonBrightness) {
                buttonBrightness = o.buttonBrightness;
                changes |= BUTTON_BRIGHTNESS_CHANGED;
            }
            if (rotationAnimation != o.rotationAnimation) {
                rotationAnimation = o.rotationAnimation;
                changes |= ROTATION_ANIMATION_CHANGED;
            }

            if (screenOrientation != o.screenOrientation) {
                screenOrientation = o.screenOrientation;
                changes |= SCREEN_ORIENTATION_CHANGED;
            }

            if (preferredRefreshRate != o.preferredRefreshRate) {
                preferredRefreshRate = o.preferredRefreshRate;
                changes |= PREFERRED_REFRESH_RATE_CHANGED;
            }

            if (preferredDisplayModeId != o.preferredDisplayModeId) {
                preferredDisplayModeId = o.preferredDisplayModeId;
                changes |= PREFERRED_DISPLAY_MODE_ID;
            }

            if (systemUiVisibility != o.systemUiVisibility
                    || subtreeSystemUiVisibility != o.subtreeSystemUiVisibility) {
                systemUiVisibility = o.systemUiVisibility;
                subtreeSystemUiVisibility = o.subtreeSystemUiVisibility;
                changes |= SYSTEM_UI_VISIBILITY_CHANGED;
            }

            if (hasSystemUiListeners != o.hasSystemUiListeners) {
                hasSystemUiListeners = o.hasSystemUiListeners;
                changes |= SYSTEM_UI_LISTENER_CHANGED;
            }

            if (inputFeatures != o.inputFeatures) {
                inputFeatures = o.inputFeatures;
                changes |= INPUT_FEATURES_CHANGED;
            }

            if (userActivityTimeout != o.userActivityTimeout) {
                userActivityTimeout = o.userActivityTimeout;
                changes |= USER_ACTIVITY_TIMEOUT_CHANGED;
            }

            if (!surfaceInsets.equals(o.surfaceInsets)) {
                surfaceInsets.set(o.surfaceInsets);
                changes |= SURFACE_INSETS_CHANGED;
            }

            if (hasManualSurfaceInsets != o.hasManualSurfaceInsets) {
                hasManualSurfaceInsets = o.hasManualSurfaceInsets;
                changes |= SURFACE_INSETS_CHANGED;
            }

            if (preservePreviousSurfaceInsets != o.preservePreviousSurfaceInsets) {
                preservePreviousSurfaceInsets = o.preservePreviousSurfaceInsets;
                changes |= SURFACE_INSETS_CHANGED;
            }

            if (needsMenuKey != o.needsMenuKey) {
                needsMenuKey = o.needsMenuKey;
                changes |= NEEDS_MENU_KEY_CHANGED;
            }

            if (accessibilityIdOfAnchor != o.accessibilityIdOfAnchor) {
                accessibilityIdOfAnchor = o.accessibilityIdOfAnchor;
                changes |= ACCESSIBILITY_ANCHOR_CHANGED;
            }

            if (!Objects.equals(accessibilityTitle, o.accessibilityTitle)
                    &amp;amp;&amp;amp; o.accessibilityTitle != null) {
                // NOTE: accessibilityTitle only copied if the originator set one.
                accessibilityTitle = o.accessibilityTitle;
                changes |= ACCESSIBILITY_TITLE_CHANGED;
            }

            if (mColorMode != o.mColorMode) {
                mColorMode = o.mColorMode;
                changes |= COLOR_MODE_CHANGED;
            }

            // This can't change, it's only set at window creation time.
            hideTimeoutMilliseconds = o.hideTimeoutMilliseconds;

            return changes;
        }

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;2번째&quot;&gt;2번째&lt;/h4&gt;

&lt;p&gt;frameworks/base/core/java/android/view/WindowManager.java의 3115 줄&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/WindowManager.java;l=78?q=windowmanager&amp;amp;sq=&quot;&gt;링크&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public String toString(String prefix) {
            StringBuilder sb = new StringBuilder(256);
            sb.append('{');
            dumpDimensions(sb);
            if (horizontalMargin != 0) {
                sb.append(&quot; hm=&quot;);
                sb.append(horizontalMargin);
            }
            if (verticalMargin != 0) {
                sb.append(&quot; vm=&quot;);
                sb.append(verticalMargin);
            }
            if (gravity != 0) {
                sb.append(&quot; gr=&quot;);
                sb.append(Gravity.toString(gravity));
            }
            if (softInputMode != 0) {
                sb.append(&quot; sim={&quot;);
                sb.append(softInputModeToString(softInputMode));
                sb.append('}');
            }
            if (layoutInDisplayCutoutMode != 0) {
                sb.append(&quot; layoutInDisplayCutoutMode=&quot;);
                sb.append(layoutInDisplayCutoutModeToString(layoutInDisplayCutoutMode));
            }
            sb.append(&quot; ty=&quot;);
            sb.append(ViewDebug.intToString(LayoutParams.class, &quot;type&quot;, type));
            if (format != PixelFormat.OPAQUE) {
                sb.append(&quot; fmt=&quot;);
                sb.append(PixelFormat.formatToString(format));
            }
            if (windowAnimations != 0) {
                sb.append(&quot; wanim=0x&quot;);
                sb.append(Integer.toHexString(windowAnimations));
            }
            if (screenOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
                sb.append(&quot; or=&quot;);
                sb.append(ActivityInfo.screenOrientationToString(screenOrientation));
            }
            if (alpha != 1.0f) {
                sb.append(&quot; alpha=&quot;);
                sb.append(alpha);
            }
            if (screenBrightness != BRIGHTNESS_OVERRIDE_NONE) {
                sb.append(&quot; sbrt=&quot;);
                sb.append(screenBrightness);
            }
            if (buttonBrightness != BRIGHTNESS_OVERRIDE_NONE) {
                sb.append(&quot; bbrt=&quot;);
                sb.append(buttonBrightness);
            }
            if (rotationAnimation != ROTATION_ANIMATION_ROTATE) {
                sb.append(&quot; rotAnim=&quot;);
                sb.append(rotationAnimationToString(rotationAnimation));
            }
            if (preferredRefreshRate != 0) {
                sb.append(&quot; preferredRefreshRate=&quot;);
                sb.append(preferredRefreshRate);
            }
            if (preferredDisplayModeId != 0) {
                sb.append(&quot; preferredDisplayMode=&quot;);
                sb.append(preferredDisplayModeId);
            }
            if (hasSystemUiListeners) {
                sb.append(&quot; sysuil=&quot;);
                sb.append(hasSystemUiListeners);
            }
            if (inputFeatures != 0) {
                sb.append(&quot; if=&quot;).append(inputFeatureToString(inputFeatures));
            }
            if (userActivityTimeout &amp;gt;= 0) {
                sb.append(&quot; userActivityTimeout=&quot;).append(userActivityTimeout);
            }
            if (surfaceInsets.left != 0 || surfaceInsets.top != 0 || surfaceInsets.right != 0 ||
                    surfaceInsets.bottom != 0 || hasManualSurfaceInsets
                    || !preservePreviousSurfaceInsets) {
                sb.append(&quot; surfaceInsets=&quot;).append(surfaceInsets);
                if (hasManualSurfaceInsets) {
                    sb.append(&quot; (manual)&quot;);
                }
                if (!preservePreviousSurfaceInsets) {
                    sb.append(&quot; (!preservePreviousSurfaceInsets)&quot;);
                }
            }
            if (needsMenuKey == NEEDS_MENU_SET_TRUE) {
                sb.append(&quot; needsMenuKey&quot;);
            }
            if (mColorMode != COLOR_MODE_DEFAULT) {
                sb.append(&quot; colorMode=&quot;).append(ActivityInfo.colorModeToString(mColorMode));
            }
            sb.append(System.lineSeparator());
            sb.append(prefix).append(&quot;  fl=&quot;).append(
                    ViewDebug.flagsToString(LayoutParams.class, &quot;flags&quot;, flags));
            if (privateFlags != 0) {
                sb.append(System.lineSeparator());
                sb.append(prefix).append(&quot;  pfl=&quot;).append(ViewDebug.flagsToString(
                        LayoutParams.class, &quot;privateFlags&quot;, privateFlags));
            }
            if (systemUiVisibility != 0) {
                sb.append(System.lineSeparator());
                sb.append(prefix).append(&quot;  sysui=&quot;).append(ViewDebug.flagsToString(
                        View.class, &quot;mSystemUiVisibility&quot;, systemUiVisibility));
            }
            if (subtreeSystemUiVisibility != 0) {
                sb.append(System.lineSeparator());
                sb.append(prefix).append(&quot;  vsysui=&quot;).append(ViewDebug.flagsToString(
                        View.class, &quot;mSystemUiVisibility&quot;, subtreeSystemUiVisibility));
            }
            sb.append('}');
            return sb.toString();
        }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3번째&quot;&gt;3번째&lt;/h3&gt;

&lt;p&gt;frameworks/base/core/java/android/view/Window.java의 781줄
&lt;a href=&quot;https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/Window.java&quot;&gt;링크&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;   void adjustLayoutParamsForSubWindow(WindowManager.LayoutParams wp) {
        CharSequence curTitle = wp.getTitle();
        if (wp.type &amp;gt;= WindowManager.LayoutParams.FIRST_SUB_WINDOW &amp;amp;&amp;amp;
                wp.type &amp;lt;= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
            if (wp.token == null) {
                View decor = peekDecorView();
                if (decor != null) {
                    wp.token = decor.getWindowToken();
                }
            }
            if (curTitle == null || curTitle.length() == 0) {
                final StringBuilder title = new StringBuilder(32);
                if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA) {
                    title.append(&quot;Media&quot;);
                } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY) {
                    title.append(&quot;MediaOvr&quot;);
                } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
                    title.append(&quot;Panel&quot;);
                } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL) {
                    title.append(&quot;SubPanel&quot;);
                } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL) {
                    title.append(&quot;AboveSubPanel&quot;);
                } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG) {
                    title.append(&quot;AtchDlg&quot;);
                } else {
                    title.append(wp.type);
                }
                if (mAppName != null) {
                    title.append(&quot;:&quot;).append(mAppName);
                }
                wp.setTitle(title);
            }
        } else if (wp.type &amp;gt;= WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW &amp;amp;&amp;amp;
                wp.type &amp;lt;= WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
            // We don't set the app token to this system window because the life cycles should be
            // independent. If an app creates a system window and then the app goes to the stopped
            // state, the system window should not be affected (can still show and receive input
            // events).
            if (curTitle == null || curTitle.length() == 0) {
                final StringBuilder title = new StringBuilder(32);
                title.append(&quot;Sys&quot;).append(wp.type);
                if (mAppName != null) {
                    title.append(&quot;:&quot;).append(mAppName);
                }
                wp.setTitle(title);
            }
        } else {
            if (wp.token == null) {
                wp.token = mContainer == null ? mAppToken : mContainer.mAppToken;
            }
            if ((curTitle == null || curTitle.length() == 0)
                    &amp;amp;&amp;amp; mAppName != null) {
                wp.setTitle(mAppName);
            }
        }
        if (wp.packageName == null) {
            wp.packageName = mContext.getPackageName();
        }
        if (mHardwareAccelerated ||
                (mWindowAttributes.flags &amp;amp; FLAG_HARDWARE_ACCELERATED) != 0) {
            wp.flags |= FLAG_HARDWARE_ACCELERATED;
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;해시맵과 switchcase 비교.
&lt;a href=&quot;https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/View.java&quot;&gt;view링크&lt;/a&gt;
view.java 5391줄 -&amp;gt; 많은 swtich case 구문. 직접 작성해서 비교해보기.
enummap으로도?&lt;/p&gt;</content><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><summary type="html">temp</summary></entry><entry><title type="html">스터디 12주차</title><link href="https://songmoolee.github.io/study/sixteenth-post/" rel="alternate" type="text/html" title="스터디 12주차" /><published>2020-06-01T00:00:00+00:00</published><updated>2020-06-01T00:00:00+00:00</updated><id>https://songmoolee.github.io/study/sixteenth-post</id><content type="html" xml:base="https://songmoolee.github.io/study/sixteenth-post/">&lt;h3 id=&quot;surfaceflinger-간략히&quot;&gt;SurfaceFlinger 간략히&lt;/h3&gt;

&lt;p&gt;사용자의 프로세스 혹은 응용 프로그램에서 생성한 화면(원래는 하나의 Surface)을 합성하여 LCD 화면에 그림을 출력할 수 있도록 관장하는 역할을 한다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.oss.kr/oss/images/news/000000005680-0000.jpg&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;따라서 SurfaceFlinger의 역할은 크게 2가지로 볼 수 있다.&lt;/p&gt;

&lt;p&gt;(1) 사용자 프로세스나 앱에서 생성한 화면을 관리 하는 역할·화면의 위치, 표시 순서(Display Order), 색상 등을 관리하는 역할&lt;/p&gt;

&lt;p&gt;(2) 커널에 위치한 프레임 버퍼 드라이버와 연동하여 생성된 최종 이미지를 프레임 버퍼 드라이버를 통해 LCD에 출력할 수 있도록 프레임 버퍼와 연동하는 역할&lt;/p&gt;

&lt;p&gt;이와 같이 SurfaceFlinger의 역할을 분류해 볼 수 있다.
하지만 게임과 같은 응용 프로그램이나 카메라를 통한 프리뷰 동작을 위해서는 고속의 화면 처리가 필요한 응용 프로그램에서는 SurfaceFlinger를 사용하여 처리하기에는 속도 면에서 부적절 하기 때문에 하드웨어 오버레이(Overlay) 사용하여 출력하는 방법이 사용된다.&lt;/p&gt;

&lt;h4 id=&quot;프레임버퍼-드라이버&quot;&gt;프레임버퍼 드라이버&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://www.oss.kr/oss/images/news/000000005680-0001.jpg&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;프레임 버퍼 드라이버의 동작 모습을 사용자의 응용 프로그램 관점에서 보여준다. 사용자의 응용 프로그램에서 작성한 화면은 프레임 버퍼 드라이버를 거쳐, 프로세서 내부에 있는 LCD 컨트롤러를 통해 LCD에 표시되게 된다. 물론 안드로이드 시스템에서는 프로그램을 작성하여 운영할 수 있지만, 앱이나 사용자의 프로세스에서 만들어진 모든 동작들은 SurfaceFlinger를 통해 운영이 된다. 즉, 사용자의 응용 프로그램과 프레임 버퍼 드라이버상에 위치하여 관리하게 된다. 따라서 프레임 버퍼에 대한 윈리의 이해, SurfaceFlinger에 대한 정확한 동작의 이해가 필요한 이유다.&lt;/p&gt;

&lt;h4 id=&quot;안드로이드-시스템에서-프레임버퍼-드라이버의-특이사항&quot;&gt;안드로이드 시스템에서 프레임버퍼 드라이버의 특이사항&lt;/h4&gt;

&lt;p&gt;● 기존 리눅스 프레임 버퍼 드라이버에 struct fp_ops와 fb_ pan_display 함수가 추가로 구현되어야 함&lt;/p&gt;

&lt;p&gt;● 실제 프레임 버퍼 크기보다 두 배의 메모리 할당 필요 해당 함수는 프레임 버퍼의 디스플레이 포인터를 옮기는 기능을 제공한다. 즉, 실제 화면보다 넓은 가상 디스플레이를 구현 가능하도록 함&lt;/p&gt;

&lt;p&gt;● 안드로이드 시스템의 프레임 버퍼 드라이버는 고속 처리를 위해 반드시 더블 버퍼링(Double Buffering)을 사용하도록 구성됨&lt;/p&gt;

&lt;h4 id=&quot;surfaceflinger&quot;&gt;SurfaceFlinger&lt;/h4&gt;

&lt;p&gt;SurfaceFlinger의 역할은 앞에서 설명 했듯이 앱이나 사용자의 응용 프로그램에서 생성한 화면(여기에서는 Surface라는 용어를 사용함) 합성 관리하는 역할이다. “Surface+Flinger”의 합성이다. 즉, 생성된 여러 개의 Surface를 하나의 Surface로 만들고 이 만든 화면을 프레임 버퍼 드라이버와 연계하여 프레임 버퍼로 만들고, LCD 화면에 표시하는 역할을 하는 것이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.oss.kr/oss/images/news/000000005680-0002.jpg&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;surfaceflinger-전체적-구성&quot;&gt;SurfaceFlinger 전체적 구성&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://www.oss.kr/oss/images/news/000000005680-0003.jpg&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;통상적인 앱은 android.view.Surface 클래스를 통해 화면 제어를 하게 된다. 당연히 앱과 내부간의 통신은 JNI 인터페이스를 통해 UI와 통신하고, SurfaceFlinger와는 바인더 통신을 통해 접근하게 된다. 안드로이드 시스템에서 생성되는&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;일반적인 그래픽들의 처리는 gralloc와 프레임 버퍼 드라이버를 통하여 그려지게 되고,&lt;/li&gt;
  &lt;li&gt;카메라나 멀티미디어와 같은 하드웨어 가속을 쓰는 경우에는 오버레이(overlay)를 통해 관리되게 된다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;surfaceflinger의-layer와-layerbuffer&quot;&gt;SurfaceFlinger의 Layer와 LayerBuffer&lt;/h4&gt;

&lt;p&gt;SurfaceFlinger 는 createSurface() 가 호출되면 Surface 클래스를 바로 생성 하는 것이 아니고 Layer 클래스를 생성한다. createSurface() 함수에 넘어온 인자에 따라 어떤 Layer 클래스를 생성할지를 선택한다. Layer 클래스는 각각 다른 형태로 출력을 하며 Surface 클래스를 포함하고 있다. SurfaceFlinger 클래스는 createSurface() 함수 요청이 있을 때마다 LayerXXX 형태의 클래스를 만들지만 리턴은 LayerXXX 클래스 내부의 getSurface() 함수를 통해서 Surface 형을 돌려주게 된다.&lt;/p&gt;

&lt;h3 id=&quot;view-간략히&quot;&gt;View 간략히&lt;/h3&gt;

&lt;p&gt;뷰는 안드로이드 기본 화면을 구성하는 모든 기본 화면의 구성요소이다.
우리가 어플리케이션에서 보는 버튼, 테이블, id/pw 입력 칸 등등 모든 것이 뷰가 된다.&lt;/p&gt;

&lt;p&gt;뷰는 뷰를 포함 할 수 있고, 중첩적으로 사용 할 수 있다.&lt;/p&gt;

&lt;p&gt;이때 뷰 중에서 눈에 보이는 것들은 &lt;b&gt;위젯&lt;/b&gt;이라 부르고, 눈에 보이지 않는 것들은 &lt;b&gt;레이아웃&lt;/b&gt;이라고 부른다.&lt;/p&gt;

&lt;p&gt;레이아웃은 그 안에 다른 뷰들을 담아둘 수 있는데 레이아웃도 뷰를 상속하여 정의되었기 때문에 레이아웃 안에 레이아웃도 담을 수 있습니다.&lt;/p&gt;

&lt;p&gt;레이아웃 안에 레이아웃, 다시 그 레이아웃 안에 레이아웃을 넣는 방식을 사용하면 복잡하지만 다이나믹한 화면을 연출 할 수 있게 된다.&lt;/p&gt;

&lt;p&gt;크기순서 : Window &amp;gt; Surface &amp;gt; Canvas &amp;gt; View&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2F8meYQ%2FbtqwBXNiVvA%2F5WWUalKRPLt73lXob4PTs0%2Fimg.png&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;window&quot;&gt;Window&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://miro.medium.com/max/2160/1*GqBKZVXpY-0dqwoY24PzyQ.png&quot; alt=&quot;5&quot; /&gt;&lt;/p&gt;

&lt;p&gt;색이 있는 네모 3개가 Window이다. 위와 같이 하나의 화면 안에는 여러개의 Window를 가질 수 있고 이러한 Window들은 WindowManager가 관리를 합니다.&lt;/p&gt;

&lt;p&gt;Window는 뭔가를 그릴 수 있는 창이라고 생각하면 됩니다. 보통 하나의 Surface를 가지고 있으며, Application은 Window Manager와 상호작용하여 Window를 만듭니다. Window Manager는 각각의 Window 표면에 Component를 그리기 위해 Surface를 만듭니다.&lt;/p&gt;

&lt;h4 id=&quot;surface&quot;&gt;Surface&lt;/h4&gt;

&lt;p&gt;각각의 Window는 Surface를 가집니다.&lt;/p&gt;

&lt;p&gt;Surface는 화면에 합성되는 픽셀을 보유한 객체입니다. 화면에 표시되는 모든 Window는 자신만의 Surface가 포함되어 있으며, Surface Flinger가 여러 소스로부터 그래픽 데이터 버퍼를 받고, 그것들을 합성해서 Display로 보냅니다.&lt;/p&gt;

&lt;p&gt;개별 Surface는 이중 버퍼 렌더링을 위한 1개 이상(보통 2개)의 버퍼를 가집니다.&lt;/p&gt;

&lt;h4 id=&quot;canvas&quot;&gt;Canvas&lt;/h4&gt;

&lt;p&gt;실제 UI를 그리기 위한 공간으로 비트맵이 그려지는 공간이라고 생각합니다.&lt;/p&gt;

&lt;h4 id=&quot;view&quot;&gt;View&lt;/h4&gt;

&lt;p&gt;View는 Window 내부의 대화식 UI 요소입니다. 창에는 단일 뷰 계층 구조가 연결되어 있으며 모든 창의 동작을 제공합니다.&lt;/p&gt;

&lt;p&gt;Window가 다시 뭔가를 그려야할 때마다 Window의 Surface에서 작업이 수행됩니다. 만약 Surface가 잠기면 그리는데 사용할 수 있는 Canvas가 반환이 됩니다. 그럼 Draw Traversal가 계층적으로 각 뷰를 Canvas에 전달하여 UI를 그리기 시작합니다.&lt;/p&gt;

&lt;p&gt;완료가 되면 Surface가 잠기고 방금 그린 Buffer가 포그라운드 상태로 바뀌고 Surface Flinger에 의해서 화면에 합성됩니다.&lt;/p&gt;

&lt;h4 id=&quot;surfaceview&quot;&gt;SurfaceView&lt;/h4&gt;

&lt;p&gt;일반적인 View는 Main Thread에서 캔버스를 그리기 때문에, 그리기를 하는 동안에는 사용자의 입력을 받을 수 없고 그로 인해 반응성이 좋지 못합니다. 그렇다고 그리는 작업을 별도의 작업 스레드에서 처리하고 싶어도 안드로이드 정책 상 Main Thread가 아닌 별도의 Thread에서는 UI 관련 작업을 할 수도 없습니다. 이럴때 사용할 수 있는게 SurfaceView입니다.&lt;/p&gt;

&lt;p&gt;SurfaceView는 Canvas 아닌 Surface(=가상 메모리 화면)에 그리고 그려진 Surface를 화면에 뿌리기 때문에 게임이나, 카메라 같은 높은 반응성이 필요한 UI 작업이 필요한 경우 사용할 수 있습니다.&lt;/p&gt;

&lt;h4 id=&quot;view와-viewgroup&quot;&gt;View와 ViewGroup&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;http://cdn.learncomputer.com/wp-content/uploads/2012/01/image0033.png&quot; alt=&quot;6&quot; /&gt;&lt;/p&gt;

&lt;p&gt;안드로이드에서 UI요소들은 크게 View와 ViewGroup으로 이루어져 있으며 아래와 같은 특징들을 가지고 있습니다.&lt;/p&gt;

&lt;p&gt;View는 화면상의 UI를 구성합니다.
ViewGroup은 ViewGroup과 View를 포함합니다.
TextView, Button등 기본적인 화면 구성 요소들은 View에 상속되어 구현됩니다.
개별적으로 속성을 가지며 개별 속성은 Parent로부터 상속을 받을 수 있습니다.
View는 Window의 Surface를 이용하여 화면을 그리고, 이벤트를 어떻게 처리할지에 대한 구현을 하는 객체입니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;출처: https://www.crocus.co.kr/1545 [Crocus], https://www.oss.kr/, https://jungwoon.github.io/android/2019/10/02/How-to-draw-View/&lt;/p&gt;</content><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><summary type="html">SurfaceFlinger 간략히</summary></entry><entry><title type="html">스터디 11주차</title><link href="https://songmoolee.github.io/study/fifteenth-post/" rel="alternate" type="text/html" title="스터디 11주차" /><published>2020-05-26T00:00:00+00:00</published><updated>2020-05-26T00:00:00+00:00</updated><id>https://songmoolee.github.io/study/fifteenth-post</id><content type="html" xml:base="https://songmoolee.github.io/study/fifteenth-post/">&lt;h3 id=&quot;코루틴이란&quot;&gt;코루틴이란&lt;/h3&gt;

&lt;p&gt;코루틴은 코틀린만의 것이 아니다.
이름이 비슷해서 코틀린의 것이라고 생각할 수 있지만 파이썬, C#, Go, Javascript 등 여러 언어에서 지원하고 있는 개념이다. Javascript를 사용하고 있으면서 async await를 사용하고 있다면 이미 코루틴을 사용해본 경험이 있는것이다. 아무튼 코루틴은 새로운 개념, 새로운 기술이 아니라 프로그래밍이 세상에 나온 초창기 부터 존재하던 개념이다.&lt;/p&gt;

&lt;p&gt;앱이든 웹이든 비동기 처리가 핵심인 클라이언트 프로그래밍에서 지금까지 가장 핫한 키워드는 rx programming일 것이다.
그러나 구글이 안드로이드 공식 언어를 자바에서 코틀린으로 변경한 이후, 최근 들어 대표적인 샘플 예제들인 bluprint와 sunflower 앱의 비동기처리를 coroutine으로 바꾸었다(아직 rx로 짠 코드를 특정 브랜치로 남겨놓고 있긴하다).
Rx 라이브러리를 걷어내고 코루틴으로 새로 작성한 것이다. 이와 더불어 상당히 많은 외국 자료들이 올라오고있다. &lt;b&gt;그 이유는 코루틴을 사용하면 비동기 처리가 너무나도 쉽게 이루어 질 수 있기 때문이라고 생각한다. 이런 이유 만으로 코루틴을 공부해 볼 가치는 충분하다.&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
코루틴을 3가지 키워드 정도로 알아보려고 한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;협력형 멀티 태스킹&lt;/li&gt;
  &lt;li&gt;동시성 프로그래밍 지원&lt;/li&gt;
  &lt;li&gt;비동기 처리를 쉽게 도와줌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;가장 중요한 개념은 1번, 협력형 멀티 태스킹이다. 사실 협력형 멀티태스킹에 대한 내용을 이해한다면 코루틴이란 것을 다 알게되는 것이다. 그러나 코루틴을 내 것으로 만들기 위해서는 동시성 프로그래밍과, 비동기 처리에 대한 관점에서 이해하는 것도 중요하다.&lt;/p&gt;

&lt;h4 id=&quot;협력형-멀티태스킹&quot;&gt;협력형 멀티태스킹&lt;/h4&gt;

&lt;p&gt;Routine은 하나의 태스크, 함수 정도로 생각하면 된다. 즉 협력하는 함수다. 더 진도를 나가기에 앞서 Routine에 대해서 좀 더 알아보자.&lt;/p&gt;

&lt;p&gt;Routine에는 우리가 흔히 알고있는 main routine과 sub routine이 존재한다. 이런 단어들이 생소할 수도 있지만, 우리가 늘 작성하고 있는 코드들이다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/18481078/63651600-6a5a5100-c791-11e9-87d1-3f81dc9b415d.png&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/18481078/63651648-f8ced280-c791-11e9-9917-1b034b855e84.png&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;자바코드이다. 메인 루틴이 서브루틴을 호출하면, 서브루틴의 맨 처음 부분에 진입하여 return문을 만나거나 서브루틴의 닫는 괄호를 만나면 해당 서브루틴을 빠져나오게 된다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/18481078/63651659-303d7f00-c792-11e9-9aae-0b756bb5e8a8.png&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/18481078/63651705-a0e49b80-c792-11e9-9924-eb737b813065.png&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;코루틴도 routine이기 때문에 하나의 함수로 생각하자.
그런데 이 함수에 진입할 수 있는 진입점도 여러개고, 함수를 빠져나갈 수 있는 탈출점도 여러개다.&lt;/p&gt;

&lt;p&gt;즉, 코루틴 함수는 꼭 return문이나 마지막 닫는 괄호를 만나지 않더라도 언제든지 중간에 나갈 수 있고, 언제든지 다시 나갔던 그 지점으로 들어올 수 있다.&lt;/p&gt;

&lt;h4 id=&quot;동시성-프로그래밍&quot;&gt;동시성 프로그래밍&lt;/h4&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;img src=&quot;https://user-images.githubusercontent.com/18481078/63693907-2d08c880-c850-11e9-8160-9198c9a755d1.png&quot; alt=&quot;5&quot; /&gt;&lt;/p&gt;

&lt;p&gt;// 코틀린 자바 성능 비교 자료 링크(비동기 처리에 대한 것은 없다, 참고자료)
&lt;a href=&quot;https://ko.bccrwp.org/compare/kotlin-vs-java-compilation-speed-f357b9/&quot;&gt;https://ko.bccrwp.org/compare/kotlin-vs-java-compilation-speed-f357b9/&lt;/a&gt;
&lt;a href=&quot;https://aroundck.tistory.com/4881&quot;&gt;https://aroundck.tistory.com/4881&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;코드-분석&quot;&gt;코드 분석&lt;/h3&gt;

&lt;p&gt;WindowManagerShellCommand.java&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; @Override
    public int onCommand(String cmd) {
        if (cmd == null) {
            return handleDefaultCommands(cmd);
        }
        final PrintWriter pw = getOutPrintWriter();
        try {
            switch (cmd) {
                case &quot;size&quot;:
                    return runDisplaySize(pw);
                case &quot;density&quot;:
                    return runDisplayDensity(pw);
                case &quot;folded-area&quot;:
                    return runDisplayFoldedArea(pw);
                case &quot;overscan&quot;:
                    return runDisplayOverscan(pw);
                case &quot;scaling&quot;:
                    return runDisplayScaling(pw);
                case &quot;dismiss-keyguard&quot;:
                    return runDismissKeyguard(pw);
                case &quot;tracing&quot;:
                    // XXX this should probably be changed to use openFileForSystem() to create
                    // the output trace file, so the shell gets the correct semantics for where
                    // trace files can be written.
                    return mInternal.mWindowTracing.onShellCommand(this);
                case &quot;set-user-rotation&quot;:
                    return runSetDisplayUserRotation(pw);
                case &quot;set-fix-to-user-rotation&quot;:
                    return runSetFixToUserRotation(pw);
                default:
                    return handleDefaultCommands(cmd);
            }
        } catch (RemoteException e) {
            pw.println(&quot;Remote exception: &quot; + e);
        }
        return -1;
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;
WindowProcessController.java&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; public WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info,
            String name, int uid, int userId, Object owner, WindowProcessListener listener) {
        mInfo = info;
        mName = name;
        mUid = uid;
        mUserId = userId;
        mOwner = owner;
        mListener = listener;
        mAtm = atm;
        mLastReportedConfiguration = new Configuration();
        mDisplayId = INVALID_DISPLAY;
        if (atm != null) {
            onConfigurationChanged(atm.getGlobalConfiguration());
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;
WindowTracing.java&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int onShellCommand(ShellCommand shell) {
        PrintWriter pw = shell.getOutPrintWriter();
        String cmd = shell.getNextArgRequired();
        switch (cmd) {
            case &quot;start&quot;:
                startTrace(pw);
                return 0;
            case &quot;stop&quot;:
                stopTrace(pw);
                return 0;
            case &quot;status&quot;:
                logAndPrintln(pw, getStatus());
                return 0;
            case &quot;frame&quot;:
                setLogFrequency(true /* onFrame */, pw);
                mBuffer.resetBuffer();
                return 0;
            case &quot;transaction&quot;:
                setLogFrequency(false /* onFrame */, pw);
                mBuffer.resetBuffer();
                return 0;
            case &quot;level&quot;:
                String logLevelStr = shell.getNextArgRequired().toLowerCase();
                switch (logLevelStr) {
                    case &quot;all&quot;: {
                        setLogLevel(WindowTraceLogLevel.ALL, pw);
                        break;
                    }
                    case &quot;trim&quot;: {
                        setLogLevel(WindowTraceLogLevel.TRIM, pw);
                        break;
                    }
                    case &quot;critical&quot;: {
                        setLogLevel(WindowTraceLogLevel.CRITICAL, pw);
                        break;
                    }
                    default: {
                        setLogLevel(WindowTraceLogLevel.TRIM, pw);
                        break;
                    }
                }
                mBuffer.resetBuffer();
                return 0;
            case &quot;size&quot;:
                setBufferCapacity(Integer.parseInt(shell.getNextArgRequired()) * 1024, pw);
                mBuffer.resetBuffer();
                return 0;
            default:
                pw.println(&quot;Unknown command: &quot; + cmd);
                pw.println(&quot;Window manager trace options:&quot;);
                pw.println(&quot;  start: Start logging&quot;);
                pw.println(&quot;  stop: Stop logging&quot;);
                pw.println(&quot;  frame: Log trace once per frame&quot;);
                pw.println(&quot;  transaction: Log each transaction&quot;);
                pw.println(&quot;  size: Set the maximum log size (in KB)&quot;);
                pw.println(&quot;  status: Print trace status&quot;);
                pw.println(&quot;  level [lvl]: Set the log level between&quot;);
                pw.println(&quot;    lvl may be one of:&quot;);
                pw.println(&quot;      critical: Only visible windows with reduced information&quot;);
                pw.println(&quot;      trim: All windows with reduced&quot;);
                pw.println(&quot;      all: All window and information&quot;);
                return -1;
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;참고자료로 가져왔다 일단&lt;/p&gt;

&lt;p&gt;출처 : https://developer.android.com/, https://wooooooak.github.io/kotlin/2019/08/25/&lt;/p&gt;</content><author><name>Songmoo Lee</name><email>goonta96@naver.com</email></author><summary type="html">코루틴이란</summary></entry></feed>