What's New in Kotlin on Android, 2 Years In (Google I/O'19)

[음악 재생] JEFFREY VAN GOGH : 안녕하세요 나는 Jeffrey van Gogh입니다

저는 Android Studio의 기술 책임자입니다 그리고 나는 프로그래밍 언어를 책임지고있다 및 컴파일러 하디 해리 : 그리고 저는 하디, 개발자 옹호자입니다 JetBrains에서

[치어 리더] JEFFREY VAN GOGH : 그래서 2 년이 지났습니다 구글이 안드로이드에 대한 코 틀린의 지원을 발표 한 이후 그리고 어제 Google은 Kotlin-first를 발표했습니다 그래서 우리는 당신에게 이것을 배경으로 줄 알았습니다 그리고 물론, 우리는 2 년 전에 시작하지 않았습니다

우리는 물건을 얻기 위해 상당한 시간이 걸렸습니다 안드로이드에서 Kotlin에 대한 준비 그리고 우리는 3 년, 3 년, 1 년 반 전에 결정했습니다 Google에는 수많은 언어 괴짜가있었습니다 나도 코 틀린과 놀기 시작 했어

헤이, 이것은 실제로 아주 멋지다 물론 Android Studio는 IntelliJ를 기반으로합니다 그리고 IntelliJ는 Kotlin을 오래된 코드베이스로 사용하기 시작했습니다 그래서 우리는 점점 더 코 틀린을 보게되었습니다 Android Studio에서 사용 중입니다

그리고 동시에, 우리는 고객 권고에서 많은 고객 피드백 게시판, 설문 조사 및 임시 토론 이 같은 회의에서 사람들은 Kotlin을 정말 좋아합니다 그리고 그들은 정말로 Google이 그것을 지원하기를 바라고 있습니다 왜냐하면 그들의 회사는 그렇지 않으면 Kotlin을 채택하지 않기 때문입니다 물론, 그런 새로운 언어를 사용합니다 큰 일이다

그래서 우리는 이사들에게 이것이 투자 할 가치가있는 무언가 우리가 발견 한 가장 좋은 방법은 우리 이사들에게 코드를 작성하게 Kotlin에서 며칠 동안 그 후에 그들은 팔렸다 I / O 2017 이전에 몇 달 전에, 우리는 그것을하기로 결정했습니다 이것은 많은 회의가이 모든 것을 설정하는 것을 의미했습니다

테크니컬 리드 나 매니저로서, 당신은 더 이상 코딩 할 시간이 충분하지 않습니다 기초를 설정하십시오 따라서 Google I / O 2017 이전의 모든 준비가 완료되었습니다 Android Dev 하위 레딧에이 큰 스레드가있었습니다 구글이 결코 Kotlin을 받아들이지 않을 것입니다

물론 우리는 무슨 일이 일어날 지 알고있었습니다 하지만 그 스레드에 회신을 보내는 것은 너무 어려웠습니다 그래, 2 년 전 Steph는 무대에 올랐어 코 틀린 지원 발표 나는 그것이 개발자의 가장 큰 박수라고 생각한다

기조 그것은 훌륭했다 물론, 우리 모두는 JetBrains과 Google 모두에서 알고있었습니다 그건 우리가 많은 일을했다는 것을 의미했다 우리 앞에 Kotlin이 잘 작동했는지 확인하십시오

Android 및 일반적으로 그리고 오늘, 우리는 우리가 지난 2 년 동안해온 일의 하디가 무슨 일이 일어 났는지 얘기 할거야 지난 몇 년 동안 코 틀린에게 그리고 나서 다시 가져 가겠 어 안드로이드 측에서 우리가 한 일에 대해서 이야기하겠습니다

하리 하리 : 고마워 시작하려면 먼저 언급하고 싶습니다 코 틀린 재단 (Kotlin Foundation) Google에서 공식 지원을 발표 한 시점을 기억한다면 몇 년 전에 Kotlin을 위해, 우리는 또한 간략하게 언급했다 우리가 창안 된 기초가 될 것입니다 JetBrains와 Google이 보호, 홍보 및 홍보 언어 Kotlin

재단은 이사회의 통제를받습니다 JetBrains의 두 대표, 두 구글, 및 1 명의 독립적 인 일원 그리고 당신에게 약간의 아이디어를주기 위해서입니다 기초의 범위가 무엇인지, 직업 중 하나 현재 언어 리드 디자이너를 임명하는 것이고, 물론 Andrey Breslav가 있습니다 변화를 막기위한 언어위원회

그리고이 점을 이해하는 것이 매우 중요합니다 범위면에서 제한적입니다 따라서 변경 사항을 깨는 것입니다 Kotlin은 지금도 열려 있기 때문에 계속 개발되고 있으며, GitHub에 우리는 여전히 KEEP을 가지고 있는데 이것은 Kotlin Evolution 개선 프로세스

그러나 언어위원회는 대부분 언어에 일어날 수있는 변화를 깨고 또한 상표 소위원회가 있습니다 그것은 Kotlin의 상표를 보호하는 것입니다 Kotlin을 홍보하고 사용하는 데 도움이되는 커뮤니티와 협력 공정한 방법으로 Kotlin 그리고 당신이 기초에 관하여 더 많은 것을 발견하고 싶은 경우에, 당신은 KotlinLang 웹 사이트에 갈 수 있습니다 세부 정보뿐만 아니라 더 많은 정보를 얻을 수 있습니다

Kotlin과 상표 등을 어떻게 사용할 수 있는지에 관한 정보 그리고 그걸로 데모로 넘어 갑시다 그리고 나는 언어로 당신에게 몇 가지 것을 보여줄 것입니다 이것은 내가 다른 사람의 기계를 사용하고있는 곳이다 이것이 어떻게 진행되는지 봅시다

ID가 맞다고 생각해 예 그래서 저는 언어에 대해 몇 가지 것을 보여 드리겠습니다 아마 가장 근본적이고 가장 중요한 것입니다 우리가 한 짓은 아주 취한 것입니다

오랫동안, 당신이 코 틀린을 쓰는 것에 익숙하다면 응용 프로그램을 사용하면 주된 진입 점이 있습니다 그래서 우리는 실제로 그것을 만들었으므로 매개 변수가 없습니다 그게 전부입니다 고맙습니다 제프리, 네가 원하니? 오

[웃음] 우린 2 년이 걸렸어 아니 그래서 우리는 우리가 가지고있는 작은 것들 중 일부부터 시작할 것입니다 언어 자체로 완성되었습니다 예를 들어, when 문을 사용하면 변수의 값을 캡처해야합니다

그 변수를 검사해야합니다 너는 너의 실제 내부에서만 그것을 사용하고있어 when 문 그래서 우리는 이것을 조금 더 멋지게 만들었습니다 본질적으로 변수를 때 문 자체

따라서 범위 밖에서 참조 할 필요가 없습니다 그리고 이것은 당신에게 당신의 언어로 의미를 부여합니다 사람들은 이것이 실제로 제한되어 있음을 이해합니다 조건부로 하지만 조금 더 얘기하자

우리가 소개 한 멋진 기능들 그것들은 좋지 않았다 나는 우리가 도입 한 더 멋진 기능을 말하고 있습니다 예를 들어 응용 프로그램이 있다고 가정 해 봅시다 클래스를 만들고 싶습니다

그리고 수업을 만들겠습니다 MicroserviceAPI라고 불릴 것입니다 그래서 저는 마이크로 서비스 API의 인스턴스를 만들 수 있습니다 마이크로 서비스 API를 말할 것입니다 우리는 거기에 갈

이제,이 마이크로 서비스가 필요한지는 모르겠습니다 마지막으로 갈거야 단지 유행 일 수 있습니다 그래서 내가하고 싶은 것은 사람들에게 이게이게 친절한 사람들이야 실험적인 기능과 같습니다

우리가 할 수있는 일은 우리가 실제로 할 수있는 것입니다 주석 클래스를 만든다 예를 들어, 이것이 새로운 API라고 말할 수 있습니다 그 주석 클래스에 주석을 달아라 Experimental이라는 다른 클래스와 함께 이제 새로운 실험적 주석을 사용할 수 있습니다

나는 내가 실험적으로 생각하는 어떤 것에도 창조했다 내 API에서 그래서 여기에이 새로운 API를 추가 할 수 있습니다 그리고 내가 그렇게하면, 이것이 빨간색으로 변하고 있음을 알 수 있습니다 그래서 그것은 나에게 컴파일러 오류를주고있다

당신이 이것을 사용할 수 없다는 말입니다 이것은 실험적인 기능이기 때문입니다 그 위에 마우스를 올려 놓으면 실험적이라고 말하는 것입니다 사실, 우리는 그것을 바꿀 수 있습니다 우리는 그것이 오류가 아니라, 실제로 경고로 정의 할 수 있습니다

그래서 여기에 경고가 될 수 있습니다 그리고 지금 막 가고 있습니다 경고로 표시됩니다 그래서 이것을 사용하기 위해서, 개발자 기본적으로이 기능을 선택해야합니다 내가 할 수있는 것은 Alt-Enter입니다

이제는 함수 호출에 새 API를 추가합니다 그래서 내가 어디에서 이것을 사용하는지, 이것은 실험적인 기능이라고합니다 이것은 사람들에게 당신이 지금 생각할 수있는 아이디어를줍니다 실험적이고 비슷한 종류의 API를 만들 수 있습니다 나는 아무것도 보증하지 않을거야

내일 우리가 뭔가를 바꾸고 싶다면 괜찮아 니가 경고 했어 Alt-Enter를 누르십시오 당신이 Alt-Enter를 봤다는 것을 알았습니다 괜찮아

너 자신의 잘못이야 그리고 우리가 실제로이 일을 한 것 중 하나는 우리는이 계약 개념을 도입 했습니까? 따라서 약간의 코드 계약에 익숙하다면, 우리는 이것을 Kotlin의 실험적 기능으로 소개했습니다 게다가 그래서 나는 어떤 함수가 있다고 가정 해 봅시다 예 : printLength

그리고 이것은 nullable 인 문자열을 취할 것이고, 그리고 string이 null이 아닌 경우, 나는 println 길이 할거야 이제이 방법이 효과가 있으며 스마트 캐스트가 완료되었습니다 문자열, null이 아닌 문자열, 내가 이미 그걸 발견했기 때문에 이것이 nullable이 아니라는 것을 알아 냈습니다 그래서 나는이 똑똑한 던지기를 할 수있다 그러나 내가 이것을 취해야한다면, 그리고 널 (null)이 아닌 대신에, 나는 무언가를한다, 아니다, 나는 앞으로 나아가고 창조한다

내 함수, 그래서 내 함수를 만드는 가정 해 봅시다 String이고 notNull 인 경우 부울을 반환합니다 그런 다음 반환 값이 null이 아니라고 말합니다 그 효과가 없다는 것을 알 수 있습니다 컴파일러가 실제로 그것이 not-nullable

컴파일러에게 알려주는 것이 좋을 것입니다 이 기능은 특정 계약을 준수해야합니다 그리고 Kotlin에서 이것을 정의 할 수 있습니다 계약 람다를 사용하여 계약 함수 계약이다 그리고 그것이 수입이라고 말할 수 있습니다

그리고 나는 진정한 의미의 반환을 말할 수 있습니다 이 @ notNull이 null이 아님을 나타냅니다 이제 오류가 발생합니다 무시해 아니, 농담이야

이 오류가 발생하는 이유 이것은 위에서 언급했듯이 실험적인 기능이기 때문입니다 두 가지 방법이 있습니다 첫 번째 것을 보여주었습니다 주석을 추가 할 수있었습니다 그러나 주석을 추가하면 그 주석이 전파되지 않습니다

그래서 뭔가가 그 API를 사용하고 있다면, 또한 주석을 추가해야합니다 전파 주석을 추가 할 수 있습니다 이것,이 형식입니다, 그리고 지금 나는 그렇게하지 않아도됩니다 그 통지를 추가하자마자, 지금 자동으로 다시 null이 허용되지 않는 문자열로 변환됩니다 따라서 실제로 계약을 맺고 함수에 대한 당신의 주장 특정 조건을 충족시킵니다

그리고 그것은 기본적으로 특정 수준의 코드 정확성 실제 코드에서 그럼 우리가 뭘하고 있는거야? 글쎄, 우리는 이것을 직렬화라고 부릅니다 멀티 플랫폼 인 직렬화 라이브러리입니다 JVM, JavaScript, Kotlin / Native, iOS, macOS, 리눅스, 윈도우, 임베디드 나는 태양 아래 모든 것을 언급했다고 생각한다

그리고 이것은 다중 플랫폼 라이브러리입니다 어떤 종류의 반성도 요구하지 않는, 일부 제품의 일부입니다 우리가 언어와 생태계의 일부로하고있는 일 그것 주위 그래서 여기에서는 클래스, 전형적인 데이터 클래스, 그리고이 serializable 어노테이션을 추가했다 이 라이브러리는 Kotlin 직렬화 라이브러리의 일부이며, 그런 다음 고객이 있으며 고객 목록이 있습니다

그래서 저는 println과 같은 것을 할 수 있습니다 그리고 나서 여기에서 나는 Json을 할 것입니다 stringify, Customer, 사용하고 싶은 시리얼 화자를 표시 한 다음 실제 고객을 전달하십시오 그리고 나는 똑같은 일을 고객 명단에서 할 수 있습니다 그래서 여기에 목록을 작성한 다음 고객 목록을 전달할 수 있습니다

그리고 이것을 실행한다면, 기본적으로 무엇을 할 것인가? JSON에서 해당 데이터 클래스로 출력됩니다 우리는 JSON을 지원합니다 Protobuf에 대한 지원이 있습니다 그리고 다른 것들이 작동합니다 그리고 우리는 분명히 그 반대를 할 수 있습니다

예를 들어, 여기에 JSON이 있다고 가정 해보십시오 이제 JSON을 만들어 보겠습니다 그래서 우리는 id가 1과 같을 것이고, 그 다음에 이름이 나와 같습니다 이메일은 you@mecom과 같습니다

나는 너무 독창적이다 이제 println을 할 수 있습니다이 경우, 저는 Json을 할 것입니다 parse, serializer를 다시 통과 시키십시오 그리고 내가 전달하고자하는 실제 JSON

그리고 이것이 할 일은 본질적으로 나에 대한 실제 데이터 클래스 객체 그리고 당신은 그것이 또한 – 나를 위해 데이터 객체를 반대로 만듭니다 내가 뭘 한거지? 이메일, 이름, 이메일 관객 : [INAUDIBLE] 하리 할리 : 필드 소스가 필요합니까? 아니, 그렇지 않아 관객 : [INAUDIBLE] 하리 할리 : 아니

그건 사실 맞아 어쨌든, 그렇게 일하고있었습니다

[웃음] 제프리예요 그는 뭔가를했습니다 제프리 반 고글 : 어 – 허 [박수 갈채] HADI HARIRI : 나는 사람들이 박수를 치기를 정말 좋아합니다 그래서 나는 그곳에서 무슨 일이 일어나고 있는지 모른다

그러나 그것은 라이브 데모에 대한 좋은 점입니다 뭔가 잘못 됐는지 확인하고 싶습니다 나는 사실 그것을 실제로했다 그래서 저는 그것을 운동으로했습니다 나중에 사무실 시간에 나에게 와서 그게 뭐가 잘못 됐는지 말해 줄거야

계속 나아 갑시다 내가 너에게 보여주고 싶은 다음 주석 클래스에 대한 간략한 개요입니다 여기에 지원을위한 몇 가지 추가 사항이 추가되었습니다 열거 형 예를 들어, 주석에 enum을 가질 수 있습니다

중첩 된 주석을 가질 수 있습니다 내 동반자 개체의 일부로 속성을 가질 수 있습니다 다시 말하지만, 이것은 나에게 더 많은 표현력을줍니다 실제 주석을 사용할 때 이제 우리가 작업 해 온 또 다른 것이 있습니다

당신이 들었을지도 모르는 멀티 플랫폼 프로그래밍입니다 그리고 멀티 플랫폼 프로그래밍의 아이디어는, 한 입 가득, 그 아이디어는 바로 지금 Kotlin입니다 다른 유형의 플랫폼을 타겟팅 할 수 있습니다 그래서 JVM을 대상으로 할 수 있습니다 자바 스크립트를 타겟팅 할 수 있습니다

네이티브 등을 타겟팅 할 수 있습니다 이제 이것에 대한 위대한 것들 중 하나 코드를 공유 할 수있는 능력, 왜냐하면 내가 공유하기를 원하는 많은 코드가 있기 때문입니다 권리? 비즈니스 로직, 검증 로직 등이 있습니다 내가 공유를 끝내고 싶다 그러면 우리는 어떻게 이런 일을 할 수 있습니까? 이것이 우리가 멀티 플랫폼의 개념을 도입 한 곳입니다

프로그램 작성 그리고 그 결과로, 당신은 지금 이 다중 플랫폼 프로젝트를 가질 생각이 들었습니다 그래서 당신은 내가 IDE에서이 프로젝트를 가지고 있다는 것을 알 수 있습니다 다른 플랫폼을 타겟팅하고 있습니다 그래서 나는 macOS를 가지고 있고, JVM을 가지고 있으며 JavaScript를 가지고있다

그런 다음 일련의 공통 코드가 있습니다 이것은 보통이라고 불린다 그리고 여기 안에는 몇 가지 코드가 있습니다 그래서 여기에 hello라는이 함수가 있습니다 즉, platform

name에서 인사하는 것입니다 그리고 platformname은 object의 속성입니다 그러나 차이점은이 객체 기대라고하는이 단어가 앞에 있습니다 이것이 말하는 것은 이것이 약간의 코드라는 것입니다

내 공통 코드에서 참조 할 수있는 구현은 실제로 여기에 제공되지 않습니다 구현이 제공 될 것입니다 다른 유형의 플랫폼에서 다른 방식으로, 이는 플랫폼에 따라 다를 수 있기 때문입니다 그래서이 귀여운 것을 볼 수 있습니다 여기 모퉁이에 작은

Alt Enter를 누르면 선언에 들어가라고 말하면서, 어떤 플랫폼 선언을보고 싶은지 묻습니다 따라서 JVM이라고하면 JVM으로 연결됩니다 내가 돌아가서 macOS에서 실제 선언문으로 간다면, 그것은 나를 macOS에 데려 갈 것이다 권리? 그래서 다른 플랫폼에서 다른 구현을 할 수 있습니다 그럼에도 공통 코드에서 해당 코드를 참조 할 수 있습니다

내 공유 코드 기반의 일부로 사용하십시오 그리고 시원한 것은 그렇게 생각해

생각해라 인터페이스와 조금 닮았습니다 그러한 인터페이스의 구현 그리고 멋진 점은 정적 컴파일 시간을 얻는다는 것입니다 확인, 말하자면 그래서 내가 이것을 주석으로 달아서 여기로 돌아 가면, 당신은 그것이 저에게 오류를주는 것을 볼 수 있습니다, 실제 플랫폼 중 하나 구현이 누락되었습니다

이제이 작업을 통해 공통 코드를 공유 할 수있는 다중 플랫폼 프로젝트 기초를두고 특정 구현을 기반으로한다 실제 목표에 약간 다르게 적용됩니다 그리고 그것은 멀티 플랫폼 프로젝트의 일부입니다 우리가 코 틀린과 함께 나아갈 것을 제안하고있다 예를 들어 Android와 공통 코드 기반을 공유하는 Android 애플리케이션, iOS 등

슬라이드로 다시 전환 할 수 있다면 내가 너에게 약간 얘기 할거야 우리가 가져온 다른 것들 Kotlin에게 언어 우리는 더 많은 표준 라이브러리 API를 가지고 있습니다 우리는 여전히 메소드의 API 번호를 유지하고 있습니다 조금 낮추지 만 더 많은 기능을 추가하고 있습니다

그 지역에 부호없는 정수 지원 – 아무도? 아니? 예 [박수 갈채] 나는 누군가를 항상 알고 있기 때문에 그것을 추가했다 그것에 대해 두드림 분명히 우리는 2018 년 패킷 KotlinConf를 발표했습니다

Kotlin 네이티브가 베타를 친다 툴링면에서 우리는 향상된 성능을 제공했습니다 Gradle 프로젝트를위한 고속, 병렬 빌드, KAPT를 사용한 점진적 주석 처리 Google에서 Ivan Garvrilovic에게 큰 소리 치십시오 우리를 돕기 위해

새로운 유형의 추론 엔진 상호 운용성의 많은 경우에, 특히 RX 주변에서 일하는 경우, 뿐만 아니라 언어를 조금 더 빌더를 사용할 때 간결하게, 등등 그리고 우리는이 프로그레시브 모드를 도입했습니다 본질적으로 당신이 코 틀린을 시험해 볼 수있게 해줍니다 새로운 기능을 사용해보십시오 일부 코드를 어기십시오

이제는 할 수있는 깃발입니다 Kotlin과 함께 좀 더 살기 가능하게하다 가장자리에 그리고 그걸로 제프리에게 건네 주겠어 그게 우리가했던 다른 것들을 보여줄거야

특히 안드로이드에서하고 있습니다 JEFFREY VAN GOGH : 고마워, 하디 데모를 잊어 버린 기능이 하나 있다고 생각합니다 HADI HARIRI : 당신이 무슨 말을하는지 전혀 모르겠습니다 JEFFREY VAN GOGH : 괜찮습니다

내 데모에 보여 줄게 HADI HARIRI : 당신이 아마 그것을 망 쳤어 [웃음] 제프리 반 고글 : 좋아 이제 Android 측에서 수행 한 작업을 살펴 ​​보겠습니다 Kotlin을 지원합니다

먼저 OS로 시작합시다 물론 OS는 바이트 코드로 작동합니다 따라서 Kotlin을 지원하기 위해해야 ​​할 일이별로 없습니다 그러나 우리는 정확성을 추가했는지 확인했습니다 성능 테스트를 통해 코 틀린 패턴을 깨지 않게했습니다

우리는 몇 가지 구체적인 성능을 구현했습니다 이러한 테스트를 기반으로 한 최적화, 루프 최적화에 특히 적합합니다 그리고 나서 우리는 OS 측면에서 큰 일을했습니다 디버깅 지원이 향상되었습니다 Kotlin은 몇 가지 구조를 가지고 있습니다

당신이 다른 언어로 가지고 있지 않은 인라인 함수처럼 Android의 새로운 버전 이제 더 나은 디버깅을 지원합니다 그런 다음 안드로이드 프레임 워크, 거기에서 일어나는 일이 많습니다 중요한 것은 API 주석을 추가 한 것입니다 아직 완성되지 않았습니다

그러나 새로운 API는 이제 nullness와 기본 매개 변수를 갖습니다 기본 값 주석이 있으므로 Kotlin에서 온 사람들을 사용할 수 있습니다 기존 API를 통해 작업하고 있습니다 뿐만 아니라 주석을 달 수 있습니다 그런 다음 Kotlin 확장 API를 추가했습니다

그래서 이것들은 여러분이 프로젝트에 다음을 제공하십시오 확장 메소드를 통한 추가 API Kotlin 코드를 더 관용적으로 만드십시오 그런 다음 우리는 전체 묶음에 대해 코 루틴 지원을 추가합니다 Jetpack 라이브러리 [박수 갈채] 따라서 비동기 코드를 작성할 수 있습니다

좀 더 절차적인 방법으로 그리고 물론, 어제 우리는 Jetpack Compose를 발표했습니다 그것은 모두 코 틀린입니다 이제 데모를 살펴 봅시다 좋아요 그래서 여기에 작은 앱을 만들면, 쇼 목록을 다운로드합니다

개조를 사용하여 서버에서 사용할 수 있습니다 그런 다음 로컬 SQL 데이터베이스를 검사합니다 방 API를 사용하여이 쇼들을 봤다 면요 그래서 여기에, 내가 정의한 것을 볼 수 있습니다 API를 사용하여 둘 다 RX 자바를 사용하여 쇼의 목록을 얻을, Kotlin 코딩 비동기 기능을 사용할 수도 있습니다

그리고 API는 거의 동일하다는 것을 알 수 있습니다 같은, 조금 다른 반환 유형 그리고 방 쪽 – 오, 미안 (QUIETLY) 내 코드는 어디에 있습니까? 좋습니다, API는 건너 뜁니다 꽤 많이 있습니다

오, 여기 있습니다 죄송합니다 그래서 당신은 똑같은 것을 봅니다 나는 쇼를 봤어? Java의 RX는 매우 유사합니다 여기 Flowable이 있습니다

[무관심]이 있습니다 따라서 API는 꽤 유사합니다 이제 전화하는 방식을 살펴 보겠습니다 RX와 Java 사이의 코드 – RX와 coroutines 그래서 RX에서는 쇼를 진행하기 위해 많은 운영자를 사용합니다

모든 비동기 호출로 우리의 흐름을 수행하십시오 그리고 이것들은 꽤 복잡해 질 수 있습니다 그리고이 코드는 노란색으로 강조 표시되어 있습니다 그게 내가 아는 뭔가가 있다는 뜻이야 반환 유형으로 수행

따라서 구독 할 때, 당신은 구독을 처리합니다 물론 RX는 Java에 뛰어난 표현력을 제공했습니다 그리고 RX의 발명가들은 똑똑했습니다 그들은 그들이 무엇을 만들고 있는지 알았습니다 그러나 그들은 언어에 의해 제한되었습니다

Kotlin에서 우리는 이제 coroutines를 가지고 있습니다 우리는 실제로 이것을 훨씬 더 멋지게 할 수 있습니다 그래서 코 루틴을 사용하는 동일한 코드가 있습니다 먼저 서버에서 프로그램 목록을 가져옵니다 우리는 이것을 대기 함수라고 부릅니다

신원이 알려줍니다 이봐 요 여기서 비동기적인 일이 일어나고 있습니다 그런 다음 우리는 for for 루프를 사용할 수 있습니다 그리고 그것은 반환 쇼 동안의 [INAUDIBLE]입니다

그리고 우리는 우리의 비동기 내가 로컬 데이터베이스에 쇼를 본 적이 있는지 알아보기 위해 호출하십시오 그리고 거기에서 계속됩니다 그리고 나서, 여기에, 당신은이 발사 호출을 봅니다 이 전화 해 데이터 세트가 변경되었음을 알리는 지 확인하십시오

UI 스레드에서 그리고 여기서 좋은 점은 절차 적으로 보입니다 디버깅을 할 때 – 나는 지금 시작해야한다 물론 작동하지 않습니다 오! 우리는 거기에 갈

이미 실행 중입니다 그래서 내가 실제로 볼 수 있다는 것을 알 수 있습니다 전체 방법으로부터의 변수들에서, 특정 운영자 만이 아닙니다 그래서 인생이 훨씬 쉬워집니다 비동기 코드를 디버깅 할 때 이제 슬라이드로 다시 전환하십시오

다음은 Android Tooling입니다 Android Studio에서 많은 작업을 수행했습니다 Kotlin이 잘 지원되는지 확인하십시오 우리가 한 첫 번째 일은 Kotlin 플러그인이 Android Studio에 포함되어 있음 우리가 그것을 공개하기 전에 우리는 그것을 잘 테스트 할 수 있습니다 JetBrains와 긴밀하게 협력했습니다

그들이 Kotlin 플러그인을 업데이트 할 때마다, 공개하기 전에 테스트를 통해 확실하게 확인합니다 Android Studio와 Kotlin은 잘 작동합니다 다음으로 Android 리팩토링 지원을 추가했습니다 IDE에는 많은 작업이 있습니다 Android 관련 리팩토링입니다

우리는 지원을 추가하기 위해 노력하고 있습니다 코 틀린에있는 모든 사람들에게 린트쪽에는 린트가 거의 있습니다 완전히 다시 작성되었습니다 자바 언어에 대해 [INAUDIBLE] 점검을 작성하는 데 사용되었습니다

이제는 UAST라고 불리는 것을 사용합니다 한 번 같은 린트 체크를 쓸 수 있습니다 그리고 Kotlin과 Java 코드를 모두 분석 할 수 있습니다 제품 템플릿을 추가하여 당신은 새로운 단편이나 새로운 활동을 만들고 있습니다 당신은 Kotlin 코드를 처음부터 가지고 있습니다

당신은 그것을 변환 할 필요가 없습니다 이제 컴파일러 측면에서, 우리의 새로운 Shrinker R8 Kotlin 특정 최적화가 많이있다 그것으로, 당신이 만드는 이익을 얻을 수 있도록 가능한 한 작은 코드 물론 IDE는 이제 Jetpack을 지원합니다 구성된 프레임 워크

문서 및 샘플 사이트에서, developerandroidcom을 보면, 모든 API 참조에는 이제 Kotlin 및 Java 구문이 모두 있습니다 유효한 Kotlin 관련 문서 포털이 있습니다

Kotlin을 시작하는 방법, 사용법을 알려줄 것입니다 호출자 루틴 등 또한 많은 샘플과 스 니펫 이제 Kotlin을 사용할 수 있습니다 양쪽 측면, GitHub 샘플입니다 올해 Google I / O를 살펴볼 수있을뿐만 아니라, Androids의 프레젠테이션 대부분을 볼 수 있습니다

그들의 샘플을 Kotlin에서해라 당신도 볼 수있는 몇 가지 애플 리케이션이 있습니다 Google I / O 앱은 물론이 새로운 Android 해바라기 앱 Kotlin을 사용하여 처음부터 구축되었습니다 우리는 종종 헤이 (hey)를 요청 받는다 너희들이 코 틀린을 추천하고있다

하지만 너 혼자 사용하고 있니? 물론 그것은 매우 공정한 질문입니다 현재 Google에는 많은 사내 개발자 도구가 있습니다 그래서 Kotlin 지원을 추가하는 데는 시간이 걸렸습니다 Google 직원을위한 내부 앱으로 시작했습니다 예를 들어 내부 앱이 있습니다

지도와 사무실 위치를 보여줍니다 그래서 우리는 그 사실로부터 많은 것을 배웠습니다 그 이후로 우리는 실제로 일부 공개 Google Apps에서 Kotlin을 사용하기 시작했습니다 여기에 몇 가지 앱이 있습니다 오늘 Kotlin 코드를 휴대 전화에 보냅니다

그리고 더 많은 것을 기대할 수 있습니다 Kotlin을 채택하는 것에 대해 말하면, 전체 생태계를 살펴보고, 우리는 활발한 개발에서 – 적극적인 개발은 지난 6 개월 동안 Play 스토어에 업로드했습니다 우리는 애플 리케이션의 16 %가 지금 Kotlin을 사용하고있는 것을 본다 그리고 앱이 개발 될 수 있음을 명심하십시오 하나의 버그 수정 또는 하나의 자산 변경이 있기 때문입니다

그래서 16 %는 꽤 인상적입니다 지난 I / O 이후로 5 배나 성장했습니다 그리고 당신이 최고 천개의 앱을 본다면, 그것은 실제로 이미 훨씬 더 커졌습니다 우리가 Kotlin을 사용하여 볼 수있는 애플 리케이션의 44 % 그래서 우리를 코 틀린으로 데려옵니다

어제 발표했습니다 그래서 왜 우리가 왜했는지에 대한 더 많은 개요를 알려 드리고자합니다 그것은 무엇을 의미할까요? 그렇다면 왜 코 틀린을 발표할까요? 우리는 코 틀린을 사용하는 사람들의 강한 입양을보고 있습니다 우리는 지역 사회에 큰 흥분을 안겨줍니다 사람들이 Kotlin을 사용할 때

실제로 사람들이 설문 조사에서 질문을받을 때 그들이 얼마나 Kotlin을 더 행복하게 사용하는지, 실제로 사람들보다 25 % 높은 점수를받습니다 누가 Kotlin을 사용하지 않고있다 업계 전반 및 Google 내부의 많은 앱 지금 Kotlin을 사용 중입니다 우리는 많은 고객에게 다가갔습니다 고객 자문위원회 (Customer Advisory Board)를 포함하여 그리고 Kotlin에 대한 투자에 집중하십시오

그럼 그게 무슨 뜻 이죠? 물론, 우리는 자바 프로그래밍을 계속 지원할 것입니다 많은 측면에서 언어 플랫폼, Android Studio 지원, 보풀, 안드로이드 X와 같은 Docs가 사라지지 않을 것입니다 하지만 다른 노력들을 보면 우리의 온라인 교육, 샘플처럼 우리는 먼저 Kotlin, 그리고 나서 자바 외국어가 최선의 노력이 될 것입니다 그리고 물론, 몇 가지 기능이 있습니다

다중 플랫폼 프로젝트와 Jetpack Compose 그것들은 단지 Kotlin에서 제공 될 것입니다 지금 당연히, 우리가 사람들에게서 들리는 다음 질문은, 그게 내가 전환해야한다는 뜻인가? 제발 Kotlin을 먼저 가져 가지 마세요 모든 Java 코드를 가져 와서 Kotlin에서 다시 작성해야합니다 그건 우리가 네가하고 싶지 않은거야 Android Studio를 확인하십시오

그것은 많은 수십만 줄의 코드입니다 지금은 Android Studio의 약 10 % Kotlin입니다 특정 코드 그리고 우리가하는 일은 새로운 기능 만 사용한다는 것입니다 코 틀린에 써라

그리고 그것은 Kotlin 자바와 좋은 상호 운용성을 가지고있다 Kotlin에서 단일 클래스를 작성할 수 있습니다 나머지는 Java로 유지하십시오 또는 Kotlin에서 코드의 99 % Java에서 남은 부분 만 남았습니다 물론, 당신의 현재 상태는 중요합니다

프로젝트 및 팀의 당신이 당신의 방출을 발송하는 것으로부터 1 주일 떨어져 있다면, 아마도 Kotlin으로 전환하기에 가장 좋은시기는 아닙니다 그러나 새로운 개발주기를 시작한다면, 니가 코 틀린을 데려 갈 수있을거야 물론 팀에 따라 다릅니다 그들은 Kotlin에 관심이 있습니까? 이것들을 안전하게 지니고 있습니까? 우리는 또한 많은 사람들이 실제로 모집에서 언급 한 Kotlin을 사용합니다 그들은 더 많은 후보자를 얻을 수 있습니다

고려해야 할 사항 물론, 기술적 측면에서, 고려해야 할 트레이드 오프가 있습니다 Kotlin은 뛰어난 기능, 더 많은 생산성, 그리고 만족 그러나 당신은 학습 곡선에 대해 생각해야합니다 사람들이 배우는 데는 시간이 걸립니다 관용적 인 코 틀린을 쓰기

우리는 Kotlin을 쓰는 대부분의 사람들이 첫번째 주, 그들은 정말로 Kotlin에 자바를 쓰고있다 그리고 3 개월에서 6 개월이 걸립니다 실제로 관용적 인 코 틀린을 쓰기 시작합니다 괜찮아 내 말은, 당신은 여전히 ​​코 틀린의 모든 이익을 얻습니다

nullness, et cetera에 대해 경고합니다 그럼 빌드 속도가 있습니다 Kotlin은 Java 컴파일러보다 느립니다 그것은 당신을 위해 더 많은 일을하고 있습니다 그리고 그것은 더 어린 컴파일러입니다

우리는 그것을 더 빨리 만들기 위해 열심히 노력하고 있습니다 그리고 물론, 유의하십시오 예, 느립니다 하지만 앱을 만들면 빌드가 줄어들 수 밖에 없습니다 가능성이 가장 높습니다

APK 크기도 있습니다 응용 프로그램은 표준 라이브러리를 사용하며, 약간의 공간이 필요합니다 그러나 R8과 같은 것들은 그것을 줄일 수 있습니다 진행중인 Kotlin 작업은 Google에서 계속 진행되고 있습니다 물론, Jetpack Compose가 가장 큰 것입니다

항상 새로운 KDX API를 계속 추가하고 있습니다 컴파일러 쪽에서 우리는 많은 작업을하고 있습니다 빨리하기 Kotlin 10330과 마찬가지로 증분 처리기 그리고 훨씬 더 많은 것이 있습니다

더 향상된 도구 및 더 많은 문서와 샘플을 볼 수 있습니다 Kotlin을 사용합니다 Kotlin 사용에 관심이 있다면, 하지만 어디서부터 시작해야할지 모르겠다 우리는 Kotlin Everywhere를 발표하고 있습니다 두 Google이 주최하는 일련의 교육입니다

및 JetBrains 그리고 지금과 KotlinConf 사이에서 일어나고 있습니다 올해 말 12 월 그것에 관심이 있다면, 참여하거나이 사이트를 호스팅하는 것을 돕고,이 링크로 이동하십시오 가입하십시오

따라서 새로운 Kotlin 첫 번째 로드맵을 통해, 안드로이드 용 Kotlin에 대한 투자 단지 더 커질 것입니다 아직 코 틀린을 사용해 보지 않은 여러분 모두를 초대하고 싶습니다 최근에 그것을 사용하지 않았거나 오늘 앱에서 사용해보십시오 Kotlin과 비슷한 경험을 해 주셨으면합니다 좀 더 예측적이고 코딩이 더 재미있을 것입니다

고맙습니다 [음악 재생]

Android Q beta 2, Cloud Healthcare API beta, & ML Kit for Natural Language Processing

토드 케펠 만 : 안녕 저는 Developer Show의 Todd Kerpelman입니다

가장 멋진 개발자의 주간 업데이트입니다 Google의 뉴스 안드로이드 Q 베타 2 – 헤이, 그 운은 – 지금 갱신 된 SDK 이 릴리스에는 개인 정보 보호 기능이 포함되어 있습니다 테스트 및 피드백, 새로운 방법 거품, foldables 에뮬레이터 등으로 멀티 태스킹을 할 수 있습니다

자세한 내용과 스크린 샷을 보려면, 게시물을 봐 Lustre 오픈 소스 병렬 파일 시스템 많은 양의 데이터에 액세스 할 수 있습니다 매우 빠른 속도와 낮은 대기 시간 그러나 그것을 구성하는 것은 기술적으로 도전적이고 시간 소모적 인 작업입니다 그래서 우리는 배포하기 쉬운 스크립트를 발표했습니다

Lustre 스토리지 클러스터 – 오, 그것도 운율이 – Google Cloud Deployment를 사용하는 Google Compute Engine에서 매니저 시작하려면 게시물로 넘어갑니다 Cloud Healthcare API는 관리 솔루션을 제공합니다 Google 클라우드에서 의료 데이터를 저장하고 액세스하는 방법 플랫폼, 기존 치료 간 중요한 연결 고리 제공 Google Cloud에서 호스팅되는 시스템 및 응용 프로그램 이제 베타 버전으로 제공됩니다 시작하려면 링크가 게시물에 있습니다

최적의 VM 및 메모리 최적화 된 VM 계산 Google Compute Engine에서 사용할 수 있습니다 두 제품 모두 2 세대 Intel Xeon 확장 가능한 프로세서 게시물에 일찍 접속할 수있는 링크가 있습니다 언어 식별 및 스마트 회신 이제 ML Kit에 사용할 수 있습니다 예제 코드와 문서 링크 당신은 그것을 추측했습니다

좋아요, 구독하고 공유하는 것을 잊지 마십시오 Todd Kerpelman이 "개발자 쇼"입니다 보고 주셔서 감사 드리며 다음 주에 다시 보겠습니다 하, 나는 무언가를 얻은 것처럼 미소 지을거야 나는 흥분한다

안드로이드 코딩 습관 #2 – 안드로이드 UI를 쉽게 구성해볼까요!

UI는 종이에 사진을 올리고 글을 쓰듯이 만든다는 거죠 안녕하세요 코딩 습관의 코딩 메이트 디모 입니다 지난 시간에 저희는 주소록을 만들기 위해 어떤 화면이 필요한지 생각해 봤습니다 이번 시간에는 이 화면들을 구성 해 볼텐데요 이런 화면 구성을 뭐라고 부를까요 바로 UI 라고 부릅니다 많이 들어는 보셨을 텐데 정확히 아시나요 UI 란 유저 인터페이스, 즉 사용자가 프로그램과 의사소통 하기 위한 매개체입니다 쉽게 말해 컴퓨터에게 사람의 말과 행동으로 입출력하게 해준다는 말입니다 그럼 본격적으로 UI 들을 구성해 보겠습니다 먼저 상세화면 부터 구성 해볼까요 주요기능은 한 사람의 입력된 정보를 모두 보여주는 화면입니다 구성 요소로 이름, 사진, 전화번호, 이메일, 인스타그램, 메모 정도를 사용 하도록 하죠 여기서 잠깐! 그런데 대체 UI는 어떻게 만드는 걸까요? 안드로이드는 각각의 UI 를 모듈 형태로 제공하고 있습니다

프로그램으로 끼워 맞추고 조작하면 됩니다 쉽게 말하면 종이에 사진을 올리고 를 쓰듯이 안된다는 거죠 여기서 빈 종이에 역할을 하는 것을 레이아웃이라고 합니다 내부에 여러 요소를 놓을 수 있죠 레이아웃에 놓을 요소들은 뷰가 담당합니다 안드로이드는 여러가지 형태의 뷰를 구현하여 제공하고 있습니다 그럼 다시 상세화면 구성으로 돌아와 봅시다 레이아웃의 프로필 사진, 별칭과 이름, 전 화번호, 인스타그램, 이메일, 메모 순으로 뷰를 놓아 보죠

왜 이렇게 배치 했을까요 UI은 사람이 인지하는 순서대로 중요한 요소를 배치해야 합니다 읽어야 하는 요소들은 책을 읽을 때처럼 좌측 상단에서 우측 하단 순으로 배치하는 것이 편합니다 그럼 방금 상세 화면을 구성하는 데는 어떤 뷰들이 사용된 지 알아볼까요 이미지 파일을 표시하는 ImageView, 그리고 글자를 표시하는 TextView를 사용했습니다 다음은 입력화면을 구성해 봅시다 입력하면 은 상세 화면에서 각 항목을 입력으로 바꿔주면 됩니다 한번 바꿔 볼까요 프로필 사진, 별칭과 이름, 전화번호, 인스타그램, 이메일, 메모까지 입력 창 으로 변경합니다

사진 위치에 대체될 카메라 아이콘은 사진을 선택하는 버튼으로 사용할 겁니다 입력 화면에서 글자를 입력하기 위한 뷰가 추가된 것을 보셨죠 글자를 입력하는 뷰를 EditText 라고 합니다 마지막은 목록 화면을 구성 해야겠죠 목록화면은 결과부터 확인해 볼까요 앞서 입력했던 내용을 명함 형태로 만들어서 레이아웃에 차례로 배치해봅니다 참쉽죠 앞서 종이 역할을 레이아웃이 한다고 설명 드렸죠 여기서 사용되는 레이아웃은 앞선 두 화면 과는 다릅니다 그건 바로 동일한 형태의 레이아웃을 목록 형태로 여러개 늘어놓는 점입니다 앞선 두 화면처럼 자유롭게 배치하는 경우에는 RelativeLayout을 목록화면처럼 반복적으로 뷰을 배치하는 경우에는 RecyclerView를 사용합니다 그럼 처음부터 다시 목록 화면을 만들어 볼까요

먼저 명함역할의 빈 RelativeLayout을 준비합니다 사진 이름 전화번호 인스타그램 이메일 정도로 요약하면 되겠죠 다음은 RecyclerView에 명함을 차례로 배치 해봅시다 이렇게 입력화면, 상세화면, 목록화면이 모두 완성되었습니다 오늘의 키포인트는 3가지! 종이의 역할을 하는 것은 Layout 요소의 역할을 하는 것은 View 라고 한다는 점

레이아웃에 뷰를 마음대로 배치하고 싶을때는 RelativeLayout 반복적으로 배치하고 싶을 때는 RecyclerView를 사용한다는 점 그리고 오늘 사용한 뷰는 ImageView, TextView, EditText가 있었다는 점을 기억하세요 다음 시간에는 pc에 안드로이드 를 개발하는 개발 도구를 설치하는 방법을 같이 알아보도록 하겠습니다 구독과 좋아요 부탁드릴게요

GOTO 2016 • Exploring RxJava 2 for Android • Jake Wharton

(음악) 좋아요, 일단 시작하기에 앞서서 이 질문을 던져보죠, 얼마나 많은 사람들이 RxJava이 무엇인지 대해 알고 있을까요? 또, 얼마나 많은 사람들이 그들의 앱에 RxJava를 적용하고 있을까요? 좋아요 Android에서 왜 reactive 가 중요해지고 있는지에 대해 얘기하면서 시작해보려고 합니다

그리고 왜 reactive적으로 생각하는 것이 중요한지에 대해서 얘기할 것이고, 그리고 나서 RxJava에 대해 본격적으로 얘기해볼거에요 또, RxJava가 어떻게 우리들의 앱에 도움이 되는지 알아보도록 하죠 한달 내로 출시될 예정인 RxJava 2를 적용한 명확한 예제들을 좀 보여드릴거에요 좋아요, 일단 왜 갑자기 Reactive라는 것이 화두가 되고 있을까요? 아마도 여러분은 사람들이 Reactive에 대해 말하는 것을 들은 적이 있거나, 혹은 실제로 적용하는 사람도 본적이 있을 것입니다 일단, 여러분들은 앱을 개발할 때 전체 시스템을 동기적으로 모델링하지 않는 한, 그저 단 하나의 비동기 코드 때문에 우리가 흔히 사용하는 전통적인 명령형 스타일 프로그래밍의 장점들이 완전히 부숴져버리는 것을 경험한 적이 있을 것입니다

부숴져버린다는 의미는, 앱이 동작하지 않게 된다는 의미는 아니고 시스템이 복잡해질 수 있다는 의미입니다 이렇게 되면, 명령형 프로그래밍의 좋은 장점들을 잃어버리게 됩니다 제가 생각하기에 이게 왜 정말 큰 문제가 될 수 있는지를 예제를 통해 보여드릴게요 사용자의 정보를 취해 User 객체를 반환하는 간단한 클래스로 시작해보죠 우리가 살고 있는 동기적인 세계 즉, 단일 스레드의 세상에서는 이 코드는 모든 것이 잘 작동합니다

우리가 기대한 대로 잘 작동할 겁니다 인스턴스를 만들고, 유저를 출력하고, 일부 프로퍼티를 변경하고, 다시 유저를 출력하고 우리가 기대했던 대로 잘 작동하죠 문제가 되는 부분은 비동기적인 방법으로 모델링할 때입니다 우리는 이 프로퍼티들을 변경할 때마다 프로퍼티의 변경사항을 서버에 반영할 필요가 있습니다 이제 여기 보이는 아래의 두 메소드는 비동기적일 필요가 있겠죠

이제 변경사항을 서버에 반영하려면, 어떻게 코드를 고쳐야 할까요? 이 상태에서 할 수 있는 것은 아무것도 없습니다 대부분의 사람들은 기본적으로 비동기 호출을 통해 서버에 정상적으로 변경사항을 반영하고 나면, 변경사항을 로컬하게(locally*) 만들 수 있을 것이라고 가정하곤 합니다 그리고 User 객체를 출력할 때에는 변경사항은 이미 즉각적으로 서버에 반영된 상태라고 생각하는 것이죠 물론, 이건 별로 좋은 생각이 아닙니다 네트워크라는 것은 신뢰할 수 없는데다가, 서버쪽에서는 에러를 반환할 수도 있습니다

그리고 지금 여러분은 User의 상태를 로컬하게 처리해야 하는 상황입니다 우리가 생각해볼 수 있는 한가지 방법은, 비동기 호출이 정상적으로 호출될 때마다 호출되는 Runnable 객체를 도입하는 것입니다 그리고 이제 우리는 보다 reactive적이게 되었습니다 데이터를 변경하면, 출력된 User의 정보를 통해 정상적으로 데이터가 변경되었음을 알 수 있게 되었습니다 하지만, 우리는 예기치않게 발생할 수 있는 문제들은 고려하지 않은 상태입니다

네트워크 연결이 실패한다거나 그런것 말이죠 따라서, 리스너를 도입할 수 있을 것입니다 에러가 발생하면 그에 따라 에러 처리를 할 수 있게 되었습니다 사용자에게 알려줄 수 있을 것이고, 다시 네트워크에 연결 시도를 할 수도 있겠죠 이 방식은 동작하는 데다가, 보통 대부분의 사람들이 비동기 코드를 안드로이드의 메인스레드인 단일 스레드에 동기적인 코드와 섞어 쓰는 방식이기도 합니다

그러나 생각해볼 수 있는 문제는 리스너에서 무언가 더 추가적으로 해야할 때, 예를 들어 User의 상태를 더 변경하는 등 추가적인 작업을 해야할 때입니다 앱의 입력 폼을 채울 여러 프로퍼티들이 있거나 또는 비동기 호출이 연계적으로 호출될 때가 있습니다(역: 콜백지옥*) 이 경우, 첫번째 콜백이 성공하면, 반드시 두번째 비동기 호출을 하게 되어 있습니다 두번째 호출은 성공 또는 실패일 수 있겠죠 여기서, 여러분은 현재 안드로이드 컨텍스트 내에 있음을 기억해야합니다

따라서 여러 추가적인 고려사항이 남아 있습니다 이 예제에서는 첫번째 콜백이 성공하면, 직접 UI에 대고 변경사항을 반영하고 있습니다 하지만, 아 죄송합니다 여기서 문제점은, 안드로이드의 액티비티는 언제라도 사라질 수 있다는 것입니다 앱이 강제종료됬거나, 전화를 받았거나 사용자가 홈버튼을 눌렀거나, 뒤로가기 버튼을 눌렀거나 그래서 만약 비동기 호출이 UI가 이미 소멸된 후에야 리턴하게 된다면, 다시 문제가 발생합니다 이 문제를 명령적인 방법으로 해결해보죠 뷰를 변경시키기 전에 상태를 검사해보는 것이죠, 나쁘지 않아 보입니다

우리는 또한 익명 타입 객체를 만들고 있는데, 이것은 결국 어느정도 짧은 메모리 누수를 일으킵니다 액티비티에 대한 참조를 보유하고 있기 때문에 액티비티가 사라졌을 때에도 백그라운드에서는 여전히 비동기 호출이 일어나는 것입니다 왜 이것이 정말 큰 문제인지 궁금하시면, 오늘 나중에 Pierre가 이 메모리 릭에 대해서 다룰 것입니다 가서 들어보실 것을 추천해드립니다 마지막으로 우리가 아직 다루지 않은 것은 이 콜백이 어떤 스레드에서 동작하냐 하는 것입니다

백그라운드 스레드로 돌아왔을 때, 명령적인 코드를 작성해야하는 것이 이제 우리가 해야할 일입니다 스레드로부터 메인스레드로 넘어가는 코드를 작성하는 것이죠 정말이지 어지러운 액티비티가 되었습니다 코드의 의도와는 정말 무관하게도 굉장히 부가적인 코드가 많이 있습니다 우리는 비동기 작업을 하는 간단한 코드와 그 비동기 결과를 핸들링하는 작업으로 시작했습니다

그저 비동기 호출을 하기 위해서 이 코드는 온갖 설정들로 가득차있습니다 우리는 단지 비동기 호출을 위해서, 폼, 버튼 등을 핸들링하고 싶지는 않았습니다 (역 :폼을 disable해둔다거나) 그러나 여기서 고작 이 작업을 위해 만들어진 코드를 보세요 그리고 실제 배포될 앱을 생각해보시면, 모든 이런 문제들은 더욱 복잡해질 것이고, 액티비티에서는 굉장히 많은 상태값들을 관리하고 검사해야할 것입니다 이 그림이 왜 리액티브적으로 생각해야하는 지를 보여줍니다

왜냐하면 여기의 모든 것은 근본적으로 어떤 방식으로든 비동기이기 때문입니다 네트워크가 있고, 우리는 요청을 보냅니다 그리고 충분히 많은 시간이 지나야 누군가의 응답이 도착합니다 이러한 이유로 메인 스레드를 블럭시켜버릴 수는 없습니다 그래서 이 과정은 백그라운드 스레드에서 일어나야 합니다

마찬가지로 파일 시스템도 그렇고, 스토리지에 값을 쓰기 위해 데이터베이스 또한 그렇고 심지어 SharedPreferences도 그렇습니다 우리는 메인스레드를 블럭시킬 수는 없기 때문에 이 작업들을 백그라운드 스레드에서 해야 합니다 "사용자" 자체 또한 비동기적입니다 우리는 UI에 데이타를 밀어 넣어 사용자에 보여주고, 사용자들은 버튼을 클릭해 그에 반응합니다 또는 텍스트 필드에 값을 변경하는 등 이러한 것들이 비동기적으로 일어납니다

사용자로부터 데이터를 빼내오는 것이 아니라 사용자가 데이터를 제공하기까지 기다리는 것이죠 이 그림은 근본적인 "UI"에 대해 생각해보게 합니다 많은 사람들은 메인 스레드인 단일 스레드만으로 모든 것을 할 수 있다고 생각하곤 합니다 하지만 실제로 UI 또한 비동기적으로 취급되어야 합니다 심지어 데이터 컴포넌트나 네트워크 컴포넌트를 가지고 있지 않을지라도, 사용자 자체는 비동기적입니다

우리는 사용자들의 입력에 대해 적절한 방식으로 반응해야 합니다 이 예제는 앱 전반에서 사용되는 데이터들이 실제로는 전혀 동기적으로 발생되지 않음을 보여줍니다 이러한 것들은 네트워크, 디스크, 사용자가 클릭버튼을 누르는 시간에 따라 발생됩니다 데이터들은 각기 다른 시간에 발생되어 앱 전반을 돌아다닙니다 그리고 앱은 반드시 그 데이터들을 받아들이고 적절하게 반응해야 하죠

따라서, 메인스레드를 블럭시키거나 또는 데이터가 비동기적으로 온다는 사실을 인지하지 못하고 작업하게 되면 앱은 데이터를 제대로 반영하지 못하거나 크래시를 일으킵니다 이 그림은, 우리의 코드가 이 모든 것들을 관리해야할 책임이 있음을 보여줍니다 하지만 그 책임을 위한 작업은 무척 복잡합니다 우리는 이 모든 상태를 액티비티, 프래그먼트 등에 갖고 있어야할 뿐만 아니라, 여러 데이터들이 비동기적으로 발생된다는 것을 감안하는 동시에 각각이 데이터를 생산하고 소비해가는 시간이 서로 다름도 인지하고 있어야 합니다 방금 전 그림은 안드로이드 자체는 고려하지 않았습니다만 안드로이드도 근본적으로 비동기적 플랫폼입니다

푸시 알림도 비동기적이며 시스템 도처에 브로드캐스트들도 그러하며 심지어 설정 변경 또한 그렇습니다, 사용자는 안드로이드 장치를 언제라도 회전시킬 수 있습니다 여러분의 코드가 "모든것은 비동기적이다"라는 사실을 인지하지 못한다면 앱이 크래쉬(crash)되거나, 앱이 오동작하기 시작하면서 일부 상태들이 앱을 완전히 멈추는 상황도 일어날 수 있습니다 다시 요점으로 돌아가보도록 하죠 이제는 하나의 비동기 소스가 결국에는 명령형 프로그래밍을 부숴버린다고 이야기할 수 있습니다 네트워크 요청을 가지고 있지 않은 앱은 찾기 어렵습니다

앱은 네트워크 요청들을 가지고 있으며 그 말은 즉슨, 안드로이드가 근본적으로 비동기적이라는 것입니다 디스크를 가지고 있으며 데이터베이스를 가지며, UI 또한 비동기적인 것이라고 간주되어야 합니다 그래서 기본적으로 안드로이드의 모든 것은 이미 비동기적입니다 따라서, 전통적인 명령형 프로그래밍과 여러 상태 관리 테크닉을 계속해서 추구하는 것은 여러분 자신을 힘들게 만들 겁니다 우리가 해야할 것은, 우리의 코드가 중간에 위치해 "상태"를 주재하며 비동기적인 모든 것들을 조정해야 함을 보여주는 이 모델 대신 비동기적인 것들을 직접 엮어야 하는 이 책임에서 벗어나는 방법을 택해야한다는 것입니다

그러면, UI가 직접 데이터베이스를 구독하도록 만들 수 있습니다 그리고 데이터베이스의 변경에 반응할 수도 있겠죠 데이터베이스의 데이터 변경과 네트워크 호출이 그저 사용자의 버튼 클릭에 반응하여 일어나도록 할 수 있습니다 유사하게, 네트워크 응답도 그렇습니다 데이터가 정상적으로 업데이트 되었다면, 데이터가 업데이트되었음을 알고 UI는 자동적으로 자신을 업데이트했으면 합니다

그래야 우리는 앞서 언급한 책임들을 제거하게 됩니다 장치가 회전하고, 브로드 캐스트를 보내는 등의 안드로이드 자체가 비동기적으로 뭔가를 한다면, UI는 자동적으로 반영하며, 백그라운드 잡은 시작 또는 중지되는 등 자동적으로 반응하게 될 수 있으면 좋을 것 같습니다 이렇게 되면, 우리는 어떤 상태들을 보유하기 위해 작성했던 많은 코드들을 제거할 수 있게 됩니다 우리는 여전히 코드를 작성하고 있으며 우리가 해야할 전부는 그저 각각의 비동기적인 것들을 합리적인 방식으로 연결하는 것 뿐입니다 그것들을 위한 상태 관리를 위해 애쓰지 않으며, 그저 이벤트를 발생하거나 소비하는 방식으로요

이제, RxJava에 대해 얘기해보겠습니다 이것은 사실상 안드로이드를 위한 리액티브 라이브러리가 되었는데 포괄적으로 자바에서도 이용가능했기 때문입니다 그리고 RxJava2도 마찬가지인데 왜냐하면 안드로이드에서 필요한 자바의 구버전을 지원하고 있기 때문입니다 (역: RxJava는 Java6 이상을 지원하고, 안드로이드는 Java7 까지 지원한다) RxJava는 세가지 중요한 것들을 제공합니다

첫번째로, 데이터의 소스들을 표현하는 타입들의 집합입니다 두번째로, 그 데이터를 구독해서 변경을 리스닝하는 타입들 집합입니다 마지막으로 가장 중요한 것은, 그 데이터들을 병합하고, 구성하고, 변형하는 메소드들인데 그 메소드들은, 서로 다른 데이터 소스들 사이를 연결하는 링크를 만들어서 구독해서 보여주기 원하는 최종 형태로 만들어줍니다 자, 이제 API는 어떤 모습인지 살펴보도록 하죠 데이터의 소스들은 자신이 구독되었을 때에 어떤 작업을 시작하거나 중지합니다

소스는 응답을 리스닝하기 전까지는 시작(fire)되지 않는 네트워크 요청처럼 생각하시면 됩니다 그리고 만약 데이터의 소스가 완료되기 전에 구독 해지되었다면, 네트워크 요청을 취소하는 등의 작업을 할 수 있습니다 소스는 동기적이거나 비동기적이 될 수도 있습니다 그래서 블럭킹되지만 백그라운드 스레드에서 동작하는 네트워크 요청같은 것을 모델링할 수도 있을 것입니다 또는 비동기적이 될 수 있는데 예를 들어, 안드로이드(API*)를 호출해서 액티비티에서 그 결과를 받아볼 수 있습니다

또는 UI에서 일어난 클릭 또한 비동기로 간주될 수 있습니다 여러분은 클릭을 기다리면서 블럭킹되지 않고 그저 클릭이 발생되었다는 사실에만 반응하면 됩니다 보통 단일 아이템을 생산할 수 있지만 많은 아이템들을 생산할 수도 있습니다 단일 요청에서 네트워크 응답은 하나의 아이템과 같지만, 버튼 클릭의 스트림 같은 경우에는 UI가 존재하는 한 무한할 수 있습니다 비록 단일 버튼을 구독했지만 말이에요

또한 아이템이 없을 수도 있습니다 예를 들어 오직 성공이냐 실패냐가 중요해서 실제로 아무런 아이템을 갖지 않는 경우 말이죠 즉, 데이터베이스나 파일 시스템에 값을 쓰는 경우를 생각해볼 수 있겠죠 실제로 아무런 응답이 필요 없습니다 아무런 아이템을 갖지 않고도 결과를 반환해줄 수 있습니다

그 결과는 성공이냐 실패냐를 나타낼 것입니다 성공이냐 실패냐에 대한 관점은 실제로 RxJava에 종료 이벤트라 부르는 것과 함께 데이터 소스에 모델링되어 있습니다 그 소스는 성공적으로 완료하거나 에러를 나타내고 종료될 수 있습니다 메소드가 정상적으로 리턴하거나 예외를 내며 리턴하는 경우를 떠올리시면 됩니다 전혀 종료되지 않을 수도 있습니다

다시 버튼 클릭 예제로 돌아가 생각하면, 버튼 클릭을 데이터의 소스로서 모델링해봅시다 UI가 사라지기 전까지는 전혀 끝나지 않는 버튼 클릭말이죠 UI가 사라졌을 때에는 여러분은 그 버튼클릭 소스로부터 구독을 해지할텐데 그럼 소스는 실제로 완료되지 않게 됩니다 실제로, 이 모든 부분들이 전통적인 옵저버 패턴의 구현이라고 볼 수 있습니다 우리는 데이터를 생산하는 생산자를 가지고 있으며, 우리는 데이터가 어떤 모습을 지니는 지 알고 있는 상태에서 생산자를 관찰하기 원합니다

따라서 우리는 생산자에 리스너를 등록합니다 그리고 생산자가 데이터를 생산하면 우리는 통지받습니다 소스를 나타내는 두 개의 주요 타입이 RxJava2에서는 Observable과 Flowable입니다 사실, 두 소스는 같은 종류의 데이터를 모델링합니다 소스는 0 나 N개의 아이템이 될 수 있으며 비어있을 수도 있고 물론 1개의 아이템이 될 수도 있습니다

물론 그보다 많을 수도 있습니다 그리고 성공적으로 종료할 수도 있고 에러가 발생해 종료할 수도 있습니다 왜 이 두 가지 타입이 같은 구조의 데이터를 나타내야 할까요? 여기서 너무 깊게 가고 싶지는 않지만, 배압(backpressure)이라는 것에 대해 얘기해봐야 합니다 복잡한 주제이기 때문에 배압이 무엇인지에 대해 차이점을 보여드리는 예제로 설명하겠습니다 배압은, 데이터 소스의 속도를 늦추도록 하는 것을 말합니다

여러분도 알겠지만, 우리는 제한된 자원을 갖는 시스템 하에 살고 있기 때문에 충분한 시간을 두고서 어떤 처리를 수행합니다 배압은 기본적으로 데이터를 보내는 쪽에게 너가 보내는 데이터가 너무 빨라서 더 이상 처리할 수 없으니 천천히 보내라고 얘기하는 것이라고 생각하면 됩니다 RxJava1은 배압을 갖고 있었지만 API 프로세스를 따르다보니 그 구현은 늦게 만들어졌습니다 그리고 시스템의 모든 타입은 배압을 갖고 있었습니다 대신에 RxJava2 에서는 두 가지 타입을 가집니다

이렇게 된 배경에는 당시에는 모든 타입이 배압을 갖고 있는 것처럼 보였기 때문에 모든 소스들이 실제로 배압을 구현한 것은 아니었음에도 배압이 가능할 것이라는 생각이 깔려있었기 때문이었습니다 그래서 결국 앱은 런타임에 크래쉬될 수밖에 없었습니다 배압은 미리 시간을 투자하여 상속처럼 실제로 설계가 되어야 하는 것이지, 나중으로 미뤄두었다가 믹스인될 수 있는 그런 것이 아니기 때문입니다 그래서 왜 RxJava2에서는 두가지 타입을 가져야하는 지 설명드리겠습니다 사용자는 타입 시스템을 통해서 배압이 지원되는지 아닌지 알 수 있어야 합니다

즉, 배압이 지원되지 않는다는 그 사실 자체는 그렇다 치더라도 사용자가 "API를 통해" 배압이 지원되지 않는다는 그 사실을 알 수 있도록 해야 합니다 이에 대해 예제를 하나 들어보자면, 터치이벤트와 같은 데이터 소스가 있다고 해봅시다 사용자는 손가락을 스크린에 대고 드래그할 것입니다 그리고 터치이벤트들을 발생시킵니다 여기서, 터치이벤트는 우리가 배압으로 속도를 제어할 수 있는 것이 아닙니다

실제로 사용자를 제어할 수는 없습니다 "곡선을 절반 정도로 그리고 내가 다 캐치할 때까지 기다려" "그리고나서 계속해서 나머지 커브를 그려" 이렇게 사용자를 제어할 수는 없습니다 하지만 다른 방식으로는 가능합니다 버튼을 클릭하지 못하도록 하거나 일단 다른 UI를 띄워서 데이터의 속도를 늦추는 것등입니다 그러나 데이터의 소스 자체는 그 데이터를 늦출 수 있는 대상은 아닌겁니다

여러 이벤트를 발생시키며 그려진 곡선이 이미 존재한다면, 시스템에게 그 데이터를 보내는 속도를 늦추라고 할 수는 없는 것이죠 데이터베이스를 예로 들어보겠습니다 우리는 많은 양의 데이터 결과 집합을 가지고 있고 우리는 한 순간에 특정 몇 행들만 가져오길 원합니다 "나는 첫 4개의 행만 원해" "알겠어" "이제 3개의 행을 더 줘" "알겠어" "이제 5개의 행을 더 줘" 데이터베이스는 이를 실제로 잘 모델링합니다 왜냐하면 커서라는 개념을 가지고 있기 때문입니다

하지만 터치 이벤트들의 스트림은 이를 전혀 모델링하지 못합니다 왜냐하면 이벤트를 미루거나 사용자의 손가락을 늦출 수는 없기 때문입니다 RxJava1에서는 두 가지 타입이 모두 Observable로 구현되었습니다 그래서 아마도 런타임에 배압을 적용해보려고 하다가 결국에는 예외발생으로 인해 앱이 크래쉬된 적이 있을 겁니다 그래서 RxJava2에서는 두가지타입으로 이를 모델링했습니다

하나는 배압을 지원하고 다른 하나는 그렇지 않죠 기본적으로 배압이 어떻게 동작할 지에 대한 전략을 적용하는 방법으로 이 두 가지를 서로 변환하는 방법들이 있습니다 하지만 여기서는 그 얘기를 하지는 않을겁니다 이들은 두 가지 서로 다른 타입이기 때문에 어떤 방법으로든 배압을 지원함을 드러내야합니다 하지만 이들은 모두 같은 종류의 데이터를 모델링하기 때문에 이들은 데이터가 어떻게 콜백에 푸시될 지에 관한 방법을 가지고 있어야 합니다

두 인터페이스는 소스로부터 이벤트를 듣는데 꽤 유사해보입니다 첫 번째 메소드는 onNext입니다 그리고 이것은 아이템을 전달받는 메소드이며 Observable 또는 Flowable에 의해 생산되는 아이템이 남아있는 한 이 메소드는 각각의 아이템이 적절하게 처리될 수 있도록 하기위해 매번 호출될 것입니다 이것은 또한 무한하게 호출될 수 있습니다 버튼 클릭과 같은 무한 Observable을 얘기했었습니다

만약 여러분들이 버튼 클릭을 구독한다면 이 메소드는 기본적으로 클릭이 일어날 때마다 호출될 것입니다 유한한 소스, 즉 실제로 끝이 있는 소스들을 위한 두가지의 종료 이벤트가 있습니다 둘 모두 완료될 수 있습니다 성공을 나타내는 완료와 에러를 나타내는 완료말이죠 에러는, onNext 콜백을 처리하는 도중 예외가 던져졌다는 뜻입니다

또는 데이터의 소스에서 이벤트를 구독하고 있다가 어떤 문제가 발생해 에러가 발생했다는 뜻입니다 onComplete와 onError는 모두 종료 이벤트라고 불립니다 즉, 이 둘 중 하나가 호출된다면, 더 이상 또 다른 콜백이 호출되지 않는다는 겁니다 마지막 메소드는 서로 다른데, onSubscribe입니다 RxJava1을 해보셨다면, 이 메소드는 처음 보실 겁니다

이는, 기본적으로 여러분이 Observable이나 Flowable을 구독했을 때 여러분은 실제로 어떤 리소스를 만들게 되는데 그리고 이 리소스들은 사용을 끝냈다면 종종 정리되어야 합니다 그리고 이 onSubscribe 콜백은 여러분이 Observable이나 Flowable을 구독했을 때 즉시 호출됩니다 그리고 파라미터로 어떤 타입을 전달해줍니다 Observable에서는 Disposable타입인데 이는 여러분으로 하여금 dispose 메서드를 호출해서, 자원을 모두 사용했다고 알리고 더 이상 콜백이 호출되는 걸 원치 않는다 말할 수 있도록 합니다 네트워크 요청을 생각해보면 이는 네트워크 요청을 취소하는 것이 될 수 있습니다

버튼 클릭의 무한 스트림을 리스닝 하고 있다면 이는 기본적으로 더 이상 버튼 클릭 이벤트를 받지 않는다고 말하는 것이며 그리고 이는 뷰에서 리스너를 제거하는 것이 됩니다 Flowable에 대해서도 마찬가지 입니다 다른 이름을 지녔지만 사용법은 같습니다 cancel메서드는 기본적으로 Disposable의 dispose와 같습니다 차이점이라면 Flowable은 request라는 또 다른 메소드를 가지고 있다는 것입니다

배압을 가지고 있다는 의미이죠 이 메소드는 얼마나 많은 아이템을 원하는지 Flowable에 명시하는데 사용합니다 서로 어떤 관계가 있는지 보여주는 간단한 차트를 보겠습니다 기본적으로 어떤 종류던지 간에 이벤트를 발생하는 것이면 모두 나타낼 수 있습니다 소스의 데이터는 0이거나 하나, 그 이상이거나, 그저 완료 또는 에러 가 될 수도 있습니다

이 두가지의 유일한 차이점은 배압을 가지느냐 아니냐입니다 빠르게, 왜 Disposable과 Subscription 타입 자체와 그들의 메소드가 서로 다른 이름을 갖는지 설명해보자면, 하나는 dispose, 다른것은 cancel인데 왜 어떤 하나가 다른 하나를 상속하게 해서 그냥 request 메소드를 추가시키지 않고 구별해 만들었을까요? 그 이유는 리액티브 스트림 명세라고 불리는 것이 존재하기 때문입니다 이것은 기본적으로 많은 벤더들의 저마다의 구현을 하나로 통합시키기 위한 것입니다, 말하자면, "자바에서 리액티브 라이브러리를 위한 인터페이스의 표준 집합을 만들어보자" "그리고 그걸 4개의 인터페이스로 만들어보자" 처럼 말이죠 Subscriber 타입이 보일겁니다 그리고 Subscription 타입도 중간에 보이고요

이들은 실제로 명세에 있는 부분입니다 그런데 아까 하나는 Disposable 타입이며 다른 하나는 Observer 타입인 것과는 이름이 다른데 여기 있는 이것들은 표준에 있는 부분이기 때문입니다 우리는 실제로 표준을 바꿀 수는 없었습니다 (역: 번역이 이상한 점 양해바랍니다) 그렇다 하더라도 이것은 표준이기 때문에 안드로이드에서는 빈번히 일어나는 일은 아니지만 만약 스트림을 위해 두 종류의 라이브러리를 사용해야 한다면 그리고 그 라이브러리들이 표준을 구현했다면, 매끄럽게 서로를 변환할 수 있게 해줍니다 이제 리액티브 스트림 명세를 구현한 실제 타입이 되도록 만들기 위해 왼쪽 컬럼을 바꿔보겠습니다

이제 이 타입은 배합을 지원함을 의미하게 되었습니다 그리고 오른쪽의 타입은 배합을 지원하지 않음을 나타냅니다 이제 다시 UserManager로 돌아가보면, 전까지는, 우리는 이 클래스 외부에서 User를 pull해갔습니다 그리고 그것을 출력했죠 그 때는 그게 적절해보였습니다

이제는 User의 Observable을 사용해 다시 모델링해보죠 이는 User객체의 소스를 의미합니다 User가 변경될 때마다 그 변경사항을 통지받습니다 그리고 그에 반응해 출력할 수 있습니다 적절한 시간이 되었는지 예측할 필요없이 시스템에서 발생한 다른 이벤트를 고려하지 않아도 됩니다

RxJava에는 특수한 소스들이 있습니다 그리고 이는 기본적으로 Observable의 서브셋입니다 그 중에는 세가지가 있는데, 첫번째로 Single입니다 단일 아이템을 가지거나 에러를 가집니다 따라서 스트림이라고 보기는 좀 그렇고 단일 아이템의 비동기 소스라고 보는 것이 적절합니다

그리고 배압을 갖지 않습니다 Scaler을 떠올리시면 좋습니다 메소드를 호출하면 값을 리턴하거나 예외를 던집니다 근본적으로 Single은 이 개념을 모델링합니다 Single을 구독하면 하나의 아이템을 내주거나 에러를 내줍니다

scaler와의 차이점은 리액티브적이라는 것입니다 Completable은 void 리턴타입의 메소드와 유사합니다 데이타 없이 완료하거나 예외를 던집니다 이를 reactive적인 Runnable로 생각하시면 좋습니다 성공적으로 완료되거나 실패하는 코드들을 가질테죠

RxJava2에서 새로 나온 타입인 Maybe입니다 아이템이 없거나 하나이며, 또는 에러를 가질 수 있습니다 Optional같은 것이라고 생각하시면 좋습니다 Optional 값을 리턴하는 메소드는 언제나 무언가를 리턴하지만 예외를 던지지 않았으면 Optional은 값을 가질 수도 아닐 수도 있습니다 잠시 후에 이게 사용되는 것을 보이겠습니다

리액티브적인 것만 제외한다면 Optional 개념과 유사합니다 RxJava2에는 실제 리액티브 스트림인 모델타입은 없습니다 리액티브 스트림들은 Observable이면서 배압이 없는 것으로 모델링 되었기 때문입니다 만약 우리의 setName과 setAge 호출이 비동기라면, 성공하던 실패하던, 아무런 데이터도 리턴하지 않을 것이고 그래서 반환형은 Completable 모델이 될 것입니다 이제 조금 빨리 살펴보도록 하겠습니다

어떻게 소스가 만들어지는지와 어떻게 리액티브 소스로 래핑할 수 있는지 보겠습니다 모든 타입들은 스칼라값들을 가지고 소스를 만드는 정적 메소드를 가집니다 또한 이렇게 배열을 가지고도 만들 수 있으며, 반복가능한 것이라면 뭐든지 가능합니다 제가 생각하기에, 동기 또는 비동기적으로 메소드와 그 메소드의 행위를 어댑트할 용도로 이상적으로 사용될 만한 두가지 경우가 있습니다 첫번째는 fromCallable입니다

fromCallable는 근본적으로 단일 값을 반환하는 동기적 행동을 모델링합니다 이 경우, 가상의 getName 메소드에 위임하는 모습인데요 fromCallable이 좋은 점은 callable에서 자바의 표준 예외를 던지는 것이 허용되기 때문에, Checked 예외를 사용해 실패하는 모델을 만들 수 있다는 점입니다 예를 들어 I/O 예외를 던질 가능성이 있는 HTTP 요청을 가지고 있다고 합시다, 우리는 이제 그 HTTP 요청 호출을 fromCallable에 넣을 수 있고 구독하게 되면, 반환된 Observable은 그 요청을 실행할 것입니다 만약 요청이 예외를 던졌다면 에러를 보게 될 것이며, 요청이 성공했다면 응답인 onNext를 받게 될 것입니다

fromCallable는 이 5개의 모든 타입에서 이용 가능합니다 이들은 데이터 단일 조각의 동기적 소스를 모델링하기 위한 것들입니다 명령적 세계에서는 리턴값을 반환하는 메소드가 될 것이며 리액티브 세계에서, fromCallable는 바로 그것을 모델링하기 위해 사용되는 것입니다 Maybe와 Completable에는 두 개의 추가적인 메소드가 있는데, 이들은 값을 리턴하지 않는 모델을 만들 수 있게 해줍니다 기본적으로 리액티브적인 Runnable이라고 생각하면 별 차이는 없습니다

Observable을 만드는 가장 강력한 메소드는 create입니다 RxJava1을 사용해봤다면 이 메소드를 알겠지만 RxJava1에서 절대 사용해서는 안될 무지 끔찍한 메소드입니다 이 점은 RxJava2에서는 수정되었고, 따라서 create 메소드는 정말 유용한 메소드들 중 하나가 되었습니다 그리고 소스들을 래핑할 때 사용되어져야 합니다 우리는 콜백과 함께 이 소스를 만들었습니다

이 콜백은 새로운 구독자가 생길 때마다 호출되는데, 그리고 Emitter라고 부르는 것을 제공받는데, Emitter는 기본적으로 구독하고 있는 쪽을 의미합니다 우리는 데이터를 취해서 Emitter에게 데이터를 보내줄 수 있습니다 이 예제에서 제가 하고 있는 것은, 데이터의 조각을 동기적으로 보내고 그리고나서 스트림을 완료하는 것입니다 이제 이를 람다로 변환해서 보일러플레이트들을 제거해보겠습니다 데이터 조각을 하나 더 보낼 수 있습니다

fromCallable과는 달리, 여러번 호출할 수 있습니다 Oh no! 또 다른 이점은, 우리는 이제 비동기적인 데이터 조각들을 모델링할 수 있다는 것입니다 만약 HTTP 요청들을 가지고 있고 동기적으로 실행시키는 것이 아니고, 비동기적으로 실행시킨다면, HTTP 콜백에서 Emitter의 onNext를 호출할 수 있습니다 create 메소드의 또 다른 이점은 구독이 해지되었을 때 뭔가를 할 수 있도록 한다는 점입니다 예를 들어 누군가 HTTP 요청을 구독하는 것을 취소한다면, 계속 요청이 실행될 필요는 없습니다

우리는 이제 HTTP 요청을 취소하고 리소스를 정리하는 취소 액션을 추가할 수 있습니다 이는 안드로이드에서 정말 유용한데, 왜냐하면 이것이 UI와의 상호작용을 모델링하는 방법이기 때문입니다 Observable을 구독할 때 버튼 클릭을 리스닝하도록 할 수 있으며 구독을 취소했다면 해당 리스너를 제거할 수 있습니다 그래야 뷰에 대한 레퍼런스를 누수하는 일이 없습니다 이 Emitter를 이용하는 Observable을 만드는 것은 다섯 개의 모든 타입에서 동작합니다

소스를 리스닝하는 것을 빠르게 봅시다 앞서 이 두개의 인터페이스를 보였습니다 그리고 이 네번째 메소드도 보였습니다 이 네번째 메소드는 새롭지만 조금 요상합니다 subscribe 메소드를 사용해서 리스닝을 시작하여 Observable을 구독할 때에는 앞서 말한 그 두 인터페이스들을 직접 사용하지는 마세요

이 4번째 메소드 때문에, 여러분은 다음처럼 헤맬 수 있습니다 "음, 이 객체를 가지고 뭘해야되는거지?" "그리고 어떻게 구독을 취소하는거지?" 대신에, DisposableObserver타입을 사용하면 이것이 자동으로 4번째 메소드를 핸들링할 것이고 여러분이 Observable로부터 통지되는 것에만 관심을 가지면 되도록 해줍니다 하지만, 여기에서 어떻게 dispose 할까요? 콜백을 더 이상 가지고 있지 않다면, 어떻게 구독을 해지할까요? 어떻게 리소스가 정리되도록 할 수 있을까요? 한가지 방법은 DisposableObserver에 대한 참조를 가지고 있는 것입니다 실제로 이 타입은 Disposable을 구현하고 있어서, dispose 메소드를 호출 할 수 있고 따라서 여러분이 제어할 수 있도록 해줍니다 하지만 RxJava2에는 subscribeWith라는 새로운 메소드가 있습니다

이는 여러분이 RxJava1에서 사용했던 방식과 유사한 방식으로 사용하게 해주는데 dispose를 호출할 수 있는 타입을 반환합니다 RxJava1에서는 이를 Subscription이라고 불렀습니다 Flowable 에서도 Subscription으로 부릅니다만 Observable에서는 Disposable이라고 부릅니다 CompositeSubscription이 있었던 것처럼 CompositeDisposable이 있습니다 이것은 기본적으로, 여러분으로 하여금 복수 개의 스트림을 구독해서 그것들의 Disposable을 반환받도록 하는데, 이는 내부적으로 Disposable을 리스트형태로 가지고 있습니다

따라서 여러분은 단박에 복수 개의 스트림을 구독 취소할 수 있습니다 이는 안드로이드에서 자주보게 될겁니다 하나의 CompositeDisposable만 가지고 있어도 액티비티, 프래그먼트, 뭐가 됬건 onDestroy같은 적절한 라이프사이클 콜백 메소드에서 복수 개의 스트림을 한번에 구독을 취소시키므로 유용하기 때문입니다 옵저버를 사용하는 그러나 배압은 지원되지 않는 4개의 타입이 보이고요, 여기에는 하나의 Flowable이 보입니다 Flowable은 Disposable을 사용하지 않고 Subscription 콜백을 사용할지라도, RxJava2에서 제공하는 타입들은 여전히 같은 방식으로 사용할 수 있게 해줍니다

아무튼, 여러분은 이 모든 5개의 타입으로부터 Disposable을 반환받을 수 있습니다, 비록 Flowable은 조금 종류가 다른 것으로 취급되더라도요 이렇게 생각해보세요, 여러분은 파일이나 데이터베이스의 커서같은 어떤 자원을 가지고 있다고요 여러분은 파일 리소스를 정리할 방법이 없는 채로 파일을 오픈하지는 않을 겁니다 마찬가지로, 데이터베이스의 커서를 닫을 방법이 없는 채로 데이터베이스의 커서를 오픈하지는 않을 겁니다 즉, 구독을 해지시키는데 사용되는 Disposable을 관리하지 않을 생각이라면 절대 Observable을 구독하지 마세요

좋아요, 이제 정말 정말 빠르게 살펴봅시다 데이터를 구성하고 변경하는데 사용되는 방금 봤던 타입들의 메소드를 살펴봅시다 이 메소드들을 오퍼레이터라고 부르며, 기본적으로 세가지 일을 합니다 데이터를 병합하거나 조작하며, 스레딩 시멘틱(threading semantics)을 바꾸거나 방출을 시작하거나 중단합니다 처음 두개만 살펴보려고 합니다

지금까지, 동기적 메소드 호출과 같은 명령적인 것으로부터 리액티브적인 것으로 변모해가는 모습을 살펴본 것처럼, 오퍼레이터에 대한 설명도 마찬가지로 할 수 있습니다 이 접근법을 문자열에 적용해보면 여기 새로운 문자열을 반환해줍니다 (역: 동기적이라는 뜻) 리액티브 세상에서는, 역시 Observable을 사용할 것입니다 오퍼레이터를 사용해서 그 접근법을 적용해봅시다 이 경우에, map이 오퍼레이터입니다 이 오퍼레이터는 방출된 데이터를 우리로 하여금 그 접근법을 적용시켜서 새로운 유형의 데이터를 만들도록 해줍니다 이건 그냥 지나갈게요

우리가 처음에 정의했던 User 객체를 떠올려보시면, 콜백은 백그라운드 스레드에서 수행되고 그리고 메인스레드로 돌아와야 했습니다 그렇게 하기 위한 내장 연산자가 있습니다 이것은 여러분으로 하여금 그 일을 보다 선언적으로 하게 해줍니다 예를 들어 저는, Observable의 아이템 방출을 어떤 다른 스레드에서 관찰하고 싶습니다 따라서 저는, 이 user로부터 반환되는 것은 백그라운드 스레드에 있게 되지만, mainThreadUser로부터 반환되는 것은 메인스레드에 있게 만들고 싶습니다

observeOn 오퍼레이터가 바로 그 일을 하게 해줍니다 스레드를 바꾸는 것이기 때문에 이들 오퍼레이터의 순서가 중요해지게 됩니다 observeOn과 유사하게, 옵저버블이 작동하는 지점을 바꿀 수 있습니다 저희가 네트워크 요청을 하는 경우를 생각해보죠, 그 네트워크 요청은 여전히 동기적으로 되고 있다고 합시다 하지만 그 요청이 메인스레드에서 수행되도록 하고 싶지는 않습니다

따라서, 우리는 이 오퍼레이터를 적용해서 옵저버블을 구독하는 지점을 바꾸도록 하면 됩니다 네트워크 요청은 완전히 그 바꾼 지점에서 일어나게 됩니다 따라서 우리가 backgroundResponse를 구독하기 시작하면 백그라운드 스레드로 바꾸게 됩니다io()는 여러분이 사용할 수 있는 스레드풀입니다

따라서 이 스레드풀에서 동작하게 될 것입니다 그리고나면 구독하고 있던 쪽에게 통지해줄겁니다 subscribeOn 오퍼레이터가 동작지점을 바꾸는 역할을 합니다 이게 좋은 이유는, 이것들은 새로운 옵저버블을 리턴하고 그리고 이 모든 메소드들은 옵저버블에 존재하기 때문에 그것들을 서로 구성하고 체이닝할 수 있기 때문입니다 이렇게 되면 보통, 이러한 작업을 위해 중간에 두어야 하는 임시적인 변수가 보시다시피 필요없게 됩니다

우리는 그저 오퍼레이터들을 특정 순서에 맞게 적용시켰을 뿐이죠 우리는 Response를 원아 죄송합니다, 우리는 백그라운드 스레드에서 요청이 실행되기를 원합니다 그리고 메인 스레드에서 요청의 결과가 관찰되기를 원하죠

그리고 응답을 보시다시피 이렇게 문자열로 바꿀 수 있죠 하지만 다시, 여기서 오퍼레이터의 순서가 중요합니다 map 오퍼레이터를 observeOn 이후에 배치했기 때문에 이는 안드로이드의 메인 스레드에서 동작하게 됩니다 우리는 메인스레드에서 HTTP 응답을 읽어오는 것을 원하지 않습니다 우리는 메인스레드로 바뀌기 이전에 응답을 읽어오기 원합니다

따라서, 요청을 보내고 나면, 옵저버블 체인을 따라 응답을 방출하고, 결과 문자열로 매핑하고, 그리고나서 메인스레드로 스레드를 바꾸고 결과를 UI에 보여줄 수 있게 됩니다 또 다른 오퍼레이터가 보이는데, flatMap은 생략하겠습니다 몇가지 다른 유형의 오퍼레이터를 보겠습니다, 여기 보이는 것들은 모두 Observable입니다 Observable을 취해서 다른 유형의 Observable로 반환해주는 오퍼레이터들이 있습니다 예를 들어 first 같은 오퍼레이터는 스트림에서 방출된 첫번째 엘리먼트를 취해서 반환해줄 것입니다

RxJava1에서는 첫번째 아이템을 방출한 옵저버블을 반환했습니다 (역: 그리고 하나의 아이템만 갖는다) 좀 이상해보입니다, 왜냐하면 만약 아이템의 리스트를 가지고 있는 상태에서 첫번째 아이템을 얻기 위해 get을 호출한다면 하나의 아이템을 갖는 리스트를 내주지 않기 때문입니다 반환되는 것은 하나의 요소 입니다 reactive 세상에서는 하나의 요소를 반환하도록 모델링하는 타입이 있습니다 그래서 RxJava2에서는 first 오퍼레이터를 호출하면 오직 하나의 요소만을 반환함을 보장하며 Single을 얻게 됩니다

만약 옵저버블이 비어있다면 예외를 발생시킬 것입니다 왜냐하면 Single은 에러 또는 하나의 아이템만을 가져야 하기 때문입니다 그리고 firstElement 오퍼레이터는 Maybe를 리턴합니다 옵저버블이 비어 있을 때, Maybe는 에러 없이 완료되는 경우를 모델링할 수 있습니다 만약 엘리먼트들은 무시하기를 원하고 그저 완료 또는 실패인지에만 관심이 있다면 Completable을 사용할 수 있는데, 이 오퍼레이터는 Completable을 리턴합니다

이것이 바로 Completable 모델입니다 이 모든 것들은 Flowable에도 존재합니다 따라서, 모두 같은 오퍼레이터를 가지며 모두 같은 특수한 타입들을 반환합니다 이 차트는 일부 오퍼레이터들의 종류별로 보여주는데, 윗 부분 오른쪽 구석을 보면 이쪽은 기본적으로 "좁은 타입"들입니다 따라서 여기 있는 것들을 호출하면, 예를 들어 스트림에서 아이템들의 수를 센다던지하면, 수치값은 언제나 Single이기 때문에 Single과 같은 좁은 타입을 얻게 됩니다

이 반대쪽에 있는 오퍼레이터를 보면, 어떤 타입을 받아서 그것을 좀더 넓게 만드는 타입들이 있습니다 예를 들어 Single을 취해서 Observable로 만드는것들 말입니다 좋습니다, 다시 기존 예제로 돌아가보겠습니다 이젠 리액티브적으로 할 수 있게 되었습니다 user를 구독하고, 메인 스레드에서 통지받기를 원하게 해놓고 그리고나서 UI에 밀어넣어 user를 보여줄 수 있습니다

언제든 user에 변경이 생기더라도 이 코드는 제대로 동작합니다 그리고 자동으로 업데이트되는 것도 볼 수 있습니다 더 이상 상태를 관리하느라 걱정하지 않아도 됩니다 그러나, 반환되는 Disposable을 관리해야함을 잊어서는 안됩니다 왜냐하면 안드로이드에서는, 액티비티가 사라졌을 때 이 코드 또한 멈추게 만들어야 하기 때문입니다

따라서 onDestroy에서 Disposable의 dispose를 호출해야 합니다 마찬가지로, 데이터를 변경하기 위해 비동기 요청을 만들 때에도 그 동작은 백그라운드에서 일어나기를 원하고, 결과는 메인스레드에서 관찰되기를 원합니다, 성공했던 실패했던 성공을 나타내는 콜백에서는 텍스트박스를 다시 입력가능하게 해놓는다던지 할 수 있습니다 다시 말하면, 여러분은 파일을 닫지 않을 거라면 파일을 열지 않을 것이기 때문에 Disposable을 관리할 수 없다면, 구독 또한 해서는 안됩니다 따라서 Disposable을 Disposable 리스트에 가지고 있도록 해야 합니다 시간이 별로 없기 때문에 좀 생략하겠습니다

하지만, RxJava1와 비교해 RxJava2에서 좋은 점은 근본적인 구조 변경이 있었다는 것입니다 이를 통해 특히 안드로이드에서 스트림을 만들 때 사용하게 되는 임시변수들의 수를 줄일 수 있게 되었습니다 호출하는 모든 오퍼레이터들은 각자의 행동을 구현하는 옵저버블을 리턴해야 합니다 map을 호출할 때는 어떤 함수를 적용시키고 새로운 데이터를 방출하는 옵저버블을 가지게 됩니다 이 때 수많은 객체들이 필요할 수 있습니다

스트림을 모델링하기 위해서 쓰이는 임시변수들 말이죠 RxJava2는 이렇게 만들어지는 임시 변수를 줄일 수 있도록 그 방식을 바꾸었습니다 Oops, I wanted to 스트림을 만들기 위해 오퍼레이터를 호출하기 위한 할당이 덜 일어나게 됩니다 각각은 하나씩 덜 오브젝트를 생성하므로 스트림을 구독할 때 오버헤드도 적게 되었습니다

동작하기 위한 메서드 디스패치도 줄었기에 가비지 컬렉션은 줄고 속도는 더 빨라졌습니다 따라서 API의 어떤 절충도 없이 라이브러리의 가바지 컬렉션도 줄게 되었습니다 따라서, RxJava2는 기본적으로 다음과 같은 아이디어를 갖고 있습니다 안드로이드에서는 근본적으로 비동기적인 것으로 간주되는 네트워크나 안드로이드 그 자체, 데이터베이스, 심지어 UI까지, 비동기 소스로서 모델링되는 것들을 취해서 이 소스들의 변경에 반응하는 코드를 작성하는 것입니다 그것들을 위한 상태를 관리하거나 변경을 처리할 필요가 없이 말이죠

현재 RxJava2는 개발자 프리뷰 릴리즈버전에 있고, API를 마무리해가고 있는 중입니다 한달내로 마지막 릴리즈가 나올 것입니다 그 때에는 이용가능해질 것입니다 즉, 이미 여러분의 앱에서 이용할 수는 있습니다 하지만 API가 바뀔 수는 있습니다, 그리고 파이널 릴리즈는 API를 더 강화합니다

그래야 라이브러리들이 이것을 사용할 수 있을 것이고 이 타입들을 노출시키기 시작할 것입니다 RxJava1을 사용하고 계신다면, 서로 변환할 수 있는 프로젝트가 실제로 있습니다 그리고 이것이 여러분의 앱을 점진적으로 업데이트하도록 해줄 것입니다 혹시 관심을 갖고 계신다면, 여기 링크를 참고하세요 gradle 디펜던시는 이와 같이 될 것입니다

마지막으로 하고 싶은 얘기는, RxJava2는 전혀 새로운 것이 아니라는 것입니다 리액티브 프로그래밍 또한 새로운 것이 아닙니다 하지만 안드로이드 그 자체로는, 어떤 이유에서건 매우 리액티브적인 세상입니다 우리는 꽤나 명령적이고 상태 중심적인 방식으로 모델링해왔고 이 비동기적인 것들을 관리하기 위해 많은 노력을 해왔습니다 그리고

리액티브 프로그래밍과 RxJava는 일반적으로 우리로 하여금 이러한 것들, 즉, 비동기적인 것들을 적절한 방식으로 다룰 수 있게 해주며, 상태들을 관리하느라 애쓸 필요가 없게 해주며 비동기적인 것들을 포용하고 함께 구성할 수 있도록 해줍니다 그러한 것으로서 우리의 앱은 진짜 리액티브적이게 됩니다 그리고 지금, 우리가 정말 관심을 가져야 할 것은 화살표가 어떻게 만들어지는지 인것이지, (역: 오퍼레이터들의 그래프들) 시스템 전반을 흐르는 데이터의 상태를 어떻게 관리할 것인지가 아니라는 것입니다 여기까지입니다 참석해주신 분들 모두 감사드립니다 (박수소리)

Introducing Gradle (Ep 2, Android Studio)

우즈텍 칼리킨스키:새로운 팀에 합류해서 급히 코딩을 하는 데 툴과 외부 라이브러리 준비가 오래 걸렸던 적이 있나요? 마감이 다가올 때 가장 싫은 건 프로젝트의 빌드에 시간이 걸리는 것이죠 안드로이드 스튜디오는 그래들을 기반으로 사용이 간단하고 효과적인 빌드시스템을 처음부터 생산적으로 쓰도록 해줍니다 관례를 구성보다 선호하며 이용자가 시작할 수 있게 기본값을 부여하며 라이브러리 관리, 멀티 APK 포함 지원 등 더 많은 고급사양을 허용합니다 몇 가지 예를 보여드리죠 빌드의 구성과 모든 프로젝트의 의존성은 직관적 선언형 구문을 사용한 그래들 빌드파일로 보존됩니다 이 파일들은 개발자 프로젝트의 단일소스입니다 다시말해, 여기의 모든 변화는 IDE에 자동적으로 반영되는데 예를 들어 코드의 완성은 항상 최신 프로젝트의 구성과 같습니다 나아가, 같은 개발파일은 그래들의 명령행에 사용될 수 있고 지속적인 통합서버와, 어떤 환경에서도 재생 가능한 개발을 일관되게 해 줍니다 안드로이드 이클립스를 수 년간 사용했다면 새 빌드시스템 학습이 큰 테스크일 수 있습니다 이클립스가 프로젝트를 받아들일 때 안드로이드 스튜디오는 그래들 파일을 자동생성하고 흔히 사용되는 라이브러리의 인식시에도 파일을 의존적으로 가져옵니다 앱의 기본적인 구성으로 어플리케이션ID SDK의 최소치와 대상, 버전 정보는 개발 파일의 디폴트 컨피그 섹션에 표시됩니다 프로젝트에 연관된 모든 로컬, 원격 라이브러리도 디펜던시 섹션에서 보실수 있습니다 만약 안드로이드 스튜디오가 파일을 불러올때 파일의 의존성 인식을 실패한 경우 또는 새로운 라이브러리의 추가만을 원하는 경우 Maven 검색 다이얼로그 사용하여 맞는 패키지 이름, 버전을 쉽게 찾을 수 있습니다 여전히 잘 모르겠고 단지 빨리 시작하고 싶다면 F [Compact]와 같은 유용한 라이브러리를 the Gradleplease 웹사이트에서 찾을수 있습니다 라이브러리를 만들거나 서드 파티 라이브러리를 사용할 때 또 다른 장애물은 코드와 함께하는 추가적인 안드로이드의 특정한 자원을 분배할 효율적인 방법의 부재입니다 디렉토리를 여기저기 옮기거나 자바클래스만을 포함하는 JAR파일로 제한해야만 했습니다 그래들과 함께 안드로이드 아카이브 포맷 보존파일방식, 안드로이드 아카이브 포멧 즉 AAR은 프로젝트 자원들, 자산, 분명한 목록까지 자족적인 라이브러리와 함께 발행하거나 첨부할 수 있습니다 안드로이드 스튜디오에는 라이브러리 관리 외에도 많은 것들이 있습니다 다중버전의 앱을 개발하고 이중코드와 다른 해결책에 당면 했던 적이 있나요? 그래들의 유연성과 함께라면 하나의 프로젝트에서 같은 어플리케이션으로 다양한 문서의 창조가 가능합니다 디버그하고, 기본값에 따른 개발타입을 출시하고 선택하고 싶은 취향의 제품과 함께 빌드 베리언트를 창조합니다 취향에 따른 타입과 제품의 개발은 매우 강력하고 맞춤이 가능한 컨셉입니다 예를 들어, 각각 개발된 타입으로 분리된 등록구성을 정의할 수 있고 무료와 유료 버전의 앱을 개발자가 플레이스토어에 업로드하고 싶을 때 그 전에 양측에 패키지 이름으로 알려진 어플리케이션 ID를 쉽게 무효화 할 수 있습니다 게다가 각각의 다른 타입과 취향의 문서도 각자 고유의 코드 및 자원 일부를 포함하고 이것이 메인코드 베이스와 합쳐집니다 추가권한의 명시도 가능하며 구성요소와 매니페스트 세팅의 무효도 가능한데 특정한 취향만을 원하는 경우에 한 합니다 플레이스토어에서 이 장치를 multi-APK 서포트와 함께 써서 특정한 장치의 APKs를 다른 화면밀도, CPU타입 API 레벨에 따라 창조, 발행할 수 있습니다 여기서 중요한 건 개발자의 경험이 늘어나고 사용자의 다운로드 크기가 작다는 겁니다 배리언트로 작업할 때 안드로이드 스튜디오는 현재 선택된 버전과 관련된 파일만을 프로젝트 개요에서 보여줍니다 원하는 버전으로 앱을 변경하기 위해서는 빌드 배리언트를 사용하세요 자동적으로 발생되는 모든 배리언트에 따른 개발 태스크도 그래들 사이드바에서 확인할 수 있습니다 개발하고자하는 모든 가능한 앱의 구조가 집합된 태스크를 사용하세요 보시다시피 안드로이드 스튜디오는 프로젝트의 관리에 따른 불편함을 덜어낸 현대의 강력한 개발시스템입니다 그래들의 가능성을 이제 찾아내기 시작했습니다 이 비디오에 대해 질문이 있다면 커뮤니티 Google+에 가입하세요 다음 비디오에서 곧 뵙겠습니다

Problemas al grabar vídeo con Android – Te contamos que es el Camera 2 API 🎥📲

Android 모바일 또는 태블릿에 동영상 녹화 응용 프로그램을 설치하고 초점이 작동하지 않거나 노출을 조절할 수 없습니다 이 비디오에서는 Android로 비디오를 녹화 할 때 몇 가지 문제를 알려 드리려고합니다 Camera2 API에 대해 알아야 할 사항 안녕하세요, 휴대 전화로 만든 동영상의 영토 친구, 나는 오스카 온 차이나입니다 elTallerAudiovisualcom에서 및 스페인어로 모바일과 비디오의 첫 온라인 학교 최종 사용자가 신경 쓰지 말아야 할 Camera2 API에 대해 말씀 드리겠습니다

그러나 결국 문제가 발생할 때 우리 일상에 몰래 들어간다 Android 휴대 전화로 동영상을 녹화 할 때 나는 이미 여러 번, 특히 유튜브와 페이스 북에서 직접, 안드로이드 수천 개의 다른 장치가 있기 때문에 매우 중요한 단편화 문제가 있습니다 이로 인해 개발자는 모든 응용 프로그램을 매우 어렵게 만듭니다 모든 장치에서 올바르게 작동합니다 음, 프로세서 이외의 경우, 메모리, 운영 체제의 버전, 또한 다른 변수를 방정식에 추가해야합니다

카메라 2 API는 몇 줄의 코드로 비디오 녹화 및 사진 촬영을위한 카메라 Camera 2 API는 Google Android 프로그래머가 개발했으며 프로그래밍 인터페이스입니다 응용 프로그램 개발자를 허용하는 지침을 포함하는 응용 프로그램 휴대 전화, 모바일 또는 태블릿의 운영 체제와 소프트웨어를 통신하십시오 MWC2015에 Android Lollipop v5로 남았습니다 모든 것이 정상적으로 진행되면 모든 휴대 전화 적어도 안드로이드 마쉬멜로 우 v6는 그것을 통합해야하지만,

이것은 사실이 아닙니다 우리는 파티에 간다 Camera2 API의 통합은 맞춤형 버전으로 제조업체에서 수행해야합니다

그들이 자신의 휴대폰에 설치하는 운영 체제의 당신이 삼성 폰의 안드로이드와 다른 브랜드의 안드로이드를 볼 때, 그들은 같은 버전의 안드로이드이긴하지만 그 모양이 다른가요? 음, 모든 제조업체가 Camera2 API, 각 모델을 완벽하게 통합하지는 않습니다 그것은 다를 수있다 필자는 4 가지 통합 수준에 대해 다음과 같이 언급했습니다 레거시 이는 이전 API Camera1의 기능 만 사용할 수 있음을 의미합니다

최대 제어 한계 자동으로 거의 모든 것 또는 모든 것 제한적

이것은 Camera2 API의 일부 기능이 장치에서 작동 함을 의미합니다 카메라 제어 기능을 거의 사용할 수 없습니다 전체 Camera2 API의 모든 기본 기능을 구현합니다 이것은 Cinema FV5, Filmic 및 기타와 같은 외부 녹음 응용 프로그램, 그들은 전화에 적절한 성능을 줄 수 있습니다 레벨 3, 레벨 3

완전한 팩 API가 제공하는 모든 옵션을 구현하여 캡처를 RAW로 최대화합니다 녹화 앱의 개발자가 최대한 활용할 수있는 방법은 여기에 있습니다 전화, 휴대 전화 또는 태블릿 카메라 물론 다음 질문은 다음과 같습니다 좋아, 내 통합 수준은 어떻습니까? Camera2 API가 있습니까? 대답은 일반적으로 다음과 같습니다 Nexus 또는 Google Pixel이있는 경우 통합이 완벽하므로 운영 체제를 만드는 마크가 적습니다

맞습니까? 나머지 장치 는요? 음, 정상적인 것은 플래그십 모델이나 최상위 레벨에서 전체 레벨로 구현을 찾는 것입니다 각 브랜드 범위의 삼성 S 시리즈, LG G 하지만 눈에는 예외가 있습니다

Huawei, Honor, Sony는 Camera 2 API를 외부 응용 프로그램 용으로 통합하지 않고 모델의 제한된 수준 또는 레거시 수준 Huawei P10과 같은 최고급 모델에서도 당신은 적어도 그 전화기의 네이티브 녹음 응용 프로그램에 감사해야합니다 일반적으로 그들은 당신이 특정 수동 제어 장치에 접근 할 수있게 해준다 내 장치에서 Camera2 API의 통합 수준을 확인하려면 어떻게합니까? Tobias Weis가 만든 2 대의 APPS, Camera2 Probe를 통해 나는 비디오의 설명과 우리가 eltalleraudiovisualcom에 쓴 글에 링크를 남겨 둡니다

목록의 링크도 있습니다 모델별로 구현 데이터가 조금씩 증가합니다 이 비디오에서 우리는 많은 호기심을 유발하는 주제로 탐구 해 왔습니다 Android 휴대 전화로 녹화하는 세계에서 블로그, eltalleraudiovisualcom, 등록 및 액세스에 대한 자세한 내용을 알고 싶다면 휴대 전화가있는 비디오 학교의 무료 콘텐츠에 공유하고 동영상을 공유하십시오

소셜 네트워크에서 그래서 우리는 우리 휴대폰으로 비디오를 만드는 사람들이 매일 더 많아 질 것입니다 다음 비디오까지