Understand Kotlin Coroutines on Android (Google I/O'19)

YIGIT BOYAR : 안녕하세요 모두들 환영합니다

내 이름은 Yigit Boyar입니다 저는 Android 팀의 엔지니어입니다 이봐 요, 제 이름은 세르게이입니다 그리고 저는 같은 팀에서 일합니다 숀 매 퀸런 : 안녕하세요, 저는 션입니다

나는 Android 개발자입니다 YIGIT BOYAR : 오늘 우리는 coroutines에 대해 이야기 할 것입니다 안드로이드에,하지만 우리가 그것에 대해 이야기하기 전에, 우리가 왜 일부 코 루틴을 필요로하는지 알아 내려고합시다 그리고 그것을 이해하기 위해, 어떻게 잊어 버립시 다 당신은 안드로이드에 AI 코드를 씁니다

이것이 우리가 작성하고자하는 꿈의 코드입니다 우리는 함수 호출은 네트워크 요청을합니다 도대체 무엇이 사용자를 얻고 텍스트 필드에 설정합니다 이것은 당신이 쓰고 싶은 것입니다,하지만 당신이 그것을 쓰면, 네트워크를 만들 수 없기 때문에 예외가 발생합니다

요청을 주 스레드에서 쉬운 우리는 코드를 스레드 안에 넣고 코드를 실행합니다 이제 textView가 불평 할 것입니다 백그라운드 스레드에서 UI 스레드를 만질 수는 없습니다

그리고 OK, 우리는 이런 종류의 코드를 작성할 것입니다 비동기로 만들 수 있습니다 콜백을 제공하고, 백그라운드 스레드에서 그립니다 UI 스레드에서 콜백을 호출합니다 이 코드는 코드를 작성하는 경우를 제외하고는 잘 작동합니다

이처럼, 당신은 메모리 부족 예외가 발생합니다 콜백을 왼쪽이나 오른쪽으로 새어 나올 것입니다 이것에 대한 해결책도있다 구독에 대한 이해를 가질 수있는 곳 이 체인을 유지합니다 그리고 당신이 멈 추면 언제든지 구독을 취소하십시오

그 중 하나가 작동하지만, 당신은 이런 식으로 끝납니다 그건 그렇고, 나는 이걸 만들지 않을거야 3 년 전, 우리가 Architecture Components를 시작했을 때, Google App 코드를보고있었습니다 그리고 나는 26 라인을 가진 하나의 어플리케이션을 발견했다 [INAUDIBLE]을 (를) 등록하십시오

Google에서 일어난다면 모든 곳에서 발생합니다 우리는 항상 최고의 코드를 작성하지는 않습니다 그러나 이것에 대한 해결책도 있습니다 RxJava와 같은 것을 사용한다면 이 함수는 관찰 할 수있는, AutoDispose 라이브러리를 사용할 수 있습니다 귀하의 [INAUDIBLE] 라이프 사이클과 연관된 가입 안전하게 가입하십시오

그리고 이것은 완벽하게 작동합니다 마찬가지로 LiveData를 사용할 수도 있습니다 관찰 할 수있는 생명주기가 있어야합니다 이것은 또한 작동합니다 그래서이 오래된 문제입니다, 그렇죠? 우리가 이미 여기에 대해서 이야기하는 이유는 무엇입니까? 좋은 해결책? 매년 우리는 이러한 개발자 벤치 마크 조사를 실시합니다

우리는 개발자들에게 그들이 어떻게 행동하는지, 그들의 문제는 무엇인지 물어 본다 그리고 작년에 우리가 조사한 설문 조사 중 최고 불만 중 하나 스레딩과 동시성이었다 개발자는 이것이 Android에서 어렵다고 말합니다 가장 큰 요청 중 하나는 바로 LiveData ++입니다 사람들은 우리가 LiveData를 확장하기를 원합니다

그것을 RxJava와 같이 만드십시오 우리는 왜 그런가? 왜 이걸 원하니? 우리에게는 좋은 해결책이 있습니다 그 중 하나만 사용하십시오 그래서 우리는 우리가 모를 때 최선을 다했습니다 우리는 UX 연구를 수행했습니다

이것은 동시성에 관한 User Experience Research입니다 그래서 우리는 9 명의 개발자와 심층 면접을했습니다 그들이하는 일은 부부를 위해 정규 일을하는 것입니다 자신의 회사에서 몇 주 그리고 동시성에 관한 문제를 볼 때마다, 이 관찰 가능한 것처럼, 그들은 단지 그것을 적어 둡니다

이것이 문제였습니다 이것이 내가 어떻게 해결했는지입니다 그리고 이것이 제가 그것에 대해 어떻게 느끼는지입니다 이 연구에서 우리는 세 가지 주요 사항에 초점을 맞추 었습니다 우리의 관찰 가능한 데이터 보유자 인 LiveData에 중점을 둡니다

우리는 RxJava에 중점을 두었습니다 우리는 Reactive Extensions 라이브러리를 보았습니다 그리고 coroutines는 정지 가능한 계산을 제공합니다 그리고 그 연구의 결과에서 이것은 결론이었습니다 LiveData는 사람들이 좋아한다고 말하면서, 그러나 우리는 완전한 해결책을 원합니다

사실 재밌 네요 LiveData는 메인 스레드 외에는 아무 것도 지원하지 않습니다 그러나 우리는 동시성 연구에서 그것에 대해 이야기합니다 RxJava의 경우 놀랍습니다 사람들은 그것을 사랑하고 싫어합니다

그들은 그것이 얼마나 강력한지를 좋아하지만 일반적인 불만 사항 우리는 항상 그것이 항상 잘못 사용되고 있다고 들었습니다 과잉 느낌 그리고 코 루틴의 경우, 이것은 정말 같았습니다 최상의 솔루션 인 것처럼 보이지만 확실하지 않습니다 그것은 아주 새롭다

성숙하지 않습니다 그래서 이것은 전반적인 결론이었습니다 우리는 단순한 솔루션이 필요하다고 말했습니다 그 해결책을 배우는 것이 어렵지 않아야합니다 포괄적이어야합니다

따라서 다양한 유스 케이스로 확장 할 수 있어야합니다 그리고 그것은 견고해야합니다 테스트 스토리가 내장되어 있어야합니다 그래서 우리는 두 가지 결정을 내 렸습니다 우리가 말했지, 좋아, 우리는 일류 품질 Jetpack의 지원

그리고 우리는 RxJava에 대한 더 많은 지원을 할 것입니다 우리의 문서에서 그러나 오늘날, 그것은 coroutines에 관한 전부입니다 션, 왜 우리 한테 조금 더 말하지 그래? 무슨 coroutines에 관하여? SEAN MCQUILLAN : 고마워요, Yigit 그래서 나는 단지 5 분 걸리고 싶다

코 루틴의 문제점에 대해 조금 이야기 해보십시오 위대한 해결 그래서, 문장에서, coroutines가 해결하는 주된 문제 콜백을 대체하여 비동기 프로그래밍을 단순화하고 있으며, 이것은 아주 추상적입니다 그럼 몇 가지 샘플을보고 어떻게 생겼는지 살펴 보겠습니다 나는 가상의 네트워크 요청을 세 가지 방법으로 만들 예정입니다

첫 번째 스타일은 차단 스타일이라고합니다 결과가 직접 반환됩니다 함수에서 실행 방법을 살펴 보겠습니다 그리고 재미있게, 나는 주 스레드에서 그것을 실행할 것입니다

호출 될 때, 블로킹 네트워크 콜 호출 한 스레드를 차단합니다 따라서 네트워크 요청이 실행되는 전체 시간, 주 스레드가 차단됩니다 UI를 업데이트해야하는 스레드입니다 사용자 접촉을 처리하므로 사용자 앱이 정지 된 것을 보거나 충돌 할 수 있습니다 이제 멈추고 거기에 있다고 말하고 싶습니다

네트워크 API의 차단 스타일에 아무런 문제가 없습니다 하지만 우리가 Android에서하고 싶은 것이 아닙니다 그래서, Yigit가 이미 이야기 한 것처럼, 우리는 일반적으로 콜백을 도입했습니다 그럼 어떻게 실행되는지 봅시다 우리는 여전히 메인 스레드에서 이것을 호출 할 것입니다

하지만 이제 fetchUser가 호출되면, 주 스레드는 자유롭게 다른 작업을 수행 할 수 있습니다 그것은 onDraw를 다루거나 사용자 접촉에 응답 할 수 있습니다 그리고 네트워킹 라이브러리는 실제로 요청을 실행하는 다른 스레드 결과가 준비되면 네트워크 라이브러리 내가 또 다른 콜백을 사용할 수있다 그것은 내 코드를 다시 호출하고 그것이 준비되었음을 알려주는 것입니다 정확히 같은 코드를 coroutines로 다시 작성해 보겠습니다

차단 스타일처럼 보입니다 fetchUser의 결과는 즉시 사용할 수 있습니다 콜백을 도입 할 필요가 없습니다 코 틀린에게 나는 코 루틴으로 이것을 실행하기를 원한다 이 함수에는 일시 중단 수정자가 있습니다

우리가 그것을 실행할 때 여전히 주 스레드에 있습니다 주 스레드는 콜백과 마찬가지로 차단 해제됩니다 그리고 이것은 coroutines의 핵심 개념입니다 네트워킹 요청은 여전히 ​​다른 스레드에서 실행됩니다 결과가 준비되면, 코 루틴을 다시 시작합니다 어디에서 멈췄다

이 코드는 콜백 스타일보다 훨씬 간단합니다 여전히 Android 앱을 작성할 수 있도록 보장합니다 사용자를 위해 동결하지 마십시오 이것은 코 루틴의 핵심 메커니즘입니다 일시 중지하고 다시 시작하십시오

코 루틴이 중지되면 실행되지 않습니다 일시 중지되었습니다 그리고 그것이 다시 시작될 때, 그것은 중단했던 곳에서부터 나아집니다 코 루틴을 콜백으로 일시 중지한다고 생각할 수 있습니다 나머지 기능들

그래서 당신은 그것을 함께 넣었습니다 일시 중지하고 다시 시작하십시오 콜백을 대체하십시오 우리는 심지어 그것을 시각화 할 수 있습니다 콜백 버전 및 코 루틴 버전 거의 똑같은 방식으로 실행됩니다

되돌아 가서 fetchUser를 살펴 보겠습니다 네트워크를 만드는 함수를 어떻게 호출 할 수 있습니까? 메인 스레드의 요청? 시작하려면 fetchUser를 만들어야합니다 또 다른 정지 기능 이것은 코 틀린에게 코 루틴과 함께 작동한다고 알려줍니다 그리고 내부에서 다른 정지 기능을 호출합니다

withContext를 호출합니다 우리는 그것을 dispatchersio에게 넘겨 줄 것이다 그 디스패처 확대, Kotlin 디폴트, IO 및 메인의 세 가지 디스패처를 제공합니다 그리고 그들은 다른 것들에 사용됩니다

CPU 집약적 인 작업에는 기본값을 사용해야합니다 100 가지 요소의 목록을 변형하는 것과 같은 것들, DiffUtil 호출 또는 사전 계산 텍스트 주 스레드에서 실행하기에는 너무 오래 걸리는 것이 있습니다 기본 발송자에서 실행해야합니다 IO는 네트워크를 차단하는 데 최적화 된 운영자입니다 디스크 IO

필요하면 언제든지 사용해야합니다 파일 쓰기와 같은 API를 차단하는 코드 작성 또는 소켓에서 읽는 중 그리고 메인 – 이것은 안드로이드의 주요 스레드입니다 그리고 놀랍게도, 그것은 우리의 추천입니다 응답으로 코 루틴을 시작할 수있는 적절한 장소 UI 이벤트

보통 코 루틴을 시작하기 때문에 메인 스레드에서 머무르다 간단한 조작을위한 추가 작업을 피할 것입니다 그런 다음 목록을 변형하거나 파일을 작성해야 할 때, coroutines를 사용하면 다른 Dispatcher 중 하나로 전환 할 수 있습니다 withContext를 사용하여 withContext는 전달한 블록을 실행합니다

운영자에게 말하십시오 여기이 블록은 디스패처에서 실행됩니다 네트워크 통화를 차단하는 것은 무료입니다 이를 통해 우리는 주요 안전 API를 제공 할 수 있습니다 당신은 단지 읽고 쓸 수있는 함수를 만들 수 있습니다

이 같은 네트워크에서 및 주 스레드에서 호출하십시오 Android에서 큰 이점입니다 이제는 모든 단일 기능에 대해 걱정할 필요가 없습니다 어떤 스레드가 실행될 필요가 있습니다 대신, 나는 단지 그것을 부를 수있다

기능 자체로 메인 쓰레드에서 호출하는 것이 안전하다는 것 코 루틴 소개를 끝내기 위해 Kotlin이 어떻게 구현하는지 살펴보십시오 모든 스레드에는 호출 스택이 있습니다 디버거 또는 스택 추적에서 볼 수 있습니다 Kotlin이 실행중인 기능을 추적하는 방법입니다

및 그 지역 변수 일시 중지 기능을 호출 할 때, Kotlin은 사실을 추적해야합니다 정규 함수 대신에 코 루틴을 실행합니다 이것을 서스펜션 마커로 나타낼 것입니다 서스펜드 마커 위에있는 모든 것은 코 루틴이됩니다

아래의 모든 것은 정규 기능입니다 그런 다음 Kotlin은 정상적인 기능처럼 loadUser를 호출합니다 스택 스택에 스택 항목을 넣을 것입니다 그리고 이것은 loadUser에 대한 지역 변수입니다 저장 될 것이다

그런 다음 발견 될 때까지 실행합니다 다른 일시 중단 함수 호출 이제 Kotlin은 일시 중지를 구현해야합니다 어떻게 그럴 수 있죠? 일단 당신이 그것을 이해하면 간단합니다 Kotlin이해야 할 일은 상태 복사입니다

함수를 스택에서 다음 위치로 옮긴다 그것은 나중에 저장할 수 있습니다 모든 중단 된 코 루틴을 여기에 넣을거야 스택과 같은 구조는 아닙니다 그런 다음 Kotlin은 실제로 fetchUser를 호출합니다

다른 스택 엔트리를 작성해, withContext를 호출하면 (자) 저것을 또한 중단한다 그래서이 시점에서 주 스레드의 모든 coroutine 일시 중지되었습니다 그리고 이것은 주 스레드가 onDraw 핸들과 같은 다른 작업을 수행 할 수 있습니다 또는 사용자 접촉에 응답 할 수 있습니다 그리고 이것은 정말로 중요합니다

스레드의 모든 coroutine이 일시 중단 된 경우, 스레드는 다른 작업을 수행 할 수 있습니다 우리가 몇 초 빨리 감기면, 네트워크 결과가 준비됩니다 그리고 코 틀린은 이력서에 전화해야합니다 그렇게하기 위해서는 저장 상태와 복사본 만 필요합니다 그것을 다시 스택에 놓고, 기능을 다시 시작합니다

loadUser를 다시 시작하면 계속해서 정상적으로 실행을 계속하십시오 loadUser가 오류가 발생하면 예외가 발생했습니다 바로 거기 중지 및 재개 메커니즘은 coroutines 뒤에있는 마법입니다 그리고 우리는 당신에게 그것을 보여주고 싶었습니다

그들이 당신처럼 일하는 방식을 이해할 수 있습니다 코드에서 사용하기 시작하십시오 그것은 coroutines 소개를 감쌌다 안드로이드의 코 루틴은 우리에게 능력을 제공합니다 콜백을 대체하여 코드를 단순화하는 방법 우리가 주요 안전을 만들어 보장 할 수 있도록 우리는 주 스레드를 차단하지 않습니다

이제 세르게이에게 넘겨 줄거야 누가 오늘 사용할 수있는 도서관에 대해 조금 이야기 할 것인가? coroutines와 함께 고마워, 션 그래, 그 스레드는 [INAUDIBLE],하지만 우리는 정말로 우리의 실제 적용에 도움이되고 싶습니다 그리고 매우 어린 코 루틴에도 불구하고, 이미 그들을 지원하는 도서관이있다

그들의 안정된 또는 더 나은 유물에서 WorkManager로 시작하겠습니다 AndroidX에서 우리에게 새로운 브랜드입니다 이미 안정적인 릴리스에서 코 루틴을 지원합니다 그리고 코 루틴 작업에도 사용할 수 있습니다

그러나 한 발 뒤로 물러나서 알아 내려고합시다 왜 그렇게하는지, 우리는 그것을 사용합니다 그래서 이것은 전형적인 노동자들의 흐름입니다 따라서 WorkManager에 익숙하지 않은 경우, 당신은 일종의 노동자라고 생각할 수 있습니다 그 긴 배경 직업 않습니다

몇 가지 제약이있을 수 있지만 매우 간단합니다 그냥 약간의 일 그 전형적인 유스 케이스, 당신은 일부 로컬 데이터를 웹 서버와 동기화해야합니다 그리고이 흐름이 너처럼 보일거야 데이터베이스에서 새 노드를 쿼리하고, 그런 다음 서버에 업로드하십시오

마지막으로, 해당 노드를 성공적으로 동기화 된 것으로 표시합니다 콜 루틴은 필요 없습니다 음, 실제로, 우리는 취소에 대해 이야기하기 시작하지 않았습니다 취소 사유는 여러 가지 이유로 발생할 수 있습니다 예를 들어이 작업자에 대한 제약 조건은 더 이상 충족되지 않습니다

UI를 제공 한 경우 사용자가이 작업을 명시 적으로 취소합니다 그러면 취소를 어떻게 지원할 수 있습니까? 음, 그런 식으로하려고 할 수 있습니다 ifCheck를 사용하여 다른 모든 줄을 넣으려고합니다 어리석은 것을보기 시작합니다 더군다나 실제로는 그렇지 않습니다

이 전화는 아마도 가장 비싼 전화 일 것입니다 네트워크에 연결되어 일부 작업을 수행하기 때문에, 취소 신호 전파가 없으므로, 그것이 시작 되었다면 무엇이든 상관없이 끝까지 달려 가라 그리고 이것은 실제로 노동자로 하여금 우리를 도울 것입니다 우리는 아직 그것에 대해 말하지 않았지만, 코 루틴은 콜백을 멋지게 잡아라 또한 좋은 cancellation 속성을 제공합니다

따라서 모든 일시 중지 기능을 취소 할 수 있습니다 이 취소에 대응할 수 있습니다 또한, 모든 내부 호출을 전파합니다 이 취소 신호 이러한 호출 내부의 코드가 여전히 차단되고 있다고 말할 수 있습니다

우리는 어쨌든 그로부터 이익을 얻지 못합니다 이것은 사실입니다 그러나 Room을 데이터베이스 솔루션으로 사용하는 경우, 쿼리를 일시 중지 기능으로 표시 할 수 있습니다 그리고 Room이 취소를 처리합니다 Sean이 여러 번 언급 한 것처럼 실을 꿰는 것뿐만 아니라, 이 일은 안전 할 것입니다

방은 스레딩을 처리합니다 그것은 배경 스레드에서 쿼리를 실행합니다 그럼, 우리 데이터베이스 호출은 지금 취소 할 수 있습니다 그러나 우리가 전에 논의한 것처럼, 주요 호출은 이것입니다 실제로 Retrofit을 사용하는 경우, Retrofit 이미 벌금을 부과 했으므로 일시 중지 할 수도 있습니다

네트워크 호출에 대한 일시 중지 식별자를 지원합니다 Retrofit을 강조하고 싶습니다 AndroidX에 포함되어 있지 않습니다 Android에서 설계된 자바입니다 다음에 Android를 사용하면 Android [INAUDIBLE]이 (가) 포용합니다

coroutines, 우리는 그것을 좋아한다 하루가 끝나면 우리에게는 일이 적습니다 좋은 이제이 코드는 취소를 지원합니다 그리고 이전처럼 쉽게 보입니다

그래서 우리는 무료로 취소를 받았습니다 그래서 이것들은 물건들에 대한 빠른 견해였습니다 오늘 이용 가능했습니다 그리고 Yigit은 우리가 방금 만든 많은 새로운 사람들을 당신에게 선물 할 것입니다 BOIGAR : 감사합니다, Sergey

그래서, 지금까지 우리는 코 루틴으로 할 수있는 것에 대해 이야기했습니다 그리고이 이야기의 나머지 부분을 위해, 우리는 새로운 것을 이야기 할 것입니다 그래서 첫 번째는 LiveData와 coroutines입니다 이제 매우 명확 해지기 위해 LiveData 동시성을 위해 설계되지 않았습니다 그것은 관찰 가능한 가치 보유자입니다

그리고 너는 접근 할 수있을 것으로 예상된다 메인 thread로부터의 값 그건 의도적 인거야 그러나 그것이 상호 운용 될 수 없다는 것을 의미하지는 않습니다 그래서 이것이 우리가 오늘 당신에게 제공 할 것입니다 coroutines와 함께 LiveData를 사용하는 쉬운 방법이있을 것입니다

따라서 가장 보편적 인 사용 사례는 가치가 있다는 것입니다 당신은 코 루틴에서 계산하기를 원합니다 결과를 LiveData로 제공하려고합니다 오늘 라이프 사이클 22 알파 01 유물로 시작하여, 이 새로운 API 인 LiveData를 얻습니다

따라서 시퀀스와 매우 유사한 빌더 함수입니다 Kotlin의 건축업자 그 안에 coroutines 블록을 전달합니다 그리고 안으로, 당신은 당신이 원하고 전화를 할 수 있습니다 이 함수는 값을 전달하는 함수를 내 보냅니다

따라서이 데이터베이스로드 기능을 보면, HLS [INAUDIBLE] 기능입니다 이 경우 사용자가 emit을 호출하기 때문에, 우리는 당신을 위해 그 타입을 추론 할 수 있습니다 이것을 지정해야합니다 따라서이 간단한 LiveData API 귀하의 LiveData 요소들 사이의 간격을 연결합니다 그리고 당신의 coroutines

이제 API에 대해 좀 더 자세히 살펴 보겠습니다 이것이 세 가지 매개 변수입니다 그리고 첫 번째 문맥입니다 그렇다면 우리는 왜 문맥이 필요한가? 이 데이터가 loadUser 함수라면, [INAUDIBLE] 기능은 일반적인 기능 이었지만, 이 코드를 작성하면 주 스레드 예외에 대한 IO를 수신하려면, 이 블록은 기본적으로이 그림의 메인에 그려지기 때문입니다 그러나 우리는 그것을 바꿀 수 있습니다

이 사진의 입출력과 같이 상황을 알릴 수 있습니다 이제이 코드는 완벽하게 작동합니다 너 한테 내가 변하지 않았 음을 알아줬으면한다 코드의 모든 내용 당신이 원하는 어떤 디스패처에서든지 내보낼 수 있습니다 값을 변경하기 위해 기본 Dispatcher에있을 필요는 없습니다

이제 두 번째 방법은 정말 어색한 매개 변수입니다 timeout이라고 불린다 시간 초과 매개 변수가 필요한 이유를 이해하려면 Android의 악명 높은 회전 문제를 살펴 보겠습니다 그래서 왼쪽에는 LiveData를 제공하는 ViewModel이 있습니다 그리고 오른쪽에는 활동 디스크가 있습니다

그래서 내 활동이 시작된 상태로가는 동안, LiveData가 활성화됩니다 확인을 의미합니다 사용자가 볼 수있는 관찰자입니다 일부 값을 만드는 것이 더 좋습니다 그러나 그 시간 동안 우리의 활동이 어떻게 변화합니까? 그래서 그것은 멈추게 될 것입니다

LiveData는 비활성 상태가되거나 파괴되거나, 새로운 활동이 올 것입니다 지금 당장은 LiveData를 관찰하는 사람이 없습니다 그래서 결과를 낼 이유가 없습니다 새로운 것을 다시 시작하는 것을 제외하고는, 다시 활성화됩니다 여기서 우리가 풀려고하는 문제는 이 차이는 LiveData 동안 신속하게 매우 빠르게 연속적으로 비활성화되고 활성화됩니다

보통 1 초 미만 어떻게 해결할 수 있을까요? 코드 블록을 어떻게 실행하는지 자세히 살펴 보겠습니다 더 잘 이해하기 위해 그냥 타이머 기능을 작성하려고합니다 기본적으로 LiveData 용 타이머를 만듭니다 현재 시간을 가져오고, LiveData 빌더를 반환하며, 그리고 무한 루프에서, 그것은 단지 방출한다

시간, 1 초 지연, 시간 방출, 지연 1 초, 결코 끝나지 않습니다 그리고 내가 보여주고있는이 코드는 100 % 쓸 수 있습니다 실제로 어떻게 작동합니까? 이 블록에 의해 반환 된 LiveData가 활성화되면, 우리는이 블록을 실행했는지 확인합니다 그리고 우리가 그 블록을 실행하지 않으면, 이제 실행을 시작합니다 우리가 그것을 실행하는 동안, 그 블록이 비활성화되면, LiveData가 비활성 상태가되면, OK,이 블록이 아직 실행 중입니다

그리고 아직 실행중인 경우 완료 할 시간을줍니다 그러나 타임 아웃 후에도 여전히 실행중인 경우 우리는 기본적으로 비활성 상태입니다 불필요한 계산입니다 LiveData를 관찰하는 사람은 아무도 없습니다 그러나 보드는 계속 달리고있다

그래서 우리는 단지 그 연속을 취소합니다 코 루틴 따라서 LiveData가 다시 활성화되면, 우리는 단지 그것을 재시작 할 것입니다 당신은 한번만 할 수 있습니다 그래서 완료되면, 거기 다시 시작할 이유가 없습니다

이제 하나 이상의 값을 방출 할 수 있습니다 이제 우리가 가지고 있던 샘플 주위에 구조를 만들자 getUser가있는 저장소가있는 곳 함수, loadUser 함수 및로드 해당 값을 내 보냅니다 자, 대부분의 경우, 이것은 작성한 코드가 아닙니다 웹 서비스로 이동하여 업데이트 된 사용자를 가져와야합니다

데이터베이스를 업데이트하고 해당 값을 다시 내 보냅니다 그래서 emit을 여러 번 호출 할 수 있습니다 당신이 그 격리 구역에있는 한 당신이 원하는대로 그러나 당신은 말할지도 모른다 음, 대부분의 경우 데이터베이스는 그렇지 않다

귀하의 사용자를 반환, 그것은 당신을 위해 LiveData를 반환 사용자, 당신이 변화에 대해 통보 받기를 원하기 때문입니다 글쎄, 여러분이 말할 수있는 것은 emit 소스를 호출 할 수 있다는 것입니다 MediatorLiveData를 사용하신다면, 이것은 emitSource와 매우 비슷합니다 LiveData에서 가져온 값이 무엇이든간에 그냥 내 가치로 만드십시오 변형과 같은 것을 실행할 수 있습니다

아, 우리도이 여분의 방출을 필요로하지 않습니다 우리가 이미 데이터베이스를 관찰하고 있기 때문에, 그래서 당신은 그것을 제거 할 수 있습니다 따라서이 LiveData API는 기본적으로 우리에게 제공합니다 coroutines와 함께 LiveData를 작동시키는 아주 좋은 방법입니다 하지만 ViewModels은 어떻습니까? SEAN MCQUILLAN : 고마워요, Yigit

코 루틴을 통합하는 방법에 대해 조금 이야기 해 봅시다 귀하의 ViewModel에 하지만, 우선 누출에 대해 조금 이야기하고 싶습니다 특히 코 루틴 누출 그리고 이것들은 매우 심각한 문제입니다

그들은 일종의 메모리 누출과 같아요 우리 모두가 잘 알고 있지만 더 나 빠졌다 코 루틴은 다시 시작될 수 있습니다 또한 메모리를 사용하는 것 외에도 CPU를 사용할 수 있습니다 파일을 쓸 수 있습니다

그것은 일어날 필요가없는 네트워크 요구를 만들 수 있습니다 코 루틴 누출 문제를 해결할 수 있도록, 코 틀린 (Kotlin)은 코 루틴 범위에 대한 아이디어를 소개했습니다 그렇다면 범위는 무엇입니까? 글쎄, 그것은 실제로 트랙을 유지하는 단지 방법이다 당신의 coroutines의 모든 코 루틴은 범위에서 실행해야합니다

그리고 범위는 모든 것을 취소 할 수있는 능력을 얻습니다 그것 안의 coroutines의 또한, 그들은 또한 장소입니다 코 루틴에서 잡히지 않은 예외가 섞여 버릴 수 있습니다 너는 그걸 모두 모으고 너는 범위를 사용하면 코 루틴을 누출하지 않도록 할 수 있습니다

Sergey가 말한 WorkManager는 범위를 제공합니다 Yigit이 방금 이야기 한 LiveData Builder도 마찬가지입니다 viewModelScope는 범위입니다 ViewModel의 KTX 라이브러리에서 멸종 속성입니다 나는 그 무서운 무한 루프의 다른 하나를 할 것이다

Yigit가 보여준 것들,하지만 이번에는 코 루틴에서 나는 ViewModel에서 시작한다 viewModelScope을 사용하여 스코프에 코 루틴을 시작합니다 그리고 기본적으로 이것은 메인에서 시작됩니다 그런 다음 무한 루프를 시작합니다

그 자체를 멈추는 법을 알아라 그리고 매 초마다 파일을 씁니다 이제 꽤 비쌉니다 코 루틴은 파일을 더 빨리 또는 더 빨리 작성하지 않으며, 우리는 분명히이 작업을 누설하고 싶지 않습니다 ViewModelScope를 사용하면 이와 같은 코드를 안전하게 작성할 수 있습니다

사용자가 화면에서 벗어날 때, 범위가 취소됩니다 이 매우 값 비싼 작업이 누출되지 않도록 보장합니다 따라서 viewModelScope는 코 루틴 누출을 방지 할 수 있습니다 모든 코 루틴을 보장함으로써 사용자가 화면을 떠날 때마다 취소됩니다 나는 세르게이에게 넘겨 줄거야

누가 우리가 추가하고있는 다른 영역에 대해서 이야기 할 것인가 세이지 바실리 네크 : 그래, 고마워, 션 네 자연스럽게 제공되는 또 다른 기능 범위는 라이프 사이클입니다 그 이름에서 시작과 끝이있는 것을 볼 수 있습니다

그리고 네가 생각한다면, 네, 그건이 수명주기에 익숙합니다 소유자 인터페이스, 당신은 실제로, 그것은 당신의 활동이기 때문입니다 그것은 당신의 단편입니다 그 단편을 편리하게 잊지 마라 두 개의 다른 라이프 사이클이 있습니다

그리고 두 번째 것은 – 우리는 그것의 내부를 사용합니다 불행히도, 저를 위해서, 저는 이제 그것에 대해 이야기해야합니다 그러나 거기에서 더 정확한 범위를 정의합시다 아시다시피, 당신의 단편은 다시 만들어집니다 구성 변경 사항 이상

따라서 수명이 더 짧아 질 수 있습니다 더 길 수 있습니다 그리고 lifecycleScope은 단지 그것을 반영합니다 라이프 사이클 소유자가 파괴 이벤트를 받으면, lifecycleScope가 취소됩니다 그리고 모든 내부 업무 또한 취소됩니다

따라서 알 수 있듯이 lifecycleScope UI와 매우 밀접하게 결합되어 있습니다 그리고 그것은 그런 상황에서 가장 잘 작동합니다 그래서 이전에, 당신은 뭔가를 할 것입니다 당신이 지연된 UI를 보여 주기로 결정했을 때 이런 식으로 그리고 이것은 꽤 간단 해 보입니다

그래서 우리는 조금 더 어렵게 만들 수 있습니다 두 단계가 있다면 이 심오함 때문에 아주 못 생겨 보입니다 그리고 실제로, 당신이 면밀한 관찰을 가지고가는 경우에, 이 mainHandler 때문에 실제 문제가 있습니다 그리고 UI에 닿는 기능은 실제로는 그렇지 않습니다 mainHandler가 함께하기 때문에 잘 작동합니다

GlobalScope의 일종입니다 라이프 사이클을 전혀 신경 쓰지 않습니다 그리고 그 함수들은 참조를 가지고 있습니다 파편이나 활동에 지연이 충분히 길다면 쉽게 많은 것들을 누출시킬 수 있고 그들로부터받을 수있다

그들의 예외 lifecycleScope는 이러한 코덱을 취소하지만, 그들은 우리에게 showFullHint입니다 일시 중지 기능이기 때문에 일종의 콜백입니다 [INAUDIBLE]에서 취소 할 것입니다 일단 당신의 라이프 사이클이 파괴되면

따라서 매우 순차적이기 때문에이 코드는 멋지게 보입니다 그리고 실제로 더 안전합니다 그러나 나는 lifecycleScope 약간의 위험 지대입니다 그러니 조금 되감습니다 나는 당신에게 개조 및 룸 지원을 보여준 사람이었습니다

일시 중단 기능 Yigit는 당신에게 뭔가를 보여 줬어 – 아주 친숙한 – 그런 것 같습니다 당신이 말할 때, 좋아, 나는 그 기능들을 결합 할 것이다 네트워크 및 데이터베이스에 대한 일부 저장소 패턴, 이제는 단 하나의 기능 만 사용할 수 있습니다 이 모든 작업을 조정하는 일시 중지 기능입니다

그래서 나는 그것을 호출하는 범위가 필요합니다 그렇다면 왜 내 수명주기에 그것을 부르지 않았을까요? 그것은 실제로 가장 밝은 아이디어는 아니지만 왜? 그리고 저를 잘못 이해하지 마십시오 Yigit와 Sean이 당신에게 모든 것을 올바르게 팔았습니다 주 스레드를 잠그지 않습니다

[INAUDIBLE]이 (가) 누출되지 않습니다 그러나, 당신은이 그림을 기억합니까? lifecycleScope가 취소되고 모든 구성이 변경됩니다 네트워크 요청이 발생 함을 의미합니다 매번 취소되므로 낭비가됩니다 사용자 자원과 리소스를 낭비하고 있습니다

환경에 좋지 않습니다 어떻게 제대로 할 수 있을지 음, 사실 중 하나가 Yigit에 의해 제시되었습니다 이 LiveData 빌더는 매우 잘 작동합니다 이런 상황에서

나는 당신에게 어떻게 접근 할 수 있는지 당신에게 보여줄 것입니다 이런 종류의 작업을위한 출발점 ViewModel 스코프입니다 따라서이 loadNote 함수를 실행하면됩니다 이 ViewModel 스코프 그런 다음 ViewModel에 함수를 도입했습니다 노트를 가져올 때 ViewModel에서 UI를 연결합니다

글쎄, 우리가 논의한 것처럼, 그것은 어딘가에있는 네트워크 호출입니다 의 loadNote 그래서 이것은 동기식 동작입니다 그래서 그것은 중단되어야합니다 그리고 이제는이 노드를 어떻게 든 연결해야합니다

하나의 범위에로드됩니다 그리고 loadNote 함수는 다른 범위에서 호출됩니다 글쎄, 나는 CompletableDeferred를 사용할 것이다 글쎄, 약간 무서운 것 같지만 실제로는 아주 간단한 것 잠시 후에보실 수 있습니다

우리가 어떻게 사용하는지 – 우리는 우리가 적재 한 메모와 함께 연기를 완료한다 그것은 단지이 오브젝트에 노트를 넣었습니다 아무 반응이 없습니다 그리고 독자는 무게 기능을 가진 주를 요구합니다 이걸 연기 했어 메모가 아직 준비되지 않은 경우 리더가 일시 중지됩니다

준비가되면 리더가 즉시 재개됩니다 이것이 우리가 ViewModel을 구현 한 방법입니다 그리고 마지막 단계에서 우리는 라이프 사이클 범위에서이를 호출합니다 ViewModel에서 소개 한이 loadNote 함수 그리고 우리의 네트워크 호출은 ViewModel에서 제대로 실행됩니다

범위이므로 구성 변경의 영향을받지 않습니다 그리고 우리의 업데이트 UI 기능은 수명주기 소유자가 파손되면 유출됩니다 그러나 일단 그림에 조각을 추가하면, 상황은 언제나처럼 복잡해집니다 그래서 우리는 조각 트랜잭션을 실행하기로 결정했습니다 그리고 합법적 인 주 예외를 받게됩니다

아무것도 보증하지 않기 때문에 조각을 실행할 수있는 올바른 상태에 있습니다 업무 그리고 우리는 뭔가 똑똑하고 도입했습니다 거래를 돕는 몇 가지 특수 기능 이런 종류의 상황들 그리고 이것은 약간 까다로울 것입니다

실제로는 상당히 복잡한 것 하지만 무슨 일을하는지,이 블록은 응용 프로그램이 시작되거나 다시 시작될 때, 그것이 전경에 있다는 것을 의미합니다 그리고이 블록은 귀하의 라이프 사이클이 막 생성되었습니다 자, 실제로 어떻게되는지에 대한 예를 살펴 보겠습니다 방법

그래서 당신은이 기능을 가지고 있습니다 아마도 처음에 불려집니다 메모가 준비되지 않았기 때문에 블록이 일시 중지됩니다 그런 다음, 일단 이것이 준비되면, 보통의 상황에서, 우리는 실행을 재개하고 다음 줄로 진행할 것입니다 그러나 launchWhenStarted 기능으로, 우리는 가서 라이프 사이클을 점검 할 것입니다

시작되지 않으면 Google은 수명주기가 끝날 때까지 다시 시작된다 일단 시작되면 우리는 다음 라인으로 진행 이 트랜잭션을 쉽게 실행할 수 있습니다 그래서 우리는이 예외적 인 상황에 처하지 않을 것입니다 그래서이 블록을 강조하고 싶습니다 생성 중에 일시 중지되었습니다

그리고 취소 된 것과는 다른 것입니다 lifecycleScope에 의해 취소가 여전히 제공되기 때문에 destroyEvent가 발생했습니다 그리고 지금, 당신이 볼 수 있듯이, 그것은 무언가입니다 우리가 시험 할 필요가있는 부분은 Sean이 도와 줄 것입니다 SEAN MCQUILLAN : 고마워요, Sergey

오늘 우리는 코 루틴에 대해 많은 이야기를 나눴습니다 API를 정리하는 방법에 대해 이야기했습니다 콜백을 대체하여 일시 중지했다가 다시 시작합니다 우리는 그들이 할 수있는 다양한 방법에 대해 이야기했습니다 다른 상황에서 사용됩니다

그리고 모든 것이 훌륭합니다 정말 끝내주는 군 그러나 그들이 시험하기가 어렵다면, 그저 비 스타터 일뿐입니다 그건 내가 진지하게 받아 들일만한 것이 아닐거야 사용할 물건으로

그래서 내가 너에게 옳은 얘기를하고 싶다 지금 Kotlinx-coroutines-test입니다 1 주일 반 전에 나왔던 새로운 도서관입니다 현재 실험용 coroutines API로 표시되어 있습니다 그것이하기 전에 더 많은 피드백이 필요하기 때문에 안정된 곳까지

Google과 JetBrain의 공동 작업입니다 안드로이드에서 coroutines를 테스트하는 것을 아주 쉽게 만들어줍니다 따라서 모든 테스트 라이브러리와 결합되지 않습니다 따라서 JUnit 4를 사용할 수 있습니다 JUnit 5를 사용할 수 있습니다

사용자가 작성한 사용자 정의 테스트 러너를 사용할 수 있습니다 그리고이 라이브러리는 코 루틴을 테스트하는 데 도움이 될 것입니다 그래서 저는 LiveData Builder에 집중할 것입니다 Yigit는 보여 주었다 그리고 우리는 그것을위한 테스트를 작성하는 방법에 대해 이야기 할 것입니다

그래서 나는 하나를 방출 할 것입니다 나는 잠깐 기다릴거야 그리고 나서 두 개를 방출 할 것입니다 이것은 비교적 간단한 LiveData입니다 그래서 나는 그것에 대한 테스트를 작성하는 방법에 집중할 수 있습니다

시작하려면 주 디스패처를 조롱해야합니다 LiveData Builder는 dispatchersmain을 사용합니다 기본적으로 Android의 실제 주 스레드입니다 테스트 코 루틴 디스패처로 대체 할 수 있습니다

특수 설계된 디스패처입니다 coroutines 테스트 그리고 우리는 테스트 코 루틴 범위를 만들 수 있습니다 이것은 코 루틴 테스트를위한 범위입니다 그러면 설치 프로그램에서 dispatchers

main을 전환 할 수 있습니다 테스트 발송자를위한 것입니다 dispatchersmain의 전역 값이 변경됩니다 즉시 LiveData Builder 우리가 제공 한 발송자를 사용할 것입니다

그런 다음 tearDown에서 resetMain을 기본값으로 설정하십시오 그리고 마지막 줄은 여기에 있습니다 정말로, 정말로 중요합니다 그것은 testScopecleanupTestCoroutines를 말합니다

운영자와 범위에 대해 생각하는 경우 하고있어, 그들은 매우 안정적이야, 맞지? 그들은 당신의 코 루틴을 추적해야합니다 실제로 실행합니다 이것을 부르지 않으면 매우 쉽습니다 검사 사이에 상태가 누출 될 수 있습니다 그래서 그것은 많은 상용구입니다

그래서 당신은 계속해서 함께 할 수 있습니다 어쩌면 JUnit 4 규칙 일 수도 있습니다 이것은 도서관에 없지만, 그러나 모든 코드를 규칙에 작성할 수 있습니다 그리고 저는 도서관을 볼 것으로 기대합니다 이것은 상대적으로 짧습니다

따라서 어떤 테스트 프레임 워크를 사용하든, 그러나 추상화를 구축해야합니다 그것은 당신의 테스트 프레임 워크에 적합합니다 그 코드를 할 수 있습니다 여기서 정의하는 규칙은 testCoroutineScope 인터페이스 runBlockingTest를 호출 할 수있게 해줍니다

이것은 테스트를 위해 최적화 된 코 루틴 빌더입니다 그것은 일종의 runBlocking처럼 작동합니다 그러나 그것은 많은 테스트를 쉽게 작성하게 만듭니다 오, 그러면 단위가 반환되므로 단일 표현으로 사용할 수 있습니다 스타일을 테스트합니다

그런 다음 주제를 얻습니다 그런 다음 LiveData 관찰을 시작해야합니다 그래서 실행됩니다 LiveData Builder가 실행되지 않는다는 것을 기억하십시오 누군가 그것을 관찰 할 때까지

observeForTesting이라는 작은 테스트 도우미를 정의 할 것입니다 이것은 내 테스트 코드 일 뿐이다 도서관 어디에도 없습니다 옵서버를 시작하려고합니다 내가 통과 한 블록을 호출하십시오

그리고 다시 시험에 첫 번째 값은 이미 방출되었습니다 이 테스트로 모든 것을 결정적으로 만들었 기 때문에 내가 사용하고있는 규칙 나는 [INAUDIBLE] 주장을 사용할 것이다 값이 1과 같아야하는지 확인하려면, 그리고 나서 나는 1 초씩 시간을 앞당길 것입니다

이것은 큰 장점 중 하나입니다 testCoroutineDispatcher의 가상 시간을 제어 할 수 있습니다 따라서 advancedTimeBy는 지연을 발생시킵니다 즉시 돌아온다 그리고 나는 내 시험에서 그것을 제어 할 수 있습니다

따라서 두 번째 방출은 이미 이 코드 줄을 읽었습니다 회전하고 결과를 기다릴 필요가 없습니다 그리고이 시험은 벗겨지지 않을 것입니다 나는 단지 제목을 말할 수 있습니다 값은 2와 같아야합니다

테스트를 통과하면 테스트를 통과합니다 테스트는 1 초가 아닌 즉시 실행됩니다 라이브러리를 확인해보십시오 당신이 찾은 버그는 반드시 제출하십시오 현재 실험중인 coroutines API로 표시되었습니다

그것이 안정을 높이기에 충분한 피드백을 가질 때까지 그리고 지금, 나는 마이크를 돌려 주겠다 이야기를 중단하기 위해 Yigit에게 BOYAR : 고마워, 션 좋아요,이게 너무 많아요

다음은 무엇입니까 그래서 오늘 우리는 당신이 어떻게 할 수 있는지 당신과 이야기합니다 AndroidX 및 기타 Android 라이브러리에서 동시 루틴을 사용하십시오 우리는 새로운 LiveData Builder를 도입했습니다 이를 통해 실제 데이터를 coroutines와 통합 할 수 있습니다

그리고 뷰 모델에 대한 새로운 라이프 사이클 기술 당신의 뷰 모델과 당신의 삶을위한 코 루틴 스코프 사이클 그런 다음이 새로운 기능을 도입했습니다 우리는 coroutines를 실행할 수있는 시작했다 귀하의 라이프 사이클 상태를 기반으로합니다

마지막으로 우리는 새로운 테스트를 도입했습니다 coroutines 용 라이브러리 그래서 오늘 일찍 우리는 코 틀린을 먼저 발표했습니다, Android 용 [INAUDIBLE] 및 Jetpack 용 그것은 coroutines보다 먼저입니다 이것은 권장 사항입니다 우리는 coroutines이 최상의 기능을 제공한다고 믿습니다

Android에서의 동시성 사용 용이성을 제공합니다 그러나 우리는 이것이 진행중인 작업임을 인정합니다 우리가 보여준 대부분의 도서관 실험적이거나 알파 하나, 우리는 지역 사회와 함께 이것을 발전시키고 자한다 건축 회사와 같은 방식으로 및 다른 Jetpack 라이브러리 그래서 우리와 함께하거나 6 개월을 기다릴 수 있습니다

그런 다음 사용을 시작하십시오 그리고이 일환으로 Kotlin이 점점 더 많이 보일 것입니다 제트 팩에서 나오는 코 루틴 따라서 이들 모두는 라이프 사이클 20에서 사용할 수 있습니다

01부터 오늘 시작하십시오 한번보세요 당신이 그것에 대해 어떻게 느끼는지 알려주십시오 또한 우리는 실제로 코 루틴을 좋아합니다 고맙습니다

[음악 재생]

Maps Live: Map Padding in the Google Maps Android API v2

안녕하세요 Google 개발자의 에피소드에 오신 것을 환영합니다

살고 있다 저는 Google Maps Developer Relations 팀의 Sarah Maddox입니다 지도를 사용하는 방법을 보여 드리겠습니다 Google Maps Android API로 패딩 지도가있는 애플리케이션이 있다고 가정 해 보겠습니다

사이드 바를지도에 추가하려면 하지만지도 UI 컨트롤이나 Google을 숨기고 싶지는 않습니다 심벌 마크 추가하면 어떻게되는지 봅시다 지도 패딩을 추가하지 않고 사이드 바를 만듭니다 이 작은 데모 응용 프로그램에는 오른쪽에 사이드 바가 있습니다

그리고 내 위치 컨트롤 찾기를 볼 수 있습니다 오른쪽 상단에 있지만 사이드 바에 의해 가려져 있습니다 마찬가지로지도 확대 / 축소 컨트롤 오른쪽 하단에 있으며 완전히 숨겨져 있습니다 그래서이 응용 프로그램으로 내가 한 일은 padded라는 버튼을 추가합니다 그리고 내가 덧대는 단추를 만지면, 응용 프로그램은 다음과 같은 메소드를 호출합니다

지도의 오른쪽에 30 픽셀의지도 패딩을 추가합니다 이제 UI 컨트롤이 멋지게 보입니다 내 사이드 ​​바 왼쪽에 약간 표시됩니다 지도는 여전히 전체보기를 사용합니다 그러나 사용자 컨트롤과 제스처 그들이 단지 사용하지 않는 것처럼 행동한다

지도의 더 작고 눈에 보이는 부분 그래서 내 위치 찾기 찾기를 탭할 것입니다 그리고 당신은 작은 파란색 위치 표시기가지도의 중심에 잘 배치되어 있습니다 지도 패딩을 고려했습니다 이제 정상적인 버튼을 누르면 내지도에서지도 패딩을 제거한 다음 내 위치 버튼을 다시 찾으십시오

위치 표시기가 약간 움직 였는지 확인하십시오 오른쪽으로 가면 중심에서 벗어난 것처럼 보입니다 전체지도를 고려하고 있기 때문입니다 보이는 부분 대신에 좋아, 나는 시드니를 만지고 위치를 잡을거야

호주 수학의 중심 그래서 주위에 멋진 푸른 바다가 많이 있습니다 그러면 Google 로고를 볼 수 있습니다 화면 왼쪽 하단에 있습니다 이제는 애플리케이션 요구 사항에 주목할 가치가 있습니다 Google 로고를 표시합니다

Google 로고가 숨겨져 있다면 Google지도의 서비스 약관을 준수하지 않음 아피스 따라서 UI 컨트롤을 왼쪽 하단에 추가해야하는 경우 맵의 패딩은 좋은 방법입니다 Google 로고가 나타나는지 확인하십시오 자, 코드를 살펴 보겠습니다 매우 간단합니다

Google지도 세트 패딩 사용 메서드를 사용하여지도 가장자리에 패딩을 추가합니다 이 메서드는 패딩을 결정하기 위해 네 개의 매개 변수를 사용합니다 왼쪽, 위쪽, 오른쪽 및 아래쪽 가장자리에 매개 변수 이름은 기억하기 쉽습니다 왼쪽, 위쪽, 오른쪽, 및 바닥 지도 재 센터링 (re-centering)과 같은 카메라 업데이트, 자동으로 패딩 처리됩니다

따라서 오프셋을 직접 계산할 필요가 없습니다 그리고 언제든지지도 패딩을 동적으로 변경할 수 있습니다 세부 사항은 문서에 있습니다 또한 Google지도 API 데모 앱을 살펴보십시오 Google Play 서비스와 함께 제공됩니다

다음은 데모에 대한 설명서 링크입니다 앱 그것은 내가 여러분에게 보여준 것보다 더 복잡한 예입니다 예를 들어, 애니메이션을 추가 할 수 있습니다 사이드 바를 안팎으로 밀어 넣을 수 있습니다

패딩 데모는 데모 앱에서 보이는 영역이라고합니다 메뉴 감사합니다 Google에서이 동영상을 즐기 셨기를 바랍니다 개발자 라이브

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과 비슷한 경험을 해 주셨으면합니다 좀 더 예측적이고 코딩이 더 재미있을 것입니다

고맙습니다 [음악 재생]

ExoPlayer: Flexible Media Playback for Android (Google I/O '17)

[음악 재생] OLIVER WOODMAN : 제 이름은 Ollie입니다 앤드류입니다

이곳에서 많은 사람들을 만나서 반갑습니다 나는 긴 하루 였음을 안다 그리고 오늘 우리는 당신에게 미디어 재생에 관해 이야기 할 것입니다 ExoPlayer를 사용하여 Android에서 우리가 다룰 내용에 관해서, 우리는 정말로 모든 사람들을 위해 약간의 노력을 기울일 것입니다

이 이야기에서 이것이 의미하는 것은 우리가 시작할 것입니다 몇 가지 기본 사항이 있습니다 그래서 우리는 ExoPlayer가 무엇인지 간략하게 논의 할 것입니다 우리는 몇 가지 기능에 대해 논의 할 것입니다

우리는 당신에 관해서 조금 이야기 할 것입니다 ExoPlayer를 사용하고 싶을 수도 있습니다 그리고 우리는 간단한 예제를 통해 어떻게 시작할 수 있는지 보여줍니다 그 후, 아마도 이미 더 많은 사람들을 위해 ExoPlayer에 익숙하다면 좀 더 진보 된 주제를 통해 아주 빨리 달릴 수 있습니다 그래서 우리는 미디어 구성에 대해 이야기 할 것입니다

ExoPlayer v2의 새로운 기능입니다 우리는 ExoPlayer의 내부에 대해 이야기 할 것입니다 어떻게 작동하는지 조금씩 설명하겠습니다 재생이 실제로 어떻게 작동하는지 설명합니다 그리고 마침내 우리는 그 지식을 바탕으로 우리가 어떻게 당신이 진짜로 주문을 받아서 만들 수 있는지에 대해서 이야기하기 시작할 것입니다

ExoPlayer가 일치하는 작업을 잘 수행하도록 미세 조정 특정 유스 케이스 좋아, 시작하자 ExoPlayer 란 무엇입니까? 따라서 ExoPlayer에 익숙하지 않은 사용자의 경우 이미 Android 용 미디어 재생 라이브러리입니다 그것은 Jelly Bean 이상에서 작동합니다 자바로 작성되었습니다

Android 개발자로서 이미 언어로되어 있습니다 네가 가장 잘 알고있는 것 ExoPlayer를 원할 경우 종속성으로 포함 시키십시오 다른 Java 라이브러리를 포함하는 것처럼 말입니다 또한 오픈 소스이기도합니다

그래서 만약 당신이 체크 아웃 영감을 이 이야기 후에 우리의 소스 코드, 당신은 쉽게 그것을 할 수 있습니다 그리고이 프레젠테이션의 마지막 슬라이드 실제로 GitHub 저장소에 대한 링크가 있습니다 기능면에서 우리는 먼 길을왔다 우리는 처음에 소스 ExoPlayer를 열었 기 때문에 2014 년 Google I / O에 돌아 왔습니다 초기 릴리스에서는 DASH 및 SmoothStreaming 적응 형 미디어 재생, 주로 조각 형식의 MP4를 컨테이너 형식으로 사용합니다

또한 TTML 캡션과 공통 암호화도 지원했습니다 그 후 우리는 지원을 추가했습니다 HLS 및 MPEG-TS 컨테이너 포맷의 경우, 추가 캡션 형식도 제공합니다 그 이후로 우리는 정말로 바빴습니다 더 많은 전통적인 미디어에 대한 지원 추가 MP3, MP4, Ogg 및 Matroska와 같은 형식을 지원합니다

우리는 또한 다른 여러 가지 확장 기능을 제공합니다 ExoPlayer 확장은 어떤 방법입니까? 다른 라이브러리의 기능을 ExoPlayer에 가져 오는 것 따라서 구체적인 예로서 OkHttp를 네트워킹으로 사용한다면 귀하의 응용 프로그램의 나머지 부분에 대한 스택, 실제로 똑같은 네트워킹을 사용하고 싶을 수도 있습니다 미디어 재생을위한 스택 그리고 OkHttp 확장 기능을 사용하여이를 수행 할 수 있습니다

그와 똑같은 네트워크 스택을 내부에서 사용할 수 있습니다 ExoPlayer 그래서 이것은 작년 중반까지 우리를 데려옵니다 그리고이 시점에서 우리는 좀 뒤로 물러났습니다 우리는 꽤 심오한 건축상의 변화를 만들었습니다

플레이어 내부 우리는 ExoPlayer 버전 2를 출시했습니다 이 릴리스에서 우리는 지원을 받았다 MultiPeriod DASH 지원과 같은 고급 기능을 사용하려면, gapless 오디오 및 미디어 구성, 우리가 아주 말할 게있는 것이지 한참 동안 많이

동시에 우리는 ExoPlayer를 사용하기 쉽게 만들려고 노력했습니다 그래서 우리는 간단한 ExoPlayer보기를 추가했습니다 죄송합니다 단순한 ExoPlayer는 다소 높은 수준입니다 ExoPlayer를 사용하기위한 API 및 일부 재생 UI 당신이 얻을 수있는 구성 요소 정말 빨리 상자에서 시작했습니다

그 이후로 우리는 더 많은 기능을 추가했습니다 특히 우리는 최근에 지원을 추가했습니다 가변 속도 재생 용 그리고 우리는 또한 우리의 능력을 키워 왔습니다 재생 된 미디어를 캐시 할 수 있습니다

그리고 이것은 오늘날 우리가있는 곳입니다 그리고이 슬라이드에서 가져온 핵심 요소 반드시 이해해야하는 것은 아닙니다 그 위에있는 모든 것 특정 유스 케이스에 맞는 것 같습니다 이 기능 중 아주 작은 하위 집합 만 있으면됩니다

여기에있는 주요 테이크 아웃은 실제로 ExoPlayer입니다 완전히 완벽한 기능을 갖춘 미디어 라이브러리로 진화했다 지금 Android 용 미디어 재생 사용 사례가있는 경우, 아마 ExoPlayer는 당신이하고 싶은 것을 지원할 것입니다 이제 우리는 거기에있는 특징들에 대해 조금 알고 있습니다

ExoPlayer를 사용하는 것이 적절한 지에 대해 이야기 해 봅시다 그리고 명백하게 대안을 사용하는 것이 의미가있을 때 ExoPlayer는 Android의 MediaPlayer API에 내장되어 있습니다 따라서 주목할 첫 번째 점은 MediaPlayer 다시 안드로이드 시작 부분까지 작동합니다 ExoPlayer는 Jelly Bean 이상입니다 이전보다 훨씬 적은 문제입니다

실제로 활성 Android 기기의 약 2 % 만 사용됩니다 아직 안드로이드의 이전 버전에서 그러나 제공에 대해 그 2 %에 대한 지속적인 지원을 한 다음 MediaPlayer 최선의 방법이 될 것입니다 사용 사례에 따라 이러한 솔루션 각각 MediaPlayer가 가장 적합합니다 간단한 사용 사례

그래서 MP3를 가지고 있다면 APK에 번들로 묶어 놓은 것일 수도 있습니다 앱 내에서 재생하려면 MediaPlayer를 당신을 위해 잘 작동 할 것입니다 어쩌면 당신은 이미 그것을 사용하고있을 것입니다 그리고 전환해야하는 실제 이유가 없습니다 ExoPlayer가 실제로 자체적으로 제공되는 곳 고급 사용 사례를위한 것입니다

DASH, SmoothStreaming을 포함한 모든 종류의 적응 형 스트리밍 및 HLS를 사용하고 실제로 일부 고급 기능을 활용하고자합니다 ExoPlayer는 미디어 구성 및 캐싱과 같은 기능을 제공합니다 염두에 두어야 할 또 다른 차이점 이 두 API가 설계된 방식입니다 MediaPlayer는 대단히 블랙 박스입니다 당신은 내부 동작에 대해 많은 통제력을 갖지 못합니다

플레이어의 반대로 ExoPlayer는 실제로 디자인되었습니다 매우 맞춤화되고 확장 가능해야합니다 그리고 당신은 정말로 발굴하고 시작할 수 있습니다 ExoPlayer 내부의 다양한 다이얼을 미세 조정하기 원하는 방식으로 일을 처리 할 수 ​​있습니다 그래서 ExoPlayer는 아마 당신이 아마 최고 일 것입니다

고급 사용자이고 이러한 것들을 조정할 수 있습니다 마지막으로 중요한 고려 사항 플레이어가 실제로 어디에 있는지의 차이를 고려하는 것입니다 MediaPlayer 및 ExoPlayer를 사용하면 오래 살 수 있습니다 따라서 MediaPlayer를 사용할 때, 왼쪽에서 볼 수 있듯이, MediaPlayer 구현은 실제로 안드로이드 운영체제에서 그리고 여기에있는 부분은 여러분이 보는 수평선입니다

아래는 운영체제입니다 ExoPlayer를 사용하면 실제 플레이어 구현은 응용 프로그램의 일부로 제공됩니다 그리고 그것은 정말로 아주 낮은 수준의 미디어로 전달됩니다 주로 액세스를 제공하기위한 플랫폼의 API 하드웨어 디코더 그렇다면 왜 이것이 중요한가? 한 가지 이유는 Android의 미디어 파워 실제로 시간이 지남에 따라 진화했다 그래서 그 결과로, 당신이 얻는 행동 Android 출시부터 Android 출시까지 약간 다를 수 있습니다

ExoPlayer와는 대조적으로, 우리는 장점이 있습니다 따라서 플레이어의 단일 버전을 배송 할 수 있습니다 응용 프로그램 내부 그리고 당신은 똑같은 버전을 얻을 것입니다 모든 버전의 Android에서 사용할 수 있습니다

ExoPlayer는 실제로 매우 일관된 경험을 제공하기 위해 더 좋은 위치에 있어야합니다 이 모델의 또 다른 중요한 이점 새 기능을 추가 할 때 일반적으로 ExoPlayer를 사용하여 Jelly Bean으로 되돌아가는 지원, MediaPlayer의 새로운 기능인 반면 후속 릴리스에서만 사용할 수 있습니다 Android의 이러한 이점에 대한 흥미로운 예 실제로 가변 속도 재생을 지원합니다 그래서 이것은 Marshmallow의 MediaPlayer에서 지원되었습니다 그리고 최근에는 ExoPlayer에서 지원을 추가했습니다

우리는 새로운 저수준에 대한 의존성이 없었기 때문에 미디어 API 또는 플랫폼의 모든 것, 우리는 Jelly Bean에게 지원을 추가 할 수있었습니다 우리가 다음에 발견 한 것은 실제로 재생 속도 및 피치 조정 구현의 버그 MediaPlayer와 ExoPlayer 모두에 영향을 미쳤습니다 그리고 우리는 그 버그를 다시 고칠 수있었습니다 ExoPlayer가있는 Jelly Bean으로 돌아 가면, MediaPlayer는 O 이상에서만 사용할 수 있습니다 그래서이 시점에서, 당신은 몇 가지 이점을 볼 수 있기를 바랍니다

ExoPlayer가 있습니다 하지만 너는 네가 그것을 사용하는 것이 더 확신 할 수있다 어떤 사람들이 이미 그것을 사용하고 있다는 것을 알고 있다면 그리고 우리가 실제로 ExoPlayer는 Google 자체 애플리케이션에서 매우 광범위하게 사용됩니다 가장 눈에 띄는 YouTube는 분명합니다

거대한 비디오 스트리밍 서비스 및 Google Play 무비 및 Google 포토와 같은 애플리케이션 실제로 우리는 실제로 강력한 채택을 보았습니다 넓은 개발 공동체에서도 마찬가지입니다 그래서 여기에 몇 가지 응용 프로그램이 있습니다 일부 ExoPlayer를 사용하거나 다른 용도로 사용할 수 있습니다 그리고 그것은 단지 어느 정도는 아닙니다

실제로 Play 스토어에는 140,000 개가 넘는 응용 프로그램이 있습니다 ExoPlayer를 사용하고 있습니다 앱 중 하나 인 경우 감사합니다 당신의 입양을 위해 그리고 우리에게 의견을 계속 보내주십시오 우리와 실제로는 정말 중요합니다

우리가하는 일을 많이 안내합니다 다음 번에는 몇 가지 코드로 다이빙을 할 것입니다 간단한 예를 보여줍니다 그 때문에 나는 너를 앤드류에게 넘기겠다 앤드루 루이스 : 안녕하세요

[박수 갈채] 기존 앱이 있다고 가정 해 보겠습니다 MP4 플레이어를 추가하고 싶습니다 그 응용 프로그램에 – 그래서 그냥 간단한 비디오를 보여주는 기존 앱에서 최소한의 변화를 겪을 것입니다 ExoPlayer를 사용해야합니다 첫 번째 단계는 ExoPlayer에 대한 의존성 그리고 두 가지 주요 옵션이 있습니다

이리 ExoPlayer 라이브러리 전체를 가져올 수도 있습니다 또한 적응 형 스트리밍 형식에 대한 지원도 포함됩니다 DASH 및 HLS와 유사합니다 그리고이 줄은 build

gradle 파일에서 사용할 수 있습니다 이것은 주방 싱크 옵션의 일종입니다 그래서 대안은 선택하고 선택할 수 있다는 것입니다 ExoPlayer 라이브러리의 특정 모듈 너는 필요해 이 예제에서는 종속성을 추가 할 것입니다

주요 플레이어가 포함 된 핵심 라이브러리 분명히 MP4와 같은 일반 미디어도 지원합니다 및 MP3 그리고 UI 라이브러리에는 여기에도 의존성이 있습니다 SimpleExoPlayerView를 가져옵니다 최소한이지만 사용자 정의 할 수있는 플레이어입니다

앱에 넣을 수 있습니다 그래서 우리가 의존성을 추가하면, 다음 단계는 일부 코드 스 니펫을 추가하는 것입니다 당신의 활동에, 그것은 플레이어를 창조하고 그것을 사용할 것입니다 그래서 우리는이 ExoPlayer 팩토리를 가지고 있습니다 여기에는 플레이어 인스턴스를 만드는 몇 가지 방법이 있습니다

그리고 이것을 사용하는 것이 가장 쉽습니다 컨텍스트와 트랙 선택기가 필요합니다 그리고이 간단한 사용 사례를 위해 우리는 DefaultTrackSelector를 사용합니다 당신이하고 싶은 거의 모든 것에 대해 합리적인 기본값을 가지고 있습니다 플레이어를 만든 후에는 다음 단계 앱 레이아웃에보기를 드롭하는 것입니다

setPlayer를 호출하여 플레이어에 바인딩합니다 방법 이제 가장 중요한 것은 플레이어에게 우리가 놀고 싶어 그리고 이것을 위해 우리는 MediaSource를 사용할 것입니다 ExoPlayer에서 재생할 수있는 모든 것은 MediaSource입니다

미디어 로딩을 담당합니다 플레이어에게 제공하는 것입니다 그래서 우리는 ExtractorMediaSource를 만들 것입니다 MP4, MP3, Matroska 파일 등이 있습니다 그래서 당신은 그것을 prepare 메소드에 넘깁니다

그리고 setPlayWhenReady를 호출합니다 플레이어에게 버퍼링이 완료 되 자마자 재생이 시작되면 재생이 시작됩니다 그리고 마침내 당신이 재생이 완료되면 플레이어 플레이어가 코덱과 같은 시스템 리소스를 보유하기 때문에 버퍼에 메모리를 사용합니다 따라서 이러한 코드 스 니펫은 일반적으로 앱의 활동 라이프 사이클 메소드로 이동하십시오 그래서 이것은 당신이 가진 것에 대한 비디오입니다

나는 런던의 스카이 라인에 대한 멋진 비디오를 가지고있다 기본 재생 기능이 있음을 알 수 있습니다 재생 및 일시 중지 단추 및 탐색 모음과 같은 컨트롤 그래서 이것을 시험해보고 싶다면, I / O의 일부로 코드 테이블이 게시됩니다 당신은 가서 시도 할 수 있습니다

개발자 가이드도 있습니다 우리의 프로젝트 페이지에서이 단계들을 안내 할 것입니다 제가 언급했듯이, 여러분이 할 수있는 모든 것 미디어 소스입니다 그리고 그것은 플레이어를위한 미디어를로드하는 책임이 있습니다 그리고이 예제에서는 ExtractorMediaSource를 사용했습니다

실제로는 다른 고급 미디어가 있습니다 소스를 사용할 수 있습니다 DASH에 대해 들어 보셨습니까? 스트리밍을위한 사양입니다 자질 간의 적응을 허용한다 다양한 네트워크 조건을 처리합니다

DASH 지원을 위해 DASHMediaSource를 제공합니다 우리는 또한 지원을위한 HLS 미디어 소스를 가지고 있습니다 HTTP 라이브 스트리밍과 SmoothStreaming을위한 미디어 소스 최근의 v2 릴리스에서는 또한 MediaSources의 새로운 카테고리를 추가했습니다 구성을 위해 설계되었습니다

그리고 구성에 의해 우리는 함께 합류하는 것을 의미합니다 다른 미디어 소스 왜 우리가 이것을하고 싶습니까? 글쎄, 나는 예제를 통해 갈 것이다 그럼 우리가하고 싶은 비디오가 있다고 가정 해 봅시다 또한 별도의 파일에있는 일부 자막은 SRT 파일

이 경우 ExtractorMediaSource를 만들 수 있습니다 비디오를로드하려면 단일 샘플 미디어 소스가 필요합니다 SRT 파일을로드하려고합니다 그리고 나서 비디오와 함께 자막을 재생할 것입니다 이제 너 스스로 시도하고 할 수있어

플레이어 위치를보고 및 재생 위치를 자막과 동기화하는 단계 당신이 보여주는거야 그러나 이것은 일반적으로 일반적으로하기가 실제로 어렵습니다 MergingMediaSource를 사용하는 것이 훨씬 쉽습니다 그리고 MergingMediaSource는 비디오를 가져옵니다 자막을 재생하고 싶다

당신을 위해 모든 것을 처리합니다 그래서 그것은 동기화를 처리 할 것입니다 그런 다음 플레이어에 표시됩니다 당신이 작곡을 사용할 또 다른 시간은 재생 목록을위한 것입니다 그래서이 경우에, 당신은 MP3의 앨범이 있다고 다시 재생하고 싶습니다

너 스스로 시도하고 할 수있어 첫 번째 스트림을 재생 한 다음 스왑 아웃하여 다음 소스 하지만 플레이어가이기 때문에 큰 일이 아닙니다 소스를 바꿀 때 버퍼링됩니다 그래서 우리는 ConcatenatingMediaSource를 추가했습니다, 어떤 소스의 목록을 당신이 걸립니다 함께 결합하고 그들을 연주하고 싶다

일관된 버퍼링 정책으로 백 – 투 – 백 따라서 플레이어에게 3 초의 미디어가 있다고 말하면 항상 버퍼링 된 다음에는 전환을 가로막는 경우에도 그러한 경우인지 확인하십시오 한 소스에서 다음 소스로 또한 gapless 재생 메타 데이터도 지원합니다 따라서 MP3 파일을 완전히 재생할 수 있습니다

원활한 재생 또한 구성도 매우 유연합니다 그래서 우리가 본 두 가지 예를 결합 할 수 있습니다 따라서 병합 된 소스와 동영상을 연결합니다 이전에 자막을 만들었습니다

그리고 그렇게한다면, 이것이 당신이 얻게 될 것입니다 첫 번째 동영상이 재생됩니다 그런 다음 첫 번째 동영상이 완료되면 우리는 다음 비디오로 자연스럽게 전환합니다 자막이 올라 오는 것을 볼 수 있습니다 우리가 기대했던대로

그래서 이것은 위대합니다 우리는 이러한 미디어 작품을 재생할 수 있습니다 그래서 우리는 이것을 구현했습니다 그리고 나서 우리는 생각했습니다 잠깐 만요

이 seekTo 메서드가 플레이어에 있습니다 하지만 이제 우리는 재생하고 싶은 재생 목록을 가지고 있습니다 여러 소스가 있습니다 타임 스탬프는 정보가 충분하지 않습니다 당신이 더 이상 추구하고 싶은 곳을 아는 것

그래서 우리는 이것에 대해 생각하고 생각했습니다 재생할 수있는 다른 유형의 미디어 소스, 라이브 미디어 소스처럼 그리고 우리는 앱에 폭로하는 방법이 정말로 필요하다는 것을 깨달았습니다 미디어 소스의 구조 그리고 어떤 미디어를 사용할 수 있습니다 그래서 어떤 것을 알 필요가 있는지의 문제를 해결하기 위해서 소스를 찾으려는 경우 매개 변수를 추가했습니다

플레이어에게 소스를 알려줍니다 원하는 재생 목록에 있습니다 그리고 나서 우리는 필요하다고 생각했습니다 사용 가능한 미디어에 대한 설명 그래서 타임 라인이라는 새로운 데이터 구조를 추가했습니다

타임 라인은 기본적으로 표현입니다 미디어 소스에서 사용할 수있는 모든 미디어를 그리고 창 목록으로 구성됩니다 각 창은 재생 목록의 한 항목으로 이동합니다 그리고 그것은 미디어의 어떤 부분을 묘사합니다 당신은 어떤 주어진 순간에 추구 할 수 있습니다

그래서이 예제를 보여 드리겠습니다 조금 더 명확하게 해줍니다 그래서 우리는 하나의 소스를 가지고 있다고 상상해 봅시다 당신은 어디에서나 찾을 수 있습니다 여기서 빨간 선은 하나의 창을 나타냅니다

왼쪽의 점은 이 미디어 소스의 기본 시작 위치는 0입니다 그래서 플레이어가 소스에 도달하면, 그것이 연결된 경우에는 시간이 0이 될 것입니다 그리고 그 창문은 끝까지 펼쳐져 있습니다 미디어 소스의 지속 시간 더 흥미로운 경우는 두 소스를 연결하는 경우입니다

함께 그리고이 경우, 당신은 타임 라인으로 끝납니다 두 개의 창이 있습니다 보시다시피 두 창 모두에서 시작 위치는 해당 소스의 시작 부분에 있습니다 라이브 미디어 소스가 있다면 어떨까요? 이 경우 타임 라인은 실제로 동적입니다

실시간 이벤트가 진행됨에 따라 더 많은 미디어 창에서 사용할 수있게되었습니다 그리고 기본 위치가 라이브 에지를 추적 중입니다 그리고 라이브 이벤트가 완료되면, 기본 위치가 처음으로 다시 스냅됩니다 그래서 이것은 정규 스트림이됩니다 처음부터 재생이 시작되고 어떤 직책을 추구 할 수있다

그리고 우리는 이것을 바탕으로 일반 스트림과 라이브 스트림의 연결 그리고 이것은 당신이 기대하는 방식으로 작동합니다 따라서 소스를 연결하면 끝나는 타임 라인으로 끝나라 창의 연결 그 개별 소스 중 따라서이 타임 라인이 노출 된 것을 볼 수 있습니다

ExoPlayer의 최상위 API에서 현재 타임 라인을 얻을 수 있습니다 플레이어를 찾을 때 창 인덱스를 전달할 수 있습니다 재생 목록의 두 번째 항목을 찾으십시오 특정 오프셋에서

그리고이 창에 대한 세부 정보를 검사 할 수 있습니다 창문이 어디서 시작되고 얼마나 오래 있는지 지금은 Ollie로 돌아가서 내부에 대해 조금 이야기합니다 선수들의 올리버 우먼 : 앤드류가 말했듯이, 이제 우리는 ExoPlayer에 대해 좀 더 깊이 들어가기로했습니다 내부적으로 일어나는 일에 대해 재생 중

그리고 우리가이 일을 할 이유는 우리가 얘기 한 후에 내부 구성 요소의 우리가 어떻게 그것들을 커스터마이징 할 수 있는지에 대해 이야기하고 플레이어를 특정 유스 케이스에 맞게 미세 조정할 수 있습니다 여기 ExoPlayer가 있습니다 재생할 MediaSource를 받았다 중요한 내부 구성 요소는 무엇입니까? 첫 번째 중요한 구성 요소 언급해야 할 것은 렌더러입니다 렌더링을 담당하는 렌더러 미디어의 단일 구성 요소

따라서 VideoRenderer는 비디오 만 디코딩하고 표시합니다 AudioRenderer도 마찬가지로 해독 해 출력합니다 그냥 오디오 실제 ExoPlayer 인스턴스는 텍스트 및 메타 데이터와 같은 항목에 대한 추가 렌더러 보유 게다가 그러나 우리는이 다이어그램에서 이들을 생략 할 것입니다

단순함을 위해서 중요한 또 다른 구성 요소는 TrackSelector입니다 미디어 소스가 실제로 노출 될 수 있음 플레이어가 재생할 수있는 여러 개의 트랙 특히 DASH 또는 HLS 적응 재생이있는 경우, MediaSource가 실제로 여러 비디오 스트림을 노출 할 수 있습니다 다른 해상도에서, 그리고 아마 여러 오디오 언어 게다가

그리고 TrackSelector의 역할 해당 트랙의 하위 집합을 선택하려면 플레이어가 버퍼링하고 재생해야합니다 우리가 얘기해야 할 마지막 구성 요소는 LoadControl입니다 LoadControl에는 실제로 두 개의 작업이 있습니다 첫 번째 작업은 MediaSource에 알려주는 것입니다 그것이이 시점에서 버퍼링되어야하는지의 여부

그리고 이것은이 도표에 표시되어 있습니다 왼쪽에있는 녹색 점으로 그래서 우리는 아직 재생을 시작하지 않았기 때문에, 우리는 아무 것도 버퍼링하지 않습니다 따라서 MediaSource를 나타내는 것은 녹색입니다 버퍼링해야합니다

두 번째 임무는 재생할 때 플레이어에게 알려주는 것입니다 실제로 시작할 수 있습니다 이것은 오른쪽 점으로 표시됩니다 그리고 우리는 아직 어떤 언론도 가지고 있지 않기 때문에, 분명히 너무 빨리 재생을 시작할 수 있으므로 빨간색입니다 우리가 언급해야 할 구성 요소 중 하나는 데이터 소스입니다 MediaSources는 데이터 소스를 사용하여 실제 미디어를로드합니다

재생을 위해 플레이어에게 제공 할 것입니다 그래서 몇 가지 주요 구성 요소를 제공했습니다 그러나 어떻게하면되는지에 대해 조금 이야기 해 봅시다 이러한 구성 요소는 실제로 재생 중에 상호 작용합니다 아직 우리는 아무것도 버퍼링하지 않았습니다

그리고 LoadControl은 MediaSource에게 그것을 버퍼링해야합니다 MediaSource가 데이터로드를 시작합니다 데이터 소스를 통해 그리고 충분한 미디어가로드 된 후, 아마 보통의 미디어 파일에 대한 헤더 일뿐입니다 MediaSource가 해결할 수있을 것입니다 트랙을 실제로 플레이어에게 노출시킬 수 있습니다

그리고 이것은 TrackGroups라는 것을 노출시킴으로써 이것을합니다 이제 우리는 TrackSelector가 실제로 재생할 트랙을 선택합니다 그러나 TrackSelector는 다른 것을 필요로합니다 그리고 다른 이유가 필요한 이유 다른 장치가 다른 기능을 가지고 있다는 것입니다 특히 VideoRenderer 특정 해상도까지만 디코딩 할 수 있습니다

따라서 MediaSource가 4K 비디오 스트림을 노출하더라도, 저가형 기기를 사용한다면 TrackSelector에 대해 이해하지 못한다 실제로 해당 스트림을 선택합니다 우리가 이러한 종류의 능력을 대표하는 방식 플레이어에서 각 렌더러가 뭔가를 노출하고 있습니다 RendererCapabilities 객체를 호출했다 그것은 구체적으로 실제로 처리 할 수있는 것을 설명합니다

다음은 TrackGroups RendererCapabilities가 TrackSelector에 보내집니다 TrackSelector는 마술을합니다 선택을 생성합니다 그리고 그 선택은 MediaSource로 돌아갑니다 이 시점에서 MediaSource는 알고 있습니다

버퍼링 할 것이기 때문에 트랙 선택이 무엇인지 알고있다 그래서 몇몇 버퍼를 할당한다 물론 우리는 아직 실제로 재생을 위해 유용한 미디어를로드했습니다 LoadControl은 여전히로드 할 MediaSource를 알려줍니다 따라서 MediaSource는 계속해서 데이터를로드합니다

버퍼를 채우기 시작합니다 그리고 여기서 볼 수있는 것은 곧 이러한 버퍼가 가득 차기 시작하면, 렌더러는 실제로 그 버퍼로부터 소비되기 시작한다 상기 미디어 데이터를 그들의 디코더를 통해 공급하는 단계로서, 재생 준비 그래서 지금 우리는 미디어 버퍼를 가지고 있습니다 렌더러는 약간의 미디어를 해독했습니다 그래서 그들은 일종의 준비가되어 있고 갈 준비가되어 있습니다

그래서 LoadControl은이 시점에서 실제로 재생을 시작하십시오 작은 빨간 원이 녹색으로 변했습니다 물론 MediaSource는 지속적으로 버퍼를 사용하고 있습니다 그리고이 시점에서 우리는 실제로 많은 미디어를 버퍼링했습니다 그래서 왼쪽에있는이 버퍼들은 꽤 꽉 찼습니다

물론 우리는 임의적으로 멀리 버퍼링하고 싶지 않습니다 따라서 LoadControl은이 시점에서 버퍼링을 중지 할 수 있습니다 재생이 계속되기 때문에 렌더러 여전히 소비하고 있습니다 따라서 이러한 버퍼는 다시 유출됩니다 낮은 수준으로

물론 우리는 버퍼가 부족한 것을 원하지 않습니다 LoadControl은 버퍼링을 다시 토글 할 수 있습니다 그래서이 패턴이 떠오르게됩니다 DataSource를 통해 데이터를 가져 오는 중 MediaSource로 보내고 렌더러로 보내야합니다 염두에 두어야 할 또 하나의 복잡성 Andrew가 말했듯이, 당신이 이것에 대해 생각할 때, MediaSource는 실제로 예를 들어, 다른 동영상

그런 동영상의 트랙 선택이 다를 수 있습니다 유효한 그리고이 과정이 계속되면서, 실제로 추가 트랙 선택을 얻을 수 있습니다 동시에 일어난다 여기에서는 계속해서 재생을 시작합니다

버퍼가 채워지고 배수됩니다 그리고이 데이터 패턴이 간헐적으로 읽혀지는 것을 보았습니다 데이터 소스를 통해 지속적으로 소비 됨 렌더러에 의해 이제 중요한 구성 요소가 어떻게 작동하는지 조금 알 수 있습니다 재생 중

우리가 어떻게 커스터마이즈 할 수 있는지에 대해 조금 이야기 해 봅시다 그 내부 행동 Andrew가 이전에 보여준 코드 조각입니다 우리는 ExoPlayerFactory로 ExoPlayer를 만들고 있습니다 그러나 실제로는 더 복잡한 방법이 있습니다

ExoPlayer 생성을위한 것입니다 그리고 당신은 우리가이 플레이어에 주입하고있는 것을 볼 수 있습니다 인스턴스는 정확히 우리가 방금 구성한 구성 요소입니다 그런데 렌더러, TrackSelector, 및 LoadControl 여기에서는 기본 구현을 삽입하는 것입니다

그럼 우리가 어떻게 플레이어를 잡아 당겨 미세 조정할 수 있는지 살펴 보겠습니다 그 중 하나 이제 LoadControl을 살펴 보겠습니다 여기에서는 여전히 기본 구현을 사용하고 있습니다 그러나 실제로 생성자에 변수를 전달할 수 있습니다

그 행동을 조작하는 것 그래서이 기본 LoadControl은 말하고있다 그것은 버퍼에서 15 ~ 30 초 사이에 원하는, 다음과 같은 경우 재생을 시작하려고합니다 25 초가 버퍼됩니다

그렇다면 그 점이 어떤면에서 보입니까? 벽 시계 시간 대 지속 시간 의 미디어가 버퍼에 있습니까? 버퍼가 채워지기 시작합니다 25 초가 지나면 재생이 시작됩니다 작은 오렌지색 점으로 표시됩니다 LoadControl을 사용하면 버퍼링을 계속할 수 있습니다

30 초 버퍼링은 잠시 꺼집니다 그리고 MediaSource 버퍼가 줄어들 것입니다 ~ 15 초이며, 이는 하한입니다 그리고 버퍼링은 다시 켜집니다

그래서 이런 종류의 톱니 패턴을 얻습니다 버퍼링 동작의 측면에서 그래서이 시점에서 분명히 분명합니다 당신은이 행동에 실제로 영향을 줄 수 있습니다 이 번호를 15에서 25로 변경할 수 있습니다

버퍼 허용에 익숙하지 않은 경우 저기를 배수한다 우리는 기본 LoadControl의 작동 방식을 이해했기 때문에, 우리는 새로운 그래프를 보여줄 수 있습니다 그래서 여기서 버퍼는 모든 점에서 더 충만하게 유지됩니다 재생 중 그리고 버퍼링은 훨씬 더 자주 켜고 끕니다

우리가 원하는 걸 결정할 수도 있어요 재생을 시작할 때보다 보수적 인 태도를 취할 수 있습니다 그래서 우리는 값을 25 초에서 10 초로 늘립니다 그리고 우리는 그 차이를 이해할 수 있습니다

이 그래프의 관점에서 이제 수정 된 기본 LoadControl을 사용할 수 있습니다 다시 플레이어에 주입하십시오 그래서 LoadControl이 아니라면? 원하는 실제 버퍼링 정책에 충분히 유연합니까? 그럼 당신은 더 나아갈 수 있습니다 독자적인 LoadControl을 처음부터 구현하십시오

그래서 당신이 가진 방법 중 하나 이것을 구현하면 shouldContinueLoading이라고 불린다 부울을 반환합니다 재생 중에 폴링됩니다 그리고 이것은 정확히 방법입니다 실제로 MediaSource가 버퍼링하는지 여부를 제어합니다

그리고 모든 종류의 행동과 논리를 구현할 수 있습니다 자신의 구현에서 TrackSelector에서도 비슷한 일을 할 수 있습니다 그래서이 경우 실제로 매개 변수를 얻을 수 있습니다 우리는 기본값을 조작 할 수 있습니다

TrackSelector는 실제로 트랙을 선택합니다 여기서는 비디오 트랙을 SD로 제한하고 있으므로 480p입니다 그리고 귀하의 사용자가 귀하의 측정 된 모바일 연결에서 그리고 대역폭이 정말 큰 경우에도, 당신은 아마 그들의 데이터 전부를 아주 빨리 사용하고 싶지 않을 것입니다 품질에 대한 상한선을 유지하고 싶을 수도 있습니다 당신이 제공하는 것

마찬가지로 사용자가 독일어 인 경우, 케이스에 대해 선호하는 오디오 언어를 선택할 수 있습니다 노출 된 오디오 트랙이 여러 개있는 경우 MediaSource에 의해 그리고 매개 변수를 다시 수정할 수 있습니다 선택기에서이 새로운 비헤이비어를 실제로 활성화하십시오 또, TrackSelector의 디폴트 구현 적합하지 않다면 한 단계 더 나아가 구현할 수 있습니다 자신의 TrackSelector

구현해야하는 방법 중 하나 이렇게하면 selectTracks입니다 그리고이 메소드의 서명을 매핑하면된다 이전에 본 다이어그램으로 돌아갑니다 렌더러의 기능을 받고 있습니다 그리고 MediaSource의 TrackGroups, 선택을 생성합니다

물론 같은 트릭을 적용 할 수 있습니다 렌더러에 대해서도 마찬가지입니다 자신 만의 VideoRenderer를 처음부터 구현하기 꽤 고급 사용자 정의입니다, 정말로 원한다면 할 수 있어요 그리고 너는 정확히 너를 잘 처리 해준다 그것을 달성하기 위해해야합니다

그리고 기본 RenderersFactory를 확장 할 수 있습니다 buildVideoRenderers 메소드를 오버라이드 (override) 해, 실제로 자신의 VideoRenderer를 플레이어에 삽입하십시오 일반적으로 생성되는 기본값 대신 앤드루 루이스 : 좋아, 좋아 잘하면 당신은 신흥 패턴을 볼 수 있습니다

맞춤 설정의 각 예에서 저것은 대략 말했다 그래서 첫 번째 단계는 플레이어의 어떤 구성 요소를 사용자 정의해야하는지, TrackSelector이든 LoadControl이든 상관 없습니다 그런 다음 해당 구성 요소의 API를 살펴 봅니다 사용하여 행동을 사용자 정의 할 수있는 방법이 있는지 확인하십시오 말하자면, LoadControl에서했던 것처럼 다른 매개 변수입니다

그게 가능하지 않다면, 당신은 확장 할 수도 실제로 할 수도있다 이 구성 요소의 자체 버전을 처음부터 구현하십시오 그래서 저는 이제 더 많은 커스터마이징 예제를 할 것입니다 이번 MediaSource 쪽에서 그러므로 우리가 승인서를 보내야한다고 상상해보십시오

헤더는 MediaSource가 만드는 각 HTTP 요청을 포함합니다 글쎄, 우리는 우리가 지나가고 있다는 것을 안다 HttpDataSourceFactory에서 그리고 이것은 기본 요청을 얻는 편리한 방법을 가지고있다 속성

그리고 기본 요청 속성을 가져 와서, 우리는 실제로 새로운 헤더를 설정하여 인증 헤더를 설정할 수 있습니다 HTTP 요청에서 일단 그렇게하면 httpDataSourceFactory를 전달합니다 MediaSource에 넣습니다 그리고 그 헤더는 모든 요청에 ​​나타납니다

다른 예를 들어 보겠습니다 사용자가 동영상을 꽤 많이 되 감을 것이라는 것을 알고, 그래서 플레이어가 캐시를 추가하지 않도록 캐시를 추가하려고합니다 반복적으로 동일한 미디어를 네트워크에서로드합니다 ExoPlayer는 당신이 사용할 수있는 간단한 캐시를 가지고 있습니다 이 예에서는 LeastRecentlyUsedCacheEvictor

이것이 작동하게되는 방식은 캐시에는 최대 크기가 있습니다 하지만 미디어가 그보다 더 길다면 미디어가 끝나면 미디어를 완전히 보았다 캐시는 실제로 그것의 시작 부분을 제거하기 시작했다 따라서이 캐시는 CacheDataSourceFactory로 전달됩니다 또한 일반 데이터 소스를 가져와야합니다

캐시 미스가 있고 캐시를 채우는 데 사용됩니다 그리고 CacheDataSourceFactory를 전달합니다 ExtractorMediaSource 이렇게 조금이라도 더 분명하게 보이기를 바랍니다 플레이어와 어떻게 어울리는 지 보자

이전에 우리가 보았던 아키텍처 이 캐시는 실제로 MediaSource 사이에 앉을 것입니다 및 HttpDataSource 그리고 MediaSource가 데이터를 요청할 때, 처음에는 캐시에서 찾아 볼 것입니다 캐시 미스가 있으면 네트워크로 연결됩니다

HttpDataSource를 사용하십시오 그런 다음 요청이 만족되면 그것은 다시 돌아와 캐시를 채울 것입니다 다음에 MediaSource가 요청할 때 같은 덩어리, 그러면 캐쉬에있을거야 그래서 극단적 인 경우의 종류에 대해 이야기했습니다 맞춤 설정으로 MediaSource 제공 또는 귀하가 구현 한 모든 것

그래서 나는 그것을하는 예제를 통해 갈 것입니다 앱을 가지고 있다고 가정 해 보겠습니다 일부 콘텐츠를 보여 주지만 이제는 광고를 나란히 게재하여 해당 콘텐츠에서 수익을 창출하고 싶습니다 타임 라인의 진행 상황에 대해 생각해 봅시다 이 경우와 같이 보입니다

글쎄, 그것은 매우 간단합니다 이 예에서는 화면에 첫 번째 광고는 프리 롤 광고입니다 아니면 더 복잡 할 수도 있습니다 이 경우 프리 롤 광고가 있습니다 미드 롤 광고 및 포스트 롤 광고에 게재됩니다

그리고 그들은 일종의 내용을 나누었습니다 그래서 언뜻 생각하면 이것은 ConcatenatingMediaSource를 사용할 수있는 곳입니다 하지만 불행히도 일반적으로 광고를로드 할 때, 특정 광고 URI에 실제로 커밋 할 수는 없습니다 때까지 당신이 그것을 재생하려고합니다 Google에서 정확히 어떤 광고가 있는지는 알 수 없습니다

우리는 선전 할 것입니다 그럼 우리가 시도하면 어떻게되는지 보자 기존 MediaSources에서 단 한 명의 플레이어 만 사용하는 방법 이러한 광고를 재생합니다 그래서 재생 시작 부분에 URI가 있습니다 첫 번째 광고를 게재 한 다음 재생할 수 있습니다

그러나 우리는 우리가 그 내용을 재생할 필요가 있음을 안다 그래서 플레이어는 실제로 버퍼링하려고합니다 우리가 대신 콘텐츠를 재생하고 싶다고 말하면됩니다 그런 다음 콘텐츠가 재생되고 사용자가 다시 버퍼링을 볼 것입니다 그런 다음 광고, 더 많은 버퍼링 및 이것이 어떻게 작동 할 것인지 말하고있는 것 같습니다

버퍼링이 많이 있습니다 그리고 이것은 좋은 사용자 경험이 아닙니다 사람들이이 문제를 해결하기 위해 노력하는 한 가지 방법 그들은 두 명의 플레이어를 사용하려고 시도 할 것입니다 그리고 그 아이디어는 한 선수가 현재 화면에있는 것을 재생하려고합니다 다른 플레이어는 백그라운드에서 버퍼링을합니다

다음에 올거야 따라서 광고 URI가 도착하자마자 배경 플레이어를 채울 수 있습니다 잘하면 일부 데이터를 버퍼링 할 수 있습니다 재생이 시작되기 전에 그리고이 경우 재생은 광고와 콘텐츠 사이를 전환하십시오

그러나이 솔루션에는 단점도 있습니다 이 두 플레이어는 모두 버퍼링을 위해 메모리를 사용합니다 동시에 코덱을 사용할 수도 있습니다 그렇게 좋지는 않습니다 그리고 이것은 또한 매우 어렵습니다

당신이 이것을 시도한 적이 있다면 올바르게 구현할 수 있습니다 그래서 우리는 MediaSource를 구현하려고 생각했습니다 특별히 광고용으로 설계되었습니다 그리고이 MediaSource가 구현되었습니다 연결 미디어 소스와 약간 비슷한 방식으로, 단,이 재생 목록 항목은 다음과 같습니다

채워지지 않습니다 그리고 그것들은 물음표로 표시됩니다 그것들은 광고들로 채워질 것입니다 그들이 도착하자마자 그럼 재생이 어떻게 보이는지 봅시다

이 가설적인 MediaSource와 같습니다 재생이 시작되고 첫 번째 광고가 표시됩니다 그런 다음 콘텐츠가 재생됩니다 바라건대 우리는 조금 더 일찍 다음 광고를 얻습니다 그 자리 표시자는 타임 라인에 채워집니다

그리고 이것이 잘 작동하면 사용자 실제로 재생하는 동안 어떤 버퍼링도 보지 않을 것입니다 그래서 이것의 실질적인 예로서, Google은 InteractiveMediaAds SDK를 제공합니다 너는 그것을 들었을지도 모른다 그리고 우리는이 ImaAdsMediaSource에서 광고를로드하는 데 이것을 사용하고 있습니다 보시다시피, 지역 종류의 광고가 IMA에서로드 될 때 강조 표시됩니다

그리고 미디어 소스가 IMA를 래핑하고 있습니다 그래서 플레이어는 게임의 세부 사항에 대해 걱정할 필요가 없습니다 광고가 실제로로드됩니다 이 타임 라인에서 원활한 전환 효과를 얻을 수 있습니다 콘텐츠와 광고 사이

그래서 우리는 이것을 실제로 개발 브랜치로 밀어 넣었습니다 오늘 미리 미리보기를 원한다면 콘텐츠에 광고를 삽입하려는 경우 사용하기가 매우 쉽습니다 그래서 당신은 당신의 콘텐츠를 가져 간다 MediaSource 당신은 그것을 구조에 전달합니다 ImaAdsMediaSource를 정의하는 adTagUri와 함께 로드 할 광고 재생 목록 또한 OverlayViewGroup을 사용합니다

어떤 양방향 미디어 광고가 사용할 것인가 플레이어 상단에 광고 사용자 인터페이스를 표시하는 방법 예를 들어 건너 뛰기 버튼처럼 이 일을 시도하면 얻을 수있는 것이 있습니다 프리 롤 광고가 재생중인 것을 볼 수 있습니다 광고가 끝나면 광고 간 전환이 아주 원활하다 콘텐츠로 또한 재생 컨트롤에 지원 기능이 있음을 알 수 있습니다

광고 마커가 거의 표시되지 않도록 사용자가 미드 롤 광고의 위치를 ​​확인하십시오 그리고이 재생 중에 일관된 버퍼링 정책이 항상 적용됩니다 이제 우리의 미래 계획에 대해 이야기하기 위해 다시 Ollie로 돌아 가자 올리버 우먼 : 우리가 너를 떠나기 전에, 나는 방향에 대해 조금 말하고 싶다 ExoPlayer가 향합니다

이것에주의를 기울이는 것만으로도 이것은 약속이 될 수 없습니다 우리는 어떤 것에도 타임 라인을 넣지 않을 것입니다 그러나 사물의 측면에서 우리가 앞으로 6 개월 동안보고있을 것입니다 1 년, 우리는 계속 될 것입니다 나머지 기능 틈을 채우기 위해 우리가 정말로 완전 해지는 관점에서 미디어 재생 라이브러리

우리가 아는 하나의 구체적인 것은 당신을 많이 일으키는 것입니다 문제는 오프라인에 대한 적절한 지원입니다 그래서 이것이 실제로 다운로드하는 곳입니다 미디어를 나중에 재생할 수 있습니다 그래서 우리는 우리가 시작하기를 기대할 수 있습니다

향후 6 개월 동안 오프라인 지원 구축 ~ 1 년 우리는 또한 계속 일할 것입니다 향상된 성능 그리고 그것은 디코더 인스턴스를 유지하는 것과 같은 것을 의미합니다 한 재생에서 다음 재생으로 플랫폼에서, 해제 및 인스턴스화 우리가 지금하는 것처럼 그 디코더는 꽤 비쌀 수 있습니다

살펴볼 성능의 또 다른 측면 DASH 및 HLS를위한 향상된 적응 형 트랙 선택입니다 SmoothStreaming 적응 형 재생 및 고급 버퍼링 정책 따라서 현재 우리가 사용하는 기본 구성 요소 이러한 작업을 수행하기 위해 제공, 그들은 꽤 효과적이지만 그들은 그들이 구현하는 정책면에서 아주 간단합니다 그래서 우리는 좀 더 깊이 잠수하기를 정말로 원합니다 적절한 연구와 종류를하고 더 나은 성능을 내기 위해 이들을 미세 조정하는 방법 상자의 마지막으로 우리는 ExoPlayer API가 매우 큰 것을 알고 있습니다

시작하기에 어려울 수 있음을 다이빙이 필요한 곳을 정확히 알아 내기 위해 뭔가를 사용자 정의하고 싶습니다 그래서 우리는 더 나은 문서화 작업을 할 것입니다 아마도 문서화로 시작한다 플레이어가 가지고있는 내부 구성 요소의 일부 사용했다 ExoPlayer로 다음에 할 수있는 일의 관점에서 네가 여기있는 동안, 내일 근무할 시간이있어

아침 9시 30 분에 근무 시간대에 우리에게 질문이 있으시면 함께 오세요 우리는 채팅하고 답변을하는 것보다 더 행복 할 것입니다 우리 소스 코드를 살펴보고 싶다면, GitHub 저장소는 공개되어 있으므로 가서 살펴볼 수 있습니다 그리고 우리는 또한 홈 페이지를 가지고 있습니다

시작하는 데 도움이되는 개발자 가이드가 포함되어 있습니다 또한 다양한 문서가 있습니다 지원되는 형식 등 그리고 그걸로와 주셔서 감사합니다 불행히도 지금은 질문 할 시간이 없습니다

그러나 우리는 아마 이후에 모퉁이에서 내려갈 것입니다 내가 말했듯이, 질문이 있으면 우리가 지금 대답 할 수없는, 제발 내일 아침에 너와 같이 갈거야 그들에게 행복하게 대답하십시오 시간 내 주셔서 대단히 감사합니다 [박수 갈채] [음악 재생]

How to Get Dark Mode on Google Chrome for Android

특히 밤에 Chrome 검색을 사용하는 경우 너는 그 소식을 읽었고, Stories 귀하의 Google 크롬에 다음 귀하의 Google 크롬에 다크 모드가 필요합니다 다크 모드는 탐색이 쉽고 눈이 안전하기 때문에 이제 Google 크롬에서 어두운 모드 기능을 원한다면 계속 조정 해보십시오

비디오가 끝날 때까지 지켜보십시오 따라서 내 YT 채널에 아직 가입하지 않은 경우 동영상을 시작하기 전에 이 빨간 SUBSCRIBE 버튼을 누르고 내 채널을 구독하십시오 도와주세요! 그래서 프로세스는 매우 간단합니다 먼저 시작합니다 구글 크롬

먼저 간체 페이지를 활성화해야합니다 야간 모드 기능을 사용할 수 있습니다 그럼 어떻게 할 수 있죠, 세 개의 도트 아이콘을 치고, 설정> Accesbility 설정에서 히트> 단순화 된 페이지보기 옵션을 설정하십시오 간체보기에서 Chrome은 기본적으로 기사를 제공합니다 읽기 모드

그것은 모든 멋진 탭을 제거합니다 다음과 같이 웹 사이트를 더 깨끗하게 볼 수 있습니다 그 후에 Google 크롬 플래그 옵션을 열고> 이제 리더 모드 트리거링 옵션을 검색합니다 그것을 가능하게하십시오

이 다섯 가지 옵션 중에서 선택할 수 있습니다 하지만 현재, 여기에서는 항상 옵션을 선택합니다 Google 크롬을 다시 시작합니다 이제 어떤 웹 페이지라도 열어보십시오> 이제 페이지를 열 때마다 읽기 모드로 변경할 수있는 팝업 창이 나타납니다

읽기 모드로 변경할 수있는 팝업 창이 나타납니다 어두운 모드로 전환하려면 가볍게 누르십시오 이제 3 도트 아이콘> Appearnce> 이제 여기에 어두운 모드가 선택됩니다

What's New in Android Studio UI Design and Debugging Tools (Google I/O'19)

[음악 재생] VADIM CAEN : 안녕하세요 우리 이야기에 일찍와 주셔서 감사합니다

Android Studio, UI 디자인 및 디버깅의 새로운 기능 도구 고맙습니다 [박수 갈채] 저는 Vadim입니다 Android Studio에서 디자인 툴을 작업합니다 JEROME GAILLARD : 저는 Android Studio 팀의 Jerome입니다

JOE BAKER-MALONE : 저는 Android Studio 팀의 Joe입니다 ASHLEY ROSE : 저는 Android 프레임 워크와 JetPack의 Ashley입니다 VADIM CAEN : 좋습니다 시작하기 전에 모바일 제품에 대해 약간의 이야기를합니다 어제 어쩌면 Android Studio 팀은 개선을 위해 모바일 제품에 중점을 두었습니다

Android Studio의 엔드 투 엔드 사용자 경험 Android Studio 개선은 수정 사항 만이 아닙니다 또한 사용 방법을 개선하는 방법이기도합니다 우리가 확인한 틈새를 채우십시오 우리의 도구 체인은 – 설계 할 때 – 새로운 레이아웃을 구축하고 새로운 탐색 기능을 구축합니다 이 레이아웃 사이에, 당신의 자원을 관리하고, 장치에서 런타임에 검사를 처리합니다

이 도구 체인을 사용하려면 전형적인 사용자 여행을 거치면서, Google Trips 애플리케이션을 구축하십시오 그리고 Jerome은 Layout Editor에 대해 이야기 할 것입니다 여기에서 볼 수있는 첫 번째 레이아웃을 작성하는 방법에 대해 설명합니다 제롬 가이 야드 : 감사합니다, 바딤 그래서 우선, 우리는 Google Trips 앱의 첫 화면, 레이아웃 편집기를 사용하여

레이아웃 편집기를 열면 이것은 화면의 종류입니다 너는 볼거야 여기는 단지 빈 레이아웃 일뿐입니다 우리가 할 첫 번째 일은 청사진 모드로 전환하는 것입니다 속도가 빠르면 빠르며 방금 만들려고 할 때 산만해진다

레이아웃상의 제약 넌 그냥보고 싶지 않아 구성 요소가 실제로 어떻게 보이는지 나는 팔레트에서 – 레이아웃에 필요한 모든 구성 요소를 드래그하여 어느 정도 확실한 곳에서 일단 내가 끝내면 그 시간이 온다

제약 조건을 만들 수 있습니다 좀 더 효율적인 건물 제약이되는 방법으로, 나는 그들을 하나 하나 만들 수 있었다 하지만 문맥 메뉴를 사용하면 한 번에 여러 가지 제약 조건을 만들 수 있습니다 예를 들어 여기서는 RecyclerView를 중앙에 배치하려고합니다 레이아웃 내에서

내가 할 수있는 한 가지는 RecyclerView를 마우스 오른쪽 버튼으로 클릭하는 것입니다 문맥 메뉴에는 옵션이 있습니다 수평으로 센터링의 그것이하는 일은 왼쪽 클릭 한 번으로 오른쪽 제약 조건을 RecyclerView가 중앙에 배치되도록합니다 일단 모든 제약 조건을 다 만들면, 이것은 내 레이아웃이 청사진 모드에서 보이는 것과 같습니다

분명히, 그것은 나에게 정말로 말하지 않는다 디자인에 비해 옳은 것을 만들면 지금 당장 나는 주어진다 이제 디자인 모드로 돌아가겠습니다 그것이 어떻게 생겼는지 보아라 디자인 모드에서는 보이지 않는 것을 볼 수 있습니다

내가받은 원래 디자인과 매우 흡사하다 그 이유는 RecyclerView 뷰 꽤 비어 있습니다 아시다시피, RecyclerView는 일반적으로 런타임에 데이터를 채우고, 하지만 그때는별로 도움이되지 않습니다 레이아웃을 만들고 데이터가 올바르게 표시되는지 확인하십시오 당신이 보게 될 것입니다

이 문제를 해결하려면 디자인 [? 도구?] 속성을 사용합니다 그래서 디자인 시간 속성, 당신은 간단하게 – RecyclerView에서 컨텍스트 메뉴를 다시 사용하십시오 샘플 데이터 선택기 등을 사용할 수 있습니다 샘플 데이터 선택 도구에서 미리 정의 된 템플릿 중 하나를 선택할 수 있습니다 RecyclerView 항목에 대해 귀하가 제공하는 정보

여기에서 첫 번째 이메일 클라이언트를 선택했습니다 그렇게하면 해당 RecyclerView에 대한 레이아웃이 생성됩니다 항목, 이메일 클라이언트 카드 그리고 동시에, 그것을 당신의 RecyclerView에 연결합니다, 그러면 레이아웃 편집기에 채워진 상태로 표시됩니다 물론 우리는 이메일 클라이언트를 구축하지 않습니다

RecyclerView에서 빌드하고자하는 것 그 여행 카드입니다 그래서 나는 그 RecyclerView 아이템을 편집하려고합니다 Trip 카드로 만들었습니다 자원 관리자 패널에서 – 여기에서 볼 수있는 왼쪽 편에, 바딤이 선물 할거야 너에게 훨씬 더 자세하게 – 간단히 말해서 RecyclerView 항목의 이름을 뭔가로 바꿀 수 있습니다

내 프로젝트에 더 적합한, 그리고 나 편집을 시작할 수 있습니다 리소스 관리자에서 레이아웃을 두 번 클릭하십시오 레이아웃 편집기에서 레이아웃을 열면됩니다 화면에서 볼 수 있듯이, 나는 꽤 많이 가지고있다 내 오른쪽 여행 카드에 필요한 모든 권리가있는 구성 요소, ImageView, 몇 개의 태그보기, 그러나 그들은 분명히 올바른 제약 조건을 가지고 있지 않습니다

그래서 모든 제약 조건을 삭제하고, 툴바에서 해당 버튼을 클릭합니다 그 작업이 끝나면, 나는 재구성 만 할 것입니다 모든 제약 한 가지 문제는 우리가 꽤 많은 구성 요소를 가지고 있다는 것입니다 작은 영역에서 서로 겹치기

그것은 약간 어수선 할 수 있습니다 그리고 우리는이 상황에서, 건물 제약 조건은 약간 어려울 수 있습니다 제약 조건을 드래그하는 것이 때로는 어려울 수 있습니다 올바른 대상, 올바른 구성 요소, 특히 구성 요소가 겹치는 경우 이제 우리가 할 수있는 일은 제약을 원하는 곳으로 직접 드래그합니다 연결하려는 구성 요소에서, 그런 다음 팝업 메뉴가 열리고 어떤 유형인지 묻습니다 설정할 제약 조건을 선택하십시오

정말 흥미로워 지네 제약 조건을 다음 위치로 드래그합니다 겹치는 구성 요소가 있습니다 그 상황에서, 우리는 여러 유형의 제약 조건을 사용할 수 있지만 겹치는 구성 요소를 선택하십시오 그 제약 조건을 첨부하고 싶습니다

그리고 그것은 그것을 훨씬 쉽게 만들어야합니다 경우에 제약 조건 레이아웃을 작성하는 방법 중첩되고 작은 구성 요소가있는 곳 도움이 될 수있는 마지막 방법 제약 조건을 효율적으로 만들 수 있습니다 구성 요소를 사용 중입니다 구성 요소에서 여러 구성 요소를 선택하는 경우 – 여기에서는 두 가지 텍스트보기를 선택했습니다

다시 컨텍스트 메뉴에서 마우스 오른쪽 버튼을 클릭하고 선택합니다 사용할 수있는 제약 조건 중 하나 당신은 하나의 제약 조건을 만들 수 있습니다 선택한 여러 구성 요소에 적용됩니다 그래서 여기에서 두 가지 제약 조건을 만듭니다 이 두 텍스트보기에서 동시에 우리가 모든 제약 조건을 다 만들면, 우리의 견해를 조금이라도 사용자 정의 할 때입니다

이를 위해 우리는 Attributes Panel을 사용할 것입니다 레이아웃 편집기의 오른쪽에 있습니다 우리는 Attributes 패널을 재 설계했습니다 Declared Attributes라는 맨 위에 새 섹션을 표시합니다 이 섹션에서는 모든 속성 구체적으로 설정된 선택한보기에 대한 그 견해에 대해서

바로 거기에서 모든 속성을 편집 할 수 있습니다 이미 설정된 해당 뷰에 새 속성을 설정하려면, 더하기 버튼을 클릭하기 만하면됩니다 해당 속성의 이름과 값을 추가하십시오 Attributes 패널에서 할 수있는 또 다른 일 Constraint Widget을 사용하여 여백을 설정합니다 귀하의 의견에 보고 싶어했을거야

숫자와 같은 실제 값만 설정할 수있을뿐만 아니라 증거금의 가치 ​​- 정의 된 맞춤 측정 기준을 설정할 수도 있습니다 프로젝트에서 그것이 우리가 @ dot dot dot option을 추가 한 이유입니다 드롭 다운의 맨 아래에 버튼을 클릭하면 자원 선택 도구가 열리고, 이미 가지고있는 특성 항목을 선택할 수 있습니다 프로젝트에서 정의하거나 바로 거기에 새로운 차원이 있습니다 일어날 필요가있는 마지막 한 가지 – 그 레이아웃을 보면서 – ImageView가 샘플 데이터로 채워지는 것을 볼 수 있습니다

하지만 단지 기본 샘플 데이터 일뿐입니다 Android Studio에서 제공됩니다 그래서 그것은 실제로 그 종류를 대표하지 않습니다 RecyclerView가 런타임에 수신 할 데이터의 양입니다 그래서 당신이 할 수있는 것은 당신 자신의 샘플 데이터를 설정하는 것입니다

그 ImageView에 cities라는 이미지를 cities라는 디렉토리에 추가했습니다 우리 프로젝트의 샘플 데이터 폴더에 있습니다 샘플 데이터 그림에 나타나는지 확인할 수 있습니다 샘플 데이터를 설정할 수 있습니다

우리의 원래 레이아웃으로 돌아가서, 우리는 이제 그것이 많이 보임을 볼 수 있습니다 당신이 가진 원래의 디자인과 더 비슷합니다 거기에서, 당신은 정말로 디자인이 제대로 구현되었으며 실제 데이터를 수신 할 때 작동합니다 장치에서 실행 중입니다 이제 우리는 첫 번째 제약 조건의 구축을 마쳤습니다

첫 번째 화면에서 계속 진행하고 싶습니다 우리의 응용 프로그램에서 우리의 다음 화면을 구축합니다 레이아웃 파일을 만드는 것만으로 돌아 가기보다는, 레이아웃 편집기에서 빌드하고, 우리는 네비게이션을 생각하고 바로 거기에서 시작하고 싶다 우리의 애플 리케이션의 흐름, 그리고 어떻게 첫 번째 화면이 전환됩니다 두 번째 화면으로 그렇게하기 위해 우리는 네비게이션을 살펴볼 것입니다 편집자

탐색 편집기는 시각적 도구입니다 이를 통해 Navigation Architecture를보다 쉽게 ​​사용할 수 있습니다 JetPack 라이브러리의 구성 요소 탐색 아키텍처 구성 요소의 방식 작품은 네비게이션 호스트 단편을 사용하는 것에 의존합니다 응용 프로그램의 기본 레이아웃

여기에 우리의 활동 주 레이아웃 파일, 우리는 Layout Editor에서 드래그 할 것입니다 NavHostFragment 팔레트 – 기본적으로 거기에 있습니다 그것을 디자인 표면 위로 끌어 올 것입니다 그렇게 할 때, 그것은 당신에게 선택을 요구할 것입니다 해당 NavHostFragment와 관련된 탐색 그래프 아직 탐색 그래프를 만들지 않은 경우, 그 대화 상자에서 바로 할 수 있습니다

우리가하는 일이야 이것이 레이아웃이 어떻게 생겼는지입니다 그것은 비어 있습니다 이 NavHostFragment가 있습니다 네비게이션 아키텍처 구성 요소 그것을 채울 것입니다 당신이로드 할 여러 단편들

그러나 두 번 클릭하면 탐색 편집기가 열립니다 이것은 네비게이션 에디터가 비어있을 때 보이는 것과 같습니다 우리가하고 싶은 첫 번째 일 첫 번째 화면을 시작 목적지로 추가합니다 우리의 애플 리케이션을 위해 대상 추가 메뉴에서 앱에있는 모든 레이아웃이 미리 선택되었습니다

그래서 우리를 위해, 우린 그 조각을 환영합니다 이전에 작업해온 레이아웃입니다 바로 거기에 놓으십시오 다음으로, 우리는 두 번째 화면을 추가하기를 원한다 그러나 이미 레이아웃을 만들지 않았기 때문에, 우리는 단순히 새로운 목적지를 만들 수 있습니다

추가 대상 메뉴에서 그렇게하면 생성의 가능성을 얻을 수 있습니다 새로운 프래그먼트 클래스와 그 관련 레이아웃, 이것이 레이아웃이 될 것입니다 두 번째 화면으로 사용됩니다 두 화면이 Navigation Editor에 있으면, 그들을 연결하는 시간이 온다

그것은 행동으로 할 수 있습니다 화면에 표시된대로 작업을 간단하게 만들 수 있습니다 또한 Attributes 패널에서 직접 탐색 편집기의 해당 동작에 대한 속성 중 일부를 설정하고, 애니메이션이 재생되는 것과 같습니다 그 동작을 통해 전환 할 때, 또는 뒤로 누르면 행동으로 할 수있는 또 다른 매우 흥미로운 일 한 화면에서 다음 화면으로 유형 안전 데이터를 전달합니다

그렇게하고 싶다면 다음과 같이 할 수 있습니다 수신 대상에 – 인수 섹션에서 더하기 단추를 클릭하십시오 속성 패널의 단순히 대화 상자를 열면 인수의 이름을 지정하십시오 인수의 유형 그것은 미리 정의 된 유형일 수 있습니다

또는 프로젝트에서 정의한 유형일 수 있습니다 당신이 원하는 어떤 물건이라도 물론, 네비게이션 그래프 만들기 앱 탐색을 완벽하게 지정하기에는 충분하지 않습니다 또한 약간의 코드를 작성해야합니다 그러나 당신이 볼 수있는 것처럼 그것은 꽤 간단합니다

여기, 나는 RecyclerView의 항목에 불과하다 OnClickListener의 경우 전환하려고합니다 그 행동을 끝내라 그래서 내가하는 일은 액션 객체를 만드는 것입니다 내비게이션에서 지정한 인수를 전달합니다

편집자 일단 행동을 취하면 나는 간단하게 탐색 라이브러리의 navigate 메소드 호출 실제로 전환을 수행합니다 그것이 실제로 정의한 전환을 수행하는 데 필요한 전부입니다 탐색 편집기에서 할 수있는 마지막 사항 나머지 네비게이션 흐름을 채우기 위해 자리 표시자를 사용하며, 그 순간에 귀찮게하고 싶지 않으면 새로운 조각 나중에, 그렇게 할 준비가되면, 당신은 단순히 돌아가서 레이아웃으로 대체 할 수 있습니다

지금은 실제로 빌드 할 때가되었다고 생각합니다 우리의 두 번째 레이아웃 보시다시피, 많은 이미지가 포함 된 레이아웃입니다 많은 자원이 필요합니다 우리는 어떻게 자원을 볼 것인가? 관리자는 우리가 그것을 구축하는 데 도움이 될 수 있습니다

VADIM CAEN : 나는 갭을 채우기 전에 이야기하고있었습니다 Android Studio에 존재했던 하나의 차이 리소스를 관리하는 방법이었습니다 문제가 무엇인지 살펴 보겠습니다 Android Studio 리소스 디렉토리 구조 프레임 워크를 위해 만들어진 것이지 실제로는 아닙니다 사용자에게 리소스를 얻을 때 디자이너에게서 보면 이렇게 보일 수도 있습니다

폴더가 많을 수도 있습니다 죄송합니다 먼저 Android Studio에서 다른 문제가 발생했습니다 전체 축소판보기가 없습니다 특정 Android보기

그래서 레이아웃, 벡터 잔해 또는 모양 – 미리 볼 수있는 유일한 방법은 하나의 레이아웃을 두 번 클릭하거나 하나의 파일에 두 번 클릭하는 것입니다 미리보기에서 확인하십시오 이 문제를 해결하기 위해 Android Studio에 도입했습니다 34 Resource Manager는 다음과 같은 새로운 도구입니다

리소스를 가져오고, 사용하고, 탐색 할 수 있도록 도와줍니다 보다 그래픽적인 방식으로 그것을 열려면 간단히 Resource Manager 버튼을 클릭하면됩니다 Android Studio의 왼쪽에있는 프로젝트 버튼 아래, 이 중립 창을 열 것입니다 한번 더 그래서 우리 문제로 되돌아갑니다

왼쪽에는 프로젝트 구조가 있습니다 오른쪽에는 디자이너가 우리에게 준 것을 가지고 있습니다 우리는 파일에서 다른 프로그램을 볼 수 있습니다 디자이너가 우리에게 준 것 어쩌면 그들은 자신이 좋아하는 디자인 소프트웨어를 사용했을 것입니다

기본 내보내기 옵션을 사용했습니다 폴더에 드로어 블 접두어가 누락되었을 수 있습니다 이름 또는 접미사 @ 2x와 함께 웹 형식을 사용했을 수도 있습니다 그리고 당신이해야 할 일은 @ 2x 접미사를 제거하는 것입니다

그런 다음 하나씩 하나씩 파일을 붙여 넣습니다 다른 문제는 폴더가 누락되었을 수 있으며, 그리고 당신은 문서로 돌아 가야 할 것입니다 이 특정 폴더에 대한 한정자가 무엇인지 기억하고, 그리고 당신은 올바른 순서로 그들을 넣어야합니다 Resource Manager와는 어떻게 작동합니까? 이제 전체 묶음을 끌어다 놓기 만하면됩니다 당신이 Resource Manager에 가져온 파일들, 자동으로 가져오고 이름별로 그룹화됩니다

여기에서 볼 수 있듯이 우리의 자원은 이름별로 그룹화되어 있습니다 올바른 한정어가 적용되었습니다 그래서 방금 무슨 일이 있었던거야? [박수 갈채] 고맙습니다 한정어를 식별하면 여기에는 웹 또는 Android가 파일 경로에있을 수 있습니다 우리는 단순히 해당 안드로이드 폴더를 만들 것입니다, 파일에있을 수있는 접미어를 제거하고, 프로젝트에 복사하십시오

물론 한정자를 추가하려는 경우 (예 : 무작위로 지방, 그리고 프랑스어와 같은 임의의 언어, 프랑스와 같은 지역에서는 간단하게 여기에서 할 수 있습니다 그리고 당신은 명령을 기억할 필요가 없습니다 수동으로 폴더를 만들면 자동으로 생성됩니다 올바른 한정어로 이 시점에서 원하는 경우 파일의 이름을 바꿀 수도 있습니다 이제 우리의 자원은 Resource Manager에서 그룹화됩니다

한 번에 모두 볼 수 있습니다 따라서 기본적으로 하나의 리소스 버전 만 표시됩니다 하지만 리소스를 두 번 클릭하면 당신은 모든 다른 버전을 볼 수 있습니다 다른 한정자가 적용되면 분석 할 파일 유형 어떤 파일이 응용 프로그램에서 가장 많은 공간을 차지했는지 자, 이것은 제가 정말로 흥분되는 특징입니다

이제 SVG를 드래그 앤 드롭 할 수 있습니다 VectorDrawable로 변환됩니다 [CROWD CHEERING] 고맙습니다 그래서 여기에 파일 선택기가 열려 있습니다 나는 아무것도 선택할 필요가 없다

간단히 클릭하고 열 수 있으며 모든 SVG를 열 수 있습니다 가져오고 변환됩니다 또 다른 멋진 기능은 모든 레이아웃을 미리 보는 것입니다 이름으로 레이아웃을 인식하는 것이 어려울 수도 있습니다 따라서 레이아웃 탭에서 리소스 관리자를 열면, 모든 레이아웃을 볼 수 있습니다

당신이 찾고있는 것을 찾으려면 전에 말했듯이 도구 체인이 있습니다 이 전체 도구 체인을 함께 통합하려고합니다 우리가 한 것은 통합 된 것입니다 [INAUDIBLE] 레이아웃 편집기로

예를 들어 여기에 포함시키고 자하는 레이아웃이 있습니다 그래서 상단 부분 이 레이아웃을 레이아웃 편집기로 드래그 앤 드롭 만하면됩니다 [INAUDIBLE]을 만듭니다 Drawable에도 똑같이 적용됩니다

Drawable을 드래그 앤 드롭하면 ImageView가 생성됩니다 이 견해의 끝까지 빨리 감습니다 이전 레이아웃에서 볼 수 있습니다 우리 툴바는 올바른 색상이 아닙니다 우리가 할 수있는 것은 컬러 탭을 열고, 우리 프로젝트에 정의 된 모든 색상을 볼 수 있습니다

그 중 하나를 두 번 클릭하기 만하면됩니다 파일을 열어서 커서를 옮깁니다 여기서 색상이 정의됩니다 그런 다음 새로운 색상 선택기를 사용할 수 있습니다 시각적으로 색을 선택하십시오

색상 선택기는 RGB 및 HSB에서 작동하며, HSB를 선택한 디자이너와 함께 일한다면 값을 사용하거나 자료를 사용할 수 있습니다 이미있는 팔레트 이제 두 개의 레이아웃이 준비되었습니다 앱에서 실행하고 싶습니다 Ashley와 Joe가 우리에게 말하기를 다시 환영 할 것입니다

새로운 레이아웃을 검사하는 방법 [박수 갈채] JOE BAKER-MALONE : 감사합니다, 바딤 이제 개발주기의 다음 단계로 넘어갑니다 우리가 실제로 앱을 실행하게되면, 실제 데이터와 함께 작동하는 방법을보고 조정할 수 있습니다 우리가해야 할 수도 있습니다

이제 오늘, 레이아웃이 어떻게 작동하는지보고 싶다면 런타임에는 Layout Inspector 도구가 있습니다 Android Studio에서 레이아웃 속성은 스냅 샷을 제공합니다 한 화면의 전체보기 계층 구조, 및 속성에 대한 일부 정보 각보기에서 설정됩니다 하지만 지금은 많은 한계가 있습니다 이것은 부분적으로 안드로이드 프레임 워크의 데이터에 기인합니다 표시 할 수 있도록 Studio에 제공됩니다

이제 Android Q에서는 프레임 워크에 Studio에 대한 여러 가지 새로운 API 추가 더 많은 뷰 및 레이아웃 디버깅을 노출하는 데 사용 정보 Ashley는 새 API에 대해 곧 이야기 할 것입니다 프레임 워크 추가가 우리에게 충분한 지 확인하려면 우리가 원하는 정보를 사용자에게 보여주고, Android Studio 팀의 우리 부부 프로젝트 마블에서 약간의 시간을 보냈습니다 새 API를 채택하고 우리가 할 수있는 것을 확인하십시오 우리는 완전히 새로운 Layout Inspector 작업을 시작했습니다

내가 너에게 지금 보여줄 것은 일의 몰래 절정이다 우리는 지금까지 해왔습니다 자, 이것은 초기 작업입니다 최신 미리보기 빌드에는 아직 포함되어 있지 않습니다 그러나 차드가 어제 개발자 기조 연설에서 말했듯이, 우리는 미리보기를 좋아합니다

우리는 개발자 의견을 환영합니다 그래서, 우리는 당신의 손에 그것을 밖으로 가져갈 것입니다 최대한 빨리 자, 어떻게 작동하는지 봅시다 Google 여행 앱부터 시작하겠습니다

우리가 해왔 던 이제 에뮬레이터에서 실행 중임을 알 수 있습니다 우리는 물건을 끌어 올려서 사용자로부터 실제 데이터를 실행하고, 디자인 타임에 사용한 샘플 데이터가 아닙니다 여기서 아래로 스크롤하면 볼 수 있습니다 실제 데이터의 일부 여행 설명 우리가 샘플 데이터에서 가지고있는 것보다 상당히 길다 텍스트가 정렬되는 지점까지 우리가 의도하지 않은 방식으로 이미지를 지배했다

새로운 레이아웃 검사기에서 이것을 살펴 보겠습니다 새로운 레이아웃 검사기가 우리에게 제공하는 것을 볼 수 있습니다 레이아웃 검사기에서 현재 가지고있는 것과 유사한보기입니다 문제의 텍스트보기를 선택하면 여기, 그리고 오른쪽에있는 Attributes Panel을보고, 우리는 몇 가지 차이점이 있음을 알 수 있습니다 현재 레이아웃 검사기에서 가지고있는 것입니다

우선, 실제 속성 이름이 있습니다 이전에는 getter 메소드 모음이 있었지만 그렇지 않을 수도 있습니다 잘 실제 속성 이렇게하면지도를 훨씬 쉽게 찾을 수 있습니다 여기서 본 것에서부터 정의한 것에 이르기까지 자신 만의 레이아웃과 스타일로

두 번째로, 우리는 멋지게 형식화 된 속성 값 다양한 가치 유형에 대해 우리는 전에 그것을 항상 얻을 수는 없었다 예를 들어 ID, 열거 형을 볼 수 있습니다 가치, 색깔, 등등 세 번째로, 우리는 지금 몇 가지 정보를 가지고있다 그 속성 값이 설정되는 곳

따라서 우리는이 선언 된 속성 섹션을 볼 수 있습니다 여기, 우리가 Layout Editor에서 가지고있는 것과 비슷합니다 직접 설정된 속성의 경우 선택한보기에서 이제 텍스트 크기와 관련된 속성을 살펴 보겠습니다 이 옵션을 선택하면 기본 탐색 기능을 사용할 수 있습니다 여기에서 직접 키 스트로크를 선언하는 방법 해당 값이 설정되는 레이아웃 xml로 이동합니다

조금 더 작게 변경하십시오 개발자 기조 연설에서 들었던 것처럼, Android Studio 35 미리보기에서 이 새로운 변경 기능을 적용하십시오 이것 이후에 바로 그 부분에 대해 더 많은 것을들을 수 있습니다 Android 개발자 도구에서 새로 워진 이야기

하지만 지금은 에뮬레이터의 변경 사항을 확인하는 데 사용하겠습니다 우리의 애플 리케이션을 재배치 할 필요없이 실제로 새로운 레이아웃에서 업데이트가 즉시 표시됩니다 경감 님 Layout Inspector가 무엇을 미러링하고 있기 때문입니다

기기 라이브에서 발생합니다 우리가 여기서 다시 스크롤한다면, 레이아웃 검사기가 오른쪽으로 스크롤되는 것을 볼 수 있습니다 게다가 [박수 갈채] 예 다른 시나리오를 살펴 보겠습니다

앱의 어두운 테마를 구현하고 싶다고 가정 해 보겠습니다 여기서 우리는 밝은 배경색을 가지고 있음을 알 수 있습니다 배경색이 어디인지 알아 보겠습니다 에서 온다 우리가 여기에있는 단편 xml을 보면, 우리는 거기에 직접 설정되어 있지 않습니다

Layout Inspector를 살펴 보겠습니다 여기서 배경을 선택하면, 정말 잘 볼 수 있다면 우리는 배경색이 없다

이보기에서 직접 설정하십시오 왜 그럴까? 글쎄, 우리는 여기에서 가장 많은보기를 선택했습니다 배경색을 어느 정도 낮추어 놓을 수도 있습니다 뷰 계층 구조에서 그러나 어떤 시각이 설정되고 있습니까? 글쎄, 새로운 레이아웃 검사기가 우리에게 제공합니다

쉽게 찾을 수있는 방법 [크라우드 반응] [웃음] 3D보기에서는 어느 것이 쉽게 볼 수 있습니다 여기에서 무엇을 그리는가? 이제이보기를 선택하면 배경이 색상이 실제로 설정되어 있습니다 그러나 어떤 파일에 설정되어 있습니까? 이것은 선언 된 속성 섹션의 맨 위에 있지 않습니다 그래서 우리는 그것이이 견해에 직접적으로 설정되어 있지 않다는 것을 알고 있습니다

그러나 다시 한번 우리가 Attributes에서 속성을 선택하면 Panel, 거기에서 직접 탐색 할 수 있습니다 그것이 설정되는 곳으로 이 경우 스타일로 설정됩니다 그리고 우리는 그 스타일을 직접 탐색 할 수 있습니다 보기에 명시 적으로 참조되지 않는 경우에도 마찬가지입니다

우리가 본 3D 표현은 우리는 다른 방식으로 사물을 시각화하고, 여기서 유용한 정보를 계속 찾고 있습니다 예를 들어 초점을 맞추는 것이 유용 할 수 있습니다 한보기 및 그 자녀들에게 또는 무엇을 기반으로보기를 함께 그룹화하는 것이 유용 할 수 있습니다 그들이 정의 된 레이아웃 파일

이 화면의 예는 상단에서 볼 수 있습니다 우리는 RecyclerView 항목을 가지고 조각을 만든 다음, 활동 그리고 그 뒤에, 다양한 견해들 프레임 워크에 의해 정의됩니다 가벼운 새로운 레이아웃 검사기를 위해 더 많은 계획을 세웠습니다 저는 우리가 무엇을 생각해 낼 수 있는지에 대해 매우 기쁩니다

이제는 필요한 프레임 워크 변경 사항에 대해 이야기합니다 이것을 가능하게하려면 여기 애쉴리가 있습니다 애쉴리 로즈 : 고마워, 조 [박수 갈채] Android Q의 경우 세 가지 새로운 API가 추가되었습니다 이러한 새로운 검사 기능을 사용할 수 있습니다

우리는 모든 도면 명령을 수행 할 수 있습니다 화면에 프레임을 만들었습니다 그것을 직렬화하여 Studio로 다시 보내십시오 그래서 그것들을 재생할 수 있고 멋진 3D보기를 만들 수 있습니다 우리는 얼마나 길게 빨랐 는가? 뷰 계층 구조에서 뷰의 특성을 가져오고, 추가 메타 데이터를 추가 할 수 있습니다

그것을보다 정확하게 만드는 것입니다 그리고 우리는 리소스 프레임 워크에 몇 가지 새로운 API를 추가했습니다 속성 값의 출처를 보자 의사 결정에 대한 더 많은 통찰력 그 과정은 다음과 같은 경우에 적용되었다 해당 속성 값에 도달합니다

그럼 Skia Picture에 대해 이야기 해 봅시다 Skia는 UI 툴킷의 기초가되는 2D 그래픽 라이브러리입니다 이것은 실제로 슬라이드에 맞도록 단순화 된보기입니다 하지만 그것은 그리기 명령의 목록입니다 더 일찍부터 우리 여행 카드 중의 1 개를 형성하는 것에 들어간다

우리가 그것을 보았다면 그림자, 둥근 사각형, 이미지, 텍스트 – 그 모든 것들을 자산과 함께 그것을 렌더링하는데 필요한 이미지 데이터, 폰트 데이터 등을 포함한다 우리는 Skia에서 이것을 기본적으로 얻습니다 매우 빠릅니다 실시간 미리보기를 수행 할 수 있기 때문에 이걸 몇 초에 한 번하십시오 그것은 일반적으로 매우 작습니다

그러나이 문제는 우리가 스위치를 확대하려면 여기를 클릭하십시오 그것은 텍스트, 둥근 사각형, 그리고 서클 슬라이더 스위치에 대한 약간의 이미지 그것들이 어떤 관점에서 왔는지는 모른다 그들은 명령을 내리는 것입니다 그리기 명령을 그룹화하는 방법이 필요했습니다

그들이 어떤 시각에서 왔는지에 따라 우리는 렌더링 노트 API를 보았습니다 두보기의 기초가되는 조직 트리입니다 그리고 drawables– 우리는 각각의 렌더링 노트에 고유 한 ID를 추가했습니다 그런 다음이 고유 한 ID를보기에 노출 시켰습니다

Skia 그림 자체에 주석을 달았습니다 여기서 각 렌더 노드는 그리기를 시작하고 멈 춥니 다 스튜디오 측에서 보기가 시작된 위치와 중단 된 위치를 확인하고 연결할 수 있습니다 이 3 개의 그리기 명령은 다시 스위치보기로 돌아갑니다 또한 우리는 시작과 중지가 있기 때문에, 우리는 멋진 중첩 된 프레임 워크를 가지고 있습니다

HTML – 우리가 볼 수있는 모든 도면 명령이 다시 있습니다 단순화 된이 카드보기를 만드는 데 들어갔다 같이 [? 오랫동안도?] 그들이 시작하고 멈추는 전망, 우리는 중첩을 해봅시다 부동산 검사를 어떻게 수정하는지 조금 이야기 해 봅시다 Joe의 관점에서 일찍 – 모든 것이 게터 이름이나 메소드 이름이었습니다

그건 우리가 반사를 사용했기 때문이었습니다 런타임시 뷰 인스턴스 내부의 속성 반사는 세계에서 가장 빠른 것이 아닙니다 특히 휴대 기기에서 매우 복잡한 앱의 경우 전체보기를 렌더링하는 데 최대 몇 초가 걸릴 수 있습니다 계층

그래서 우리는 다음과 같은 접근 방식을 들여다 보았습니다 모든 것을 직렬화하는 메서드가 있습니다 그것은 조금 부서지기 시작합니다 보기에 새 속성을 추가하면 업데이트되지 않습니다 우리는 주석 처리기에 추가했습니다

그것은 우리가 반사를 유연하게 유지할 수있게 해줍니다 우리를 제공했다 특수 효과를 추가하기 만하면됩니다 새 게터를 추가하면됩니다 사용자 정의에 대해 어떻게 보일지 살펴 보겠습니다

이는 사용자가 누구에게나 관련이 있기 때문에 볼 수 있습니다 곧 라이브러리보기를 빌드하십시오 우리는 컬러보기를했습니다 속성은 색이며 주석을 달았습니다 InspectableProperty

주석 처리기가 보이면 그것으로 우리에게 조금 더 많은 맥락이 생깁니다 우리가 이전에 얻은 것보다 훨씬 낫습니다 그래서 우리는 Kotlin에 있고 @ColorInt 주석을 볼 수 있습니다 정수형뿐만 아니라 우리는이 정수에 색을 채웠다는 것을 압니다 그리고 그것은 단지 수치가 아닙니다

재산의 이름이 있습니다 우리는 속성 ID에 대한 추론을하는 데 사용할 수 있습니다 그것을 부르는 것 물론 우리는 주석에 대한 속성을 사용하여 추론하기 그 자체 그래서이 코드 생성은 어떻게 생겼습니까? 이 객체는 이 견해와 나란히 앉을 것이다

그 중 하나가 어떻게 생겼는지 살펴 보겠습니다 이것은 검사 동반자입니다 그것은 Q를위한 새로운 API입니다 두 가지 목적이 있습니다 하나는 클래스가 주어진 경우의 목록을 정의합니다

여기에 그 클래스에 정의 된 속성이 있습니다 이 경우 색상을 정의했습니다 지도 색상에 대한 호출을 살펴보면, 색깔이기 때문에 거기에 유형이 있습니다 우리는 속성 이름을 가지고 있고 유추했습니다 ID의 속성 R

attr 이것은 또한 우리가 – 추론 된 속성 ID가없는 경우, 또는 당신이 하나를 공급했다면 우리는 그것을 거기에 넣을 것입니다 내가보기에 Studio를 가르치면, 여기에 내가 가지고있는 속성이 있습니다 여기에 그들의 속성 ID가 무엇인지, 이것은 우리가 그 부분을 가능하게합니다 코드 완성 기능으로 이동하십시오

다음 단계는 실제로 우리가 보기의 인스턴스가 있으면 속성을 읽고 싶습니다 다시 말하지만, 우리의 견해가 Kotlin에서 정의되고 자바를 사용하고 있기 때문에 – 이것이 생성 된 코드이기 때문에 – 우리는 viewgetColor를 호출한다 직접 호출한다 getter에게 반사가 필요 없습니다

매우 빠릅니다 이를 통해 뷰 계층의 실시간 업데이트를 수행 할 수 있습니다 Studio에서는 우리가 가지고 있지 않기 때문에 우리가 전에했던 모든 추가적인 오버 헤드 우리를 얻는 모든 것이 현재의 가치에 달려 있습니다 우리가 말할 수있는 것은 여기에 우리가 가지고있는이 사랑스러운 푸른 색 텍스트 색입니다

우리는 그것이 무엇인지에 관계없이 말할 수 있습니다 그것이 런타임에 설정되었는지 여부 viewsetColor를 호출했을 수도 있습니다 또는 자원에 설정되어있는 경우

그러나 대부분의 속성 값은 자원에서 설정되며, 그래서 우리는 그 사건을 돕고 싶었습니다 우리는이 경우에, 그것은 위젯에 정의되어 있습니다 리소스에 API를 추가하여, 나는이 가치를 얻었다 그게 어디서 왔는지 말해줘 Google은 해당 데이터를 추적하여 전체 리소스를 통해 저장합니다

뼈대 또한, 우리는 통찰력을 얻고 싶었습니다 스타일이 어떻게 영향을 미치는지 그래서 자원 프레임 워크가 해결 될 때 속성 값 – 어떤 스타일을 적용할지 결정해야합니다 의사 결정 트리를 가져 와서 API를 추가하여이를 나타냅니다

근본적으로 고려 된 스타일 목록입니다 그러나 결국 사용되거나 사용되지 않을 수 있습니다 해당 속성 값을 해석하는 동안 이 모든 문제는 일시적인 현상입니다 왜냐하면보기, 일단 팽창되면, 그들은 그들의 관계를 잊는다 리소스

일단 그들이 건설되면, 그들은 그들이 어디에서 온 것인지 기억하지 못한다 개발자 옵션을 추가했습니다 속성 ID의 맵과, 그들이 왔던 곳, 스타일 해상도는보기의 테마에서 스택됩니다 그래서 스튜디오 – 준비가되었거나 관심이있을 때 재산으로 더 자세히 조사하고 싶어요 돌아와

보기로하고,보기에게 묻는다, 헤이, 어디에서 당신의 속성 값이 왔는지, 그들의 스타일은 무엇입니까? Q가 가진 모든 것을 꽤 많이 감쌌다 바딤과 제롬을 환영하고 싶습니다 우리를 감싸는 무대에 [박수 갈채] VADIM CAEN : 전체 툴 체인에 대해 들었습니다

그리고 집에 돌아갈 때 그것을 사용하기를 바랍니다 레이아웃 편집기로 레이아웃을 작성하고, 우리가 추가 한 새로운 기능 네비게이션 편집기로 네비게이션 만들기, 자원 관리자로 자원 관리, 새로운 레이아웃 검사기로 검사를 수행하십시오 올해 I / O에는 Android Studio 협상이 가득합니다 바로 뒤에 – 원형 극장에서 – 당신은 안드로이드 개발의 새로운 기능을 볼 수 있습니다

Tor 및 [? Ja ?] 그렇다면 당신은 2 단계의 Android 빌드 시스템의 새로운 기능 그것은 다른 쪽 위에있다 그것은 오늘 오후에 시작한다 여기에 빨간 점이 거의 없습니다 Android Studio 팁 및 트릭 제공 선별 된 엔지니어 및 프로젝트 매니저에 의해, 2 단계

마지막으로 내일, ConstraintLayout의 새로운 기능 Nicolas와 John의 모션 레이아웃 우리는 여기서 밖에 질문을 할 것입니다 와 주셔서 대단히 감사합니다 내년에 봐 [음악 재생]

Google Pay API Implementation Demo (Android)

(내레이터) Android 용 Google Pay API를 사용하면, 당신은 당신의 사용자를위한 지불 거래를 촉진 할 수 있고, 응용 프로그램에서 체크 아웃을보다 편리하게 사용할 수 있습니다 오늘 Google Pay를 사용하는 다른 비즈니스에 가입하십시오

사용자 증가, 전환 증가, 데이터 노출 및 트랜잭션 취약점을 줄입니다 다음은 Google Pay를 통합하는 방법입니다 네 가지 간단한 단계를 거쳐 Android 애플리케이션에서 프로젝트 구성; 지불 할 준비를 결정한다 Google Pay 버튼을 표시합니다 PaymentDataRequest 오브젝트를 작성하십시오

먼저 Google Pay 라이브러리를 종속성 목록에 추가합니다 귀하의 응용 프로그램 모듈에 사용 가능한 최신 버전을 확인하려면 설명서를 검토하십시오 또한 매니페스트 에서 Google Pay API를 사용하도록 설정해야합니다 다음 태그를 추가하면됩니다

애플리케이션 노드 내부 준비가 되 자마자 Google Pay 버튼을 표시 할 활동을 엽니 다 그리고 paymentsClient의 새로운 인스턴스를 취득합니다 귀하의 onCreate 메소드 내부 getPaymentsClient 메서드는 walletOptions 매개 변수를 사용합니다 이 클래스의 정의를 사용하여 환경을 지정하십시오

당신이 원하는, 테스트 또는 생산 TEST 환경에서는 Google에 등록 할 필요가 없습니다 API로 직접 게임하고 애플리케이션에 통합 할 수 있습니다 이 경우 실제 지불 정보를 사용할 수 있습니다 그러나 선택이있을 때마다 우리는 당신에게 청구 할 수없는 토큰을 돌려드립니다

환경 테스트에서 실제 카드 정보가 사용되지 않는다는 것을 기억하십시오 단 하나의 유료 카드를 Google 계정에 추가해야합니다 계속하기 전에 통합을 완료하고 실제 지불을 처리 할 준비가되면, 셀프 서비스 포털을 통해 우리와 함께 등록하십시오 그런 다음 환경을 PRODUCTION 으로 바꿉니다

프로덕션 액세스를 신청할 수 있습니다 gco/pay/signupup에서 이제 paymentsClient가 생성되었으므로, 호출해야하는 첫 번째 API는 IsReadyToPay 입니다 IsReadyToPay 사용 사용자가 유효한 결제 수단을 파일에 가지고 있는지 여부를 확인할 수 있습니다 지원되는 장치에서 트랜잭션을 완료 할 수 있습니다 이 요청은 API 버전을 지정하는 매개 변수를 사용합니다

귀하의 전화를 타겟으로, 이 거래에 허용 된 결제 수단뿐 아니라 Google은 전환 최적화를 중점적으로 다룹니다 IsReadyToPay 가 false를 반환하면, 우리는 강력히 추천한다 Google Pay 버튼을 표시하지 않습니다 이제 사용자가 Google Pay를 사용하여 지불 할 준비가되었음을 알았으므로, 버튼을 사용자에게 보이게 할 수 있습니다 개발자 설명서에서 그래픽 공유를 사용하는 것이 좋습니다

Google Pay 브랜딩이 올바르게 사용되도록하기 최신 지침에 따라 이 번들에서는, 드로어 블 및 레이아웃 리소스를 찾을 수 있습니다 서로 다른 화면 크기와 해상도에 맞게 조정할 수 있습니다 여러 언어로의 번역 버튼의 텍스트입니다 사용자가 버튼을 탭하면, 당신은 loadPaymentData (request) 를 호출한다 지불 시트를여십시오

PaymentDataRequest 객체를 생성 할 수있다 이는 특정 거래에 사용 된 지불 구성 세트입니다 추가 정보를 요청할 수 있습니다 배송 주소 및 이메일 주소와 마찬가지로, 결제 자격 증명 외에도 필요한만큼 정보를 수집하는 것이 좋습니다 사용자가 추가 정보를 입력하는 것을 방지하기 위해 계정에 저장되지 않을 수 있습니다

이 객체에서 호출 할 수있는 또 하나의 요점 PaymentRequest 토큰 매개 변수입니다 Google은 사용자가 선택한 카드에 대한 정보를 암호화합니다 가맹점의 보안 처리를위한 게이트웨이 또는 상인의 보안 서버에 직접 연결하십시오 프로세서의 통합 지침을 확인하십시오 지불을 확정하는 데 필요한 것을 알아 내야합니다 이제 요청 객체를 생성했습니다

당신은 loadPaymentData에 그것을 전달할 수 있습니다 – 지불 시트를 여는 비동기 작업 사용자가 선택을하면, 우리는 활동 결과로 PaymentData 오브젝트를 리턴합니다 사용자 선택에 대한 메타 데이터로 구성됩니다 또한 지불 토큰이 포함되어 있습니다 거래를 완료하는 데 사용할 수 있습니다

이제 최종 제작 준비 애플리케이션을 Google에 보낼 수 있습니다 최종 테스트 Google은 실제 카드로 앱을 테스트합니다 모든 것이 맞는지 알려줍니다 그런 다음 앱이 실행되도록 초기화됩니다

개발자 문서에서 추가 정보를 찾을 수 있습니다 gco/pay/api에서 Google Pay 및 Android에 대한 향후 동영상을 놓치지 마세요 Android 개발자 채널에 가입하십시오 모바일로 시청하는 경우, 새 벨소리 알림을 받으려면 작은 벨을 살짝 누르십시오

곧 뵙겠습니다!

Quick Walkthrough of a Google Compute Engine API Sample for Android

PAUL RASHIDI : 안녕하세요 저는 Paul Rashidi, 개발자 프로그램 엔지니어입니다

Google Cloud Platform에서 저는 Compute Engine과 모바일 앱에 대해 매우 열정적입니다 너무 오래 전, 나는 일을 시작했다 둘 다 사용하는 일부 응용 프로그램에서는 거기에 다른 개발자가 있다는 것을 알고 있습니다 비슷한 일을하고 싶기 때문에 최근에 소스를 오픈했습니다 샘플 앱

앱 데모를 보여 드리겠습니다 그런 다음 건물을 짓는 과정에 대해 간단히 이야기하십시오 Android Studio에서 GitHub의 샘플 앱에 포함 된 readme 파일 직접 앱을 배포하는 방법을 설명합니다 그래서 당신은 자신의 안드로이드 장치에서 실행되도록 할 수 있습니다 먼저 데모

응용 프로그램은 CE API Java를 사용하는 간단한 응용 프로그램입니다 클라이언트 라이브러리를 사용하여 프로젝트 자원 정보를 검색하십시오 모든 활성 리소스에 대한 정보를 가져옵니다 이전에 등록한 개발자 프로젝트에서 가져 왔습니다 보시다시피 로그인 페이지부터 시작합니다

여기서 Google 계정을 선택할 수 있습니다 샘플 계정을 선택하겠습니다 이 계정 목록은 Google 계정에서 가져옵니다 Android 기기에 등록 된 경우, 사용자가 비밀번호를 다시 입력하지 않아도됩니다 이제 코드를 완성했습니다

코드는 Android에 OAuth를 요청합니다 해당 계정의 20 토큰 (Compute의 OAuth 20 범위 포함) 엔진 및 클라우드 스토리지 나는이 프롬프트를 받아 들일 것이고, 이제는 OAuth 2

0 액세스 토큰을 검색 할 수 있습니다 OAuth 20 액세스 토큰을 상기시켜드립니다 시간 제한된 권한 부여 문자열입니다 Compute Engine에 대한 액세스를 제공하는 사용자를 대신하여 클라우드 스토리지 API를 제공합니다

다음으로 개발자 프로젝트의 프로젝트 ID를 입력합니다 Google 계정에 대한 액세스 권한이 있습니다 이것은 분명히 이미 프로젝트가되어야합니다 CE를 사용하거나 적어도 API가 활성화되어 있어야합니다 이 값은 프로젝트 이름 문자열 또는 우리가 콘솔에서받는 프로젝트 번호

이 리소스보기 버튼을 클릭합니다 새로운 활동이 호출됩니다 이 응용 프로그램은 백그라운드에서 CE API와 대화합니다 자원 정보를로드합니다 우리는 몇 개의 인스턴스와 디스크가 있음을 알 수 있습니다

우리 프로젝트가 접근 할 수있는 구역으로 이 인스턴스가 예정된 정전이 있습니다 이것은 실제로 이전에 삭제하려는 인스턴스입니다 그래서 우리는 이것을 조사하고 삭제할 것입니다 다시, 앱은 CE API와 비동기 적으로 삭제를 수행합니다 아주 간단한 앱

이 앱에서는 Android 마스터 세부 정보를 사용하기로 결정했습니다 견본 따라서 태블릿에서 앱을 실행하는 경우, 첫 번째와 두 번째 활동을 멋지게 결합한 것을 알 수 있습니다 함께 이것은 직장에서 안드로이드 조각이지만, 이것에 대한 자세한 내용 후에

이제 코드를 살펴 보겠습니다 코드를 살펴보기 위해 그것을 검색해야 할 것입니다 그렇게 쉬운 일입니다 우리는 Git을 사용하여 소스 코드를 체크 아웃 할 것이다 가져 오기 옵션을 통해 프로젝트를 가져옵니다

Android Studio에서 우리는 최고 수준의 프로젝트를 선택하고, Gradle 래퍼 옵션을 사용하고 가져옵니다 여기에서 문제가 발생하면 readme를 참조하십시오 보다 포괄적 인 지침을 보려면 코드 저장소를 참조하십시오 이제 코드가 생겨서 우리에게 가장 쉬운 방법입니다 이 프로젝트를 이해하는 것은 코드를 보는 것입니다

그것이 헌신 된대로 첫 번째 커밋을 볼 수 있습니다 프로젝트 마법사가 생성 한 코드이며 주로 Git 무시 항목을 정의합니다 구조는 Eclipse 환경과 조금 다릅니다 보시다시피, 우리는 build 디렉토리를 제외하고 있습니다

아이디어와 Gradle 숨겨진 디렉토리 이 모든 파일은 주 파일에서 유추되어야합니다 Gradle 파일을 작성하십시오 따라서 체크인 할 필요가 없습니다 우리는 또한 lib 디렉토리를 제외합니다

Maven을 통해 의존성을 끌어 들이기 때문에 vis a vis Gradle 조금 나중에 Gradle에 대해 자세히 설명합니다 프로젝트 마법사 커밋의 경우 모든 기본값을 사용했습니다 단 최소한의 SDK 11을 선택했다 그래서 나는 안드로이드 조각을 사용할 수있게했다

이것은 내가 마스터 세부 사항을 사용할 수있게했다 샘플 내 애플 리케이션의 기초로 버전 11을 선택하지 않아도됩니다 자신의 앱을 만들고 파편을 원하지 않습니다 하지만 나는 타블렛의 단순함을 좋아한다

우리가 이전에 본 인터페이스 다음 커밋은 두더지입니다 API 상호 작용 코드가 추가되었습니다 프로젝트에 CE API를 사용하는 모든 코드는 여기에 있습니다

우리는 사용자 인터페이스에서 네트워크 호출을 유지할 필요가 있기 때문에 실 기본적으로 API 스텁을 인스턴스화하는 것을 볼 수 있습니다 명령을 작성한 다음 명령을 실행하십시오 삭제 명령의 경우, 우리는 추가 상태 호출을하려고합니다 완료 될 때까지 기다리십시오

이 커밋에서 나는 또한 덧붙였다 로그인 활동 이는 샘플 로그인 활동입니다 Android 스튜디오에서 마우스 오른쪽 버튼을 클릭하여 만들 수 있습니다 이런 식으로

마지막으로 중요한 변경 사항을 알 수 있습니다 이 커밋의 buildgradle 파일에 있습니다 Gradle에 익숙하지 않은 경우, 그러면 당신은 아마 사실을 잊어 버릴 수 있습니다 빌드를 정의하는 새로운 방법입니다

이 스 니펫은 특히 모든 종속성을 정의함으로써 Maven 의존성으로 Android Jars 용 Google 클라이언트 라이브러리, Compute의 표면 확장뿐만 아니라, 이 라인 때문에 프로젝트에 추가됩니다 스 니펫은 Maven을 사용하지만 여전히 SDK 관리자를 통해 라이브러리를 다운로드해야합니다 스 니펫의 주석을 읽으십시오 특정 패키지에 대해서는 완전히 업데이트해야합니다

다음 커밋은 로그인 활동을 구현하도록합니다 Google 계정 자격증 명을 사용합니다 Android 인식 자격 증명입니다 기기에서 Google 계정을 다시 사용합니다 애플리케이션에 OAuth 2

0 토큰 액세스를 허용합니다 마지막으로 흥미로운 커밋 자원 목록의 구현이다 이전에 체크인 한 비동기 작업에 연결합니다 이 커밋에서 우리는 XML 레이아웃을 조정했다 파일을 사용하여 리소스를 표시하고 목록 및 세부 정보를 업데이트했습니다

조각을 사용하여 인스턴스, 디스크 및 영역을 표시합니다 그것이 코드에 관한 것입니다 정말 일부 응용 프로그램을 보길 고대하고 있습니다 Compute Engine API를 사용하는 휴대 기기에서 시간 내 주셔서 감사 드리며 GitHub에서 우리 프로젝트에 별표를 던지거나 동영상이 유용했음을 나타냅니다 고맙습니다

DevBytes: Google Drive Android API

[음악 재생] 거대한 HYTTSTEN : 안녕하세요 내 이름은 Magnus Hyttsten이고 나는 Google의 개발자 관계 팀에서 일하십시오

새롭고 흥미로운 API에 대해 이야기하겠습니다 Google 드라이브 Android API를 출시했습니다 여기 내가 오늘 다룰 계획입니다 우선 Google 드라이브 Android API는 무엇인가요? 그런 다음 기능에 대해 이야기하겠습니다 아주 흥미 진진한 두 가지 이야기를하기 전에 투명한 오프라인 동기화 및 사용자 인터페이스 구성 요소

마지막으로 Google 드라이브 Android API는 스토리지 액세스 프레임 워크와 관련이 있습니다 KitKat과 함께 출시 된 API 먼저 Google 드라이브 API 란 무엇입니까? Java로 작성된 기본 Android API입니다 Google 드라이브 콘텐츠에 액세스합니다 이때, 전에 물어 보지 않았습니까? 그리고 대답은 '예'이지만 기본 Android API는 아닙니다

그리고 이것은 매우 중요합니다 왜냐하면 우리는 많은 기능을 추가했습니다 빛나는 1 급 Google 드라이브를 만들 수 있습니다 땀을 흘리지 않고도 Android에서 앱을 사용할 수 있습니다 이 API를 매우 유용하게 만드는 기능 중 하나 Google Play 서비스에 통합 된 것입니다

그래서 안드로이드 장치의 핵심 부분입니다 그리고 여기에는 몇 가지 중요한 이점이 있습니다 우선, 이것은 앱의 크기를 크게 줄입니다 그것은 완벽합니다 앱을 더 빨리 다운로드 할 수 있기 때문에, 그것은 자주 업데이트 될 필요가 없습니다

또한 앱 실행 빈도가 줄어 듭니다 예를 들어, 그것은 많은 메모리를 차지하지 않을 것입니다 물론 대단한 것 하지만 아마도 더 흥미 진진한 측면 Google Play 서비스 통합 API가 호환 될 것입니다 진저 브레드로 시작하는 모든 기기에서 실행됩니다

그리고 이것으로는 별 도움이되지 않습니다 거기 안드로이드 장치의 98 %가 포함됩니다 즉, 안심할 수 있습니다 이 API는 모든 사용자가 사용할 수 있습니다 장치가 조금 밖에 없어도 사용하지 못할 수도 있습니다

그러나 대부분은 그렇게 할 것입니다 이로 인해 API의 기능이 향상되었습니다 그래서 필요한 모든 것 훌륭한 Google 드라이브 앱을 만드는 방법 API에 포함되어 있습니다 파일 및 폴더를 읽고, 쓰고, 업데이트 할 수 있으며, 폴더 트리를 트래버스하고, 메타 데이터를보고 업데이트합니다 파일 선택기 사용자 인터페이스가 있습니다

또한 투명한 오프라인 동기화 기능을 사용할 수 있습니다 이제 투명 오프라인 동기화가 있음을 이야기하겠습니다 우선 첫째로 안드로이드 장치는 로컬 저장소입니다 Google 드라이브 스토리지는 클라우드에 있습니다

자, 모바일 장치에 대한 하나의 작은 특이한 점 네트워크 연결을 결코 신뢰할 수 없다는 것입니다 그것은 항상 네트워크를 변경하고 네트워크 액세스가 전혀없는 경우가 많습니다 이는 클라우드에 물건을 저장하는 것을 어렵게 만듭니다 하지만 Google 드라이브 API가 아닌 Google 드라이브 Android API, 우리는 당신의 앱이 데이터를 쓸 때 결코 실패하지 않을 것입니다 또한 Google 드라이브와의 통신이 불가능한 경우, API는 일시적으로 데이터를 로컬에 저장합니다

Google 드라이브에 동기화합니다 일단 연결이 다시 설정되었습니다 안드로이드 개발자로서 당신에게 이것은 물론, 위대한, 모든 오류 관리가 필요하기 때문에 당신의 마음에서 네트워크 문제로 인한 Google 드라이브 Android API의 또 다른 멋진 기능 사용자 인터페이스 구성 요소입니다 그리고 API의 첫 번째 릴리스에서는 폴더 및 파일 탐색 및 선택기가 있습니다

이렇게하면 응용 프로그램을 작성하는 것이 정말 쉽습니다 사용자는 폴더 또는 파일을 선택해야합니다 이 파일 선택기를 표시하면됩니다 어떻게 그걸합니까? 음, 우선, 당신은 의도를 만들고, 파일 활동 빌더를 엽니 다 그런 다음 실제 마법은 의도가 시작되면 발생합니다

사용자는 파일 또는 폴더를 선택할 수 있습니다 필요 사용자가 파일을 선택하면, 결과는 onActivityResult 메소드에서 사용할 수 있습니다 Android에서 늘 그렇듯이 마지막으로 콘텐츠의 드라이브 ID를받습니다 너와 함께 일할 수있어

마지막으로, KitKat에 대해 몇 마디 말하고 싶습니다 저장 용량 API 및 Google 드라이브 Android와의 관련성 API 둘 다 정보에 액세스하고 저장할 수 있지만 Google 드라이브에는 몇 가지 근본적인 디자인 차이가 있습니다 첫 번째는 Google 드라이브 Android API 전용입니다 Google 드라이브에서 작동합니다

이를 통해 Google은이 API에 Google 드라이브에서만 사용할 수 있습니다 반면에, 스토리지 액세스 프레임 워크 제네릭 API입니다 그리고 이것으로 여러 다른 백엔드에서 작동 할 수 있습니다 스토리지 기술은 Google 드라이브뿐만 아니라, 단일 인터페이스를 사용합니다 여기에는 큰 차이가 있습니다

당신이 아주 단단하고 좋은 통합을 할 계획이라면 앱용 Google 드라이브를 사용하려면 그러면 Google 드라이브 Android API가 완벽합니다 Google 드라이브의 또 다른 기능은 개발자가 안전하게 추측 할 수있는 것 사용자가 이미 Google 드라이브에 로그인했음을 나타냅니다 스토리지 액세스 프레임 워크가 우수합니다 앱이 여러 저장소에 액세스해야하는 경우 기술뿐만 아니라 드라이브 그리고 물론,이 모든 것을 말하면서, 너를 멈추게하는 것이 아무것도 없어

둘 다 동시에, 물론 – 모든 Google 드라이브 별 기능 및 일반적인 통합 다른 스토리지 기술과 함께 스토어 액세스 프레임 워크는 KitKat에서 작동하는 장치에서만 작동합니다 그게 오늘 제가 당신에게 선물하기를 원했던 것입니다 Google 드라이브 Android를 시작하게되어 매우 기쁩니다 API 및 포함 된 기능

이제 밖으로 나와 멋진 앱을 만듭니다 이 Android 및 드라이브 API를 사용합니다 그리고 우리에게 그것에 대해 모두 말해주는 것을 잊지 마십시오

Migrate your existing app to target Android Oreo and above (Google I/O '18)

[음악 재생] 알았어 "Android 앱 마이그레이션"에 오신 것을 환영합니다

Android O 및 그 너머에 " FRED CHUNG : 안녕하세요 나는 개발자 옹호자 프레드 정입니다 Dan GALPIN : 안녕하세요, 저는 개발자 Galphin입니다 ERIC KUXHAUSEN : 안녕하세요, 저는 개발자 대변자가 아닌 에릭입니다

저는 마이그레이션을 담당하는 리드 소프트웨어 엔지니어입니다 API 26을 타겟팅 할 Google Play 스토어 앱 단 갈린 : 오후에 우리와 함께 해줘서 고마워 마지막 날의 가장 기대되는 세션을 예약하는 곳입니다 우리가 기록하지 않는 재미있는 즉흥적 인 것을 제외하고 죄송합니다

집 시청자입니다 그래서 네가 진짜 여기있는거야 구글 I / O의 대단원 FRED CHUNG : 음, 대단원이 시작됩니다 그렇다면 왜 마이그레이션해야합니까? 많은 이유가 있지만, 무엇보다도 마음에, 특히 Google Play에서 배포하는 경우, 올해 말까지 2018 년 8 월에 새로운 앱이 출시 될 예정입니다 최소한 API 레벨 26 또는 Android 8

0을 타겟팅해야합니다 마찬가지로 앱 업데이트의 경우에도 앱 업데이트가 필요합니다 2018 년 11 월까지 최소 API 수준 26을 타겟팅해야합니다 다시 말해서 앞으로 앱 업데이트 DAN GALPIN : 이제 모든 새로운 Android 버전 중요한 보안을 가져 오는 변경 사항을 소개합니다

성능 향상 및 경험 향상 전체적으로 Android 이러한 변경 사항 중 일부는 명시 적으로 선언 한 앱에만 적용됩니다 타겟 SDK 버전 매니페스트 속성을 통한 지원, 타겟 API 레벨이라고도합니다 실제로 타겟을 사용하여 APK를 업로드하려고하면 SDK가 26 미만이면 친숙한 알림을 볼 수 있습니다 이런 식으로 ERIC KUXHAUSEN : 저는 우리가 여기 있기 때문에 여기 있습니다

Google Play에서 Play 스토어 앱을 계속 업데이트하고 싶었습니다 11 월 마감 이후 프레드 (FRED CHUNG) : 그래서 몇 가지 기본 사항을 빠르게 살펴 보겠습니다 각자 모두 최소 SDK는 가장 낮은 플랫폼 버전입니다

앱이 기꺼이 지원할 것입니다 종종 시장 침투와 관련된 결정입니다 다양한 Android 출시 DAN GALPIN : 컴파일 SDK는 말 그대로입니다 프로젝트가 링크하는 SDK 헤더 및 스텁 라이브러리 ERIC KUXHAUSEN : 중요한 것은 물론, 내가 말하는거야 targetSdkVersion은 플랫폼의 방식입니다

하위 호환성을 보장합니다 즉, 특정 행동 만 취할 수 있습니다 변경 사항은 특정 특정 대상 SDK 버전으로 적용됩니다 FRED CHUNG : 기술적으로 이것은 사실 일 필요가 있습니다 그리고 이것은 전형적이고 권장되는 사례입니다

당신이 아마 걱정하기 때문에, 대략 95 %의 사용자 최신 버전을 대상으로하지는 않습니다 Androids의 버전은 아직 그것을 개선하기 위해 노력하고 있습니다 DAN GALPIN : 목표를 변경하지 않으면 SDK가 버전 26 이상인 경우 런타임 권한과 같은 것을 처리해야하며, AlarmManager가 변경되어 다양한 방법으로 작동합니다 BroadcastReceiver 동작을 처리하려면, 배경 서비스를 피할 수 있습니다 ERIC KUXHAUSEN :하지만 좋은 기회가 있습니다

앱이 네트워크 및 배터리를 낭비 할 것이라는 점, 장치의 경험을 덜 빠르고 유동적으로 만듭니다 프레드 (FRED CHUNG) : 프리 -M 버전에서 마이 그 레이션하는 경우, 더 큰 변화 중 하나는 아마도 지원 일 것입니다 런타임 권한 런타임 권한은 실제로 사용자 개인 정보 보호 및 신뢰에 관한 것입니다 하지만 앱이 민감한 권한을 요청할 수도 있습니다

문맥 그리고 그것은 애플 리케이션을위한 좋은 일이다 누군가 당신의 앱을 설치하지 않기를 원하기 때문에 당신이 허락을 구하고 있기 때문에 하나의 특정 흐름에있는 민감한 정보 앱 내에서 따라서 우선, 모든 권한이 아닙니다 런타임 것들이 간단하고, 이것을 기억하기 쉽습니다 FRED CHUNG : 개발자는 걱정하지 않습니다

사용 권한을 생각할 수 있습니다 사용자는 이러한 광범위한 범주의 측면에서 볼 수 있습니다 그리고 당신이 가지고 있어야 할 첫 번째 질문 앱이 정말로 조항을 필요로하는지 여부입니다 결국 허가를 제거하는 것은 쉽습니다 자, 에릭, Play 스토어 앱에서 어떻게 처리 했습니까? ERIC KUXHAUSEN : 간단합니다

당신이해야 할 일은 앱이 시스템 이미지에 대한 권한을 미리 부여했습니다 FRED CHUNG : 그건별로 도움이 안돼, Eric ERIC KUXHAUSEN : 말하자면, 우리도 시도하고 사용합니다 가능한 한 이들 중 적은 수만큼 DAN GALPIN : 물론, 앱이 아직 준비되지 않았기 때문에 M을 타겟팅한다고해서 사용자가 가서 원하지 않는 권한을 비활성화하십시오

FRED CHUNG : 특별 권한이 있습니다 얻기 위해 사용자를 설정으로 리디렉션해야합니다 예를 들어, 오버레이 창 그리기, 또는 일부 행렬 권한이 될 수 있습니다 같은 화면 캡처 단 갈린 (DAN GALPIN) : 이제 UI의 작업으로, 런타임 권한은 실제로 활동이나 프래그먼트가 필요합니다

onRequestPermissionResult를 재정의 한 방법 자, 이것은 당신의 뷰 레이어, 활동과 파편과 같은 실제로 필요한 모든 사용 권한을 예상한다 다른 층에 의해 자, 대단한 변화가 있습니다 알람에 대해 이야기 해 봅시다

Android의 알람은 두 가지 기본 형식을 취합니다 앱이 스스로 깨어나도록 허용하는 리터럴 알람입니다 실시간 이벤트에 대한 알림을 전달하기 위해 당신을 깨우는 것과 같은 약속 또는 곧 예정된 약속 또는 그들은 일을 스케쥴링하는 방법입니다 앱이 종료 된 후 얼마 후에 발생합니다 Android 초기에는 단일 API였습니다

하지만 KitKat을 통해 AlarmManager가 정확하지 않게되었습니다 명시 적으로 요청되지 않은 한, 향후 작업 일정을 수립 할 때 더 좋습니다 이제 앱이 정확한 시간에 사용자에게 알릴 필요가 있다면, setExact 메소드를 추가했습니다 여기에 우리가 구현 한 곳이 있습니다 KitKat 이상에서이를 호출하는 지원 라이브러리의 메소드

ERIC KUXHAUSEN : Play 스토어에서 정확한 알람을 사용하지 않습니다 앱 우리가 사용하는 알람은 정확하지 않습니다 시스템이이를 더 잘 배치 할 수있게 해준다 배터리 및 시스템 상태

DAN GALPIN : 이제 Android Marshmallow Android를 유휴 상태로 만들 때 경보는 일반적으로 발화합니다 그래서 우리는 명백한 메소드 인 setExactAndAllowWhileIdle을 추가했습니다 알람을 울리면 장치를 깨울 수 있습니다 그리고 우리는 그 지원 라이브러리에 메소드를 구현했습니다 게다가

그리고 실제로 이전 지원 라이브러리를 호출합니다 이전 플랫폼 버전의 setExact 메소드 FRED CHUNG : 그래서 그 박람회가 끝나면, 테이크 어웨이는 꽤 간단합니다 맞습니까? WorkManager를 통해 향후 작업을 GCM 작업으로 옮기는 것을 고려하십시오 WorkManager는 새로운 작업 스케줄링 작업입니다 우리가 시작했다

DAN GALPIN : 이제 WorkManager는 Jetpack의 일부입니다 그리고 당신의 임무를 수행하는 가장 좋은 방법을 선택합니다 API 버전 및 앱 상태와 같은 항목을 기반으로합니다 안정적으로되면 권장 API가됩니다 우리가 무언가를 생각해 내지 않으면 그전에는 더 좋았어

ERIC KUXHAUSEN : Play 스토어에서 우리의 배경을 볼 수있었습니다 작업은 정기적으로 KitKat에서 2 % 더 많은 사용자에게 도달합니다 우리가 Firebase JobDispatcher를 채택했을 때, 단지 알람을 사용합니다 이렇게하면 시스템 상태 및 배터리 사용이 향상됩니다 알람을 사용해야 할 경우 가장 정확한 알람을 사용하십시오 너는 할 수있어

FRED CHUNG : 이제, 가장 정확한 경보, [INAUDIBLE]처럼 15 분마다 사용해야합니다 따라서 당신은 현명하게 그것들을 사용해야 만합니다 DAN GALPIN : 오, 예, WorkManager입니다 그럼 BroadcastReceiver에 대해 다시 이야기합시다 FRED CHUNG : 우리는 BroadcastReceiver에 대해 이야기해야합니까? DAN GALPIN : 우리는 그들에 대해 이야기해야합니다

FRED CHUNG : 그렇게하자 DAN GALPIN : 네 FRED CHUNG : 그래서 BroadcastReceiver, 저는 많은 사람들이 아마 그걸 알 것 같아, 그렇지? 플랫폼에서 알림을 보내고 실행하는 데 사용됩니다 시스템 전반의 이벤트에 대한 응답으로 Android에서 강력한 API를 제공하는 이유 중 하나입니다 서비스

DAN GALPIN : 이제 커다란 힘이 엄청난 책임입니다 그리고 이러한 엔드 포인트의 방식에 대한 응답으로 사용 된 경우 대부분이 더 이상 앱을 시작할 수 없으며, O를 목표로 한 번 이상 FRED CHUNG : 물론, 예외가 있습니다 안드로이드 맞지? 이들 중 상당수는 매우 드물게 발생하지만, 로케일 변경 등 또는 어떤 경우에는 아직 대안이 없습니다

그 (것)들을 필요로하는 apps를위한 방송에, 예를 들면, 그 USB 액세서리 것들처럼 브로드 캐스트 사용을 피하는 방법에 대한 예를 확인해 봅시다 따라서 직장에서는 적절한 실행을 설정하여 그렇게 할 수 있습니다 기준, 네트워크 서비스 요구, 그런 다음 우리는 기능을 가질 수 있습니다 이는 네트워크 상태 변경 수신 대기와 유사합니다

방송 그리고 매니페스트에 이와 같은 코드가 있다면 이전 버전의 Android에서는 연결 변경에 대한 리스너를 비활성화 할 수 있습니다 그냥 사용 안함으로 두십시오 그리고 나서, 당신은 무엇을 할 것입니까? 그런 다음 수신기를 설정하여 PackageManager의 ComponentEnableSetting입니다 ERIC KUXHAUSEN : 또 다른 예외 팩을 마친 후에 많은 작업을 수행해야하는 경우입니다

예를 들어 알람을 다시 예약하거나 업데이트 귀하의 데이터베이스 수신기를 등록 할 수 있습니다 action_my_package_replaced에 대한 매니페스트에서, 그것은 계속 작동합니다 앱을 겨냥한 명시적인 브로드 캐스트 중 하나 DAN GALPIN : 자, 정말로 필요하다면 모든 패키지 업데이트에서 어떤 작업을 수행하려면, 당신은 아마 당신이하지 않기 때문에 action_package_replace_events에서 더 이상 시작할 수 없습니다

그러나 우리는 getChangedPackages라는 API를 가지고 있습니다 앱에서 무엇을 볼 수있게 해주는 패키지는 이전 저장된 일련 번호 이후로 변경되었습니다 지금 인생에서 달리기는 대개 건강합니다 나는 아마 더 많이해야한다 하지만 Android 앱은 가능한 한 작게 운영되기를 원합니다

그리고 게으른 앱은 사실 더 나은 앱입니다 그리고 나는 선언문이나 뭔가를 만들어야한다 프레드, 우리가 실제로해야 할 일이 뭐라고 생각하니? FRED CHUNG : 나에게 좋은 소리 우선, 무엇에 대해 이야기 해 봅시다 그것은 전경에 있다는 것을 의미합니다

완전히 명백하지 않기 때문에 그렇습니까? 다음과 같은 몇 가지 일반적인 경우가 있습니다 앱이 사용자에게 표시되거나 사용자가 볼 때 전경 서비스를 사용하거나 앱이 전경 앱에 묶여있다 그래서 앱도 전경에 있습니다 이 예외적 인 경우에 앱이 보이지 않을 때 배경에 있습니다

표준 서비스를 실행하는 경우, 작업 서비스 또는 BroadcastReceiver 그리고 당신이 O +에있을 때 백그라운드에서 실행할 때 서비스 시작 IllegalStateException이라는 예외를 throw합니다 그것은 좋지 않다 DAN GALPIN : 이제 서비스를 시작할 수 있습니다

앱이 포 그라운드에 있습니다 그리고 그들은 약 1 분 동안 계속 달릴 것입니다 귀하의 앱이 배경으로 된 후에 그리고 이것은 특히 중요합니다 왜냐하면 O에서 시스템은 앱이 보유하고있는 모든 웨이크 잠금 장치 활동과 같은 활동적인 구성 요소가없는 경우 또는 서비스

O를 타겟팅하는 앱뿐만 아니라 모든 앱에 적용됩니다 FRED CHUNG : 앱이 여전히 작동하는 몇 가지 경우가 있습니다 포 그라운드라면 실행할 수 있음 예를 들어 알림에 대한 응답으로 서비스를 시작합니다 액션, 우선 순위가 높은 Firebase Cloud 메시지, 또는 MMS 또는 SMS 배달에 대한 응답으로 이제 몇 가지 솔루션을 살펴 보겠습니다

백그라운드 서비스없이 백그라운드에서 실행됩니다 DAN GALPIN : 우선, GCM 소방 작업을 사용하십시오 – 아! – 백그라운드 작업을위한 WorkManager 이제는 이것에 대한 많은 이유가 있습니다 여러 Android에서 일관된 API 서비스를 만듭니다 예를 들어, 버전

ERIC KUXHAUSEN : 또는 당신이 가진 것에 대해별로 신경 쓰지 않는다면 앱은 플랫폼간에 일관되게 작동하며, 또는 최소한의 작업량으로 O로 이동하려는 경우, JobIntentService를 사용할 수도 있습니다 DAN GALPIN :하지만 진지하게 WorkManager 사용을 고려하십시오 제약 조건을 활용하고 삶을 편하게 만듭니다 ERIC KUXHAUSEN : Google Play 스토어 앱 WorkManager를 사치스럽게 사용하지는 않았지만, 왜냐하면 그것은 아직 존재하지 않았기 때문입니다 그건 우리가 JobScheduler와 Firebase를 사용해야한다는 것을 의미했습니다

JobDispatcher 자, 우리가 처음 배운 것은 Android L에서 JobScheduler를 사용하려면, 당신이 정말로 어떻게 이해하지 못한다면 다음과 같은 경우 알람이 울리며 작동합니다 예상대로 작동하지 않습니다 또한, 대안을 사용하십시오 예를 들어, L과 M의 첫 번째 릴리스에서, JobScheduler는 실제로 당신의 업무를 수행하지 않을 것입니다

동일한 제약 조건이 충족 된 두 개의 작업이없는 한 두 가지 작업을 예약하여이 문제를 해결할 수 있습니다 일치하는 제약 조건 DAN GALPIN :하지만 WorkManager처럼 진지하게 FRED CHUNG : WorkManager ERIC KUXHAUSEN : JobScheduler의 상황이 훨씬 나아졌습니다

M, MR1 이상 그러나, 또 다른 특질은 당신이 최소 대기 시간을 0으로 설정하는 것을 피해야합니다 이것은 오버라이드를 방해 할 수 있습니다 일부 릴리즈의 마감일 재정의 기한은 당신의 일은 일정 기간 동안 계속됩니다

제약 조건이 충족되지 않더라도 DAN GALPIN : 아니면 그냥 사용할 수 있습니다 실제로 작동하지 않는 WorkManager 재정의 기한이있다 하지만 당신이해야 할 일은 두 번째 직업을 예약하는 것입니다 비슷한 기능을 수행하는 워치 독으로 ERIC KUXHAUSEN : 여기에 몇 가지가 있습니다 JobScheduler 또는 WorkManager를 사용할 때 고려해야합니다

Android는 캡 티브 포털과 [INAUDIBLE]을 감지하려고 시도하지 않습니다 조건, 그러나 불완전한 예술이다 또한 Android는 간혹 네트워크 전에 앱을 깨우십시오 앱에서 사용할 수 있습니다 이것이 의미하는 바는 적절한 오류 처리가 필요하다는 것입니다 일자리를 재조정하는 일

Play 스토어에서 지수 백 오프를 추가하면 우리의 일에, 우리는 19 % 더 성공적인 배경 작업을 보았습니다 여기에서 핵심은 시스템이 작동하도록 허용합니다 동일한 작업으로 일정을 다시 잡는 실수를 저지르기 쉽습니다 ID, 시스템 백 오프도 사용합니다 이는 백 오프 속도를 방해하거나 재설정 할 수 있습니다

DAN GALPIN : 또는 WorkManager에서 – 사실, 그래, 그러지 마라 같은 결과가 있기 때문에 프레드 (FRED CHUNG) : PendingIntents를 사용하면 PendingIntent를 변경할 수 있습니다 서비스 대상에서 BroadcastReceiver 대상 이제 작업이 30 초 이내에 실행되면, goAsync를 호출하고 작업을 바로 실행할 수 있습니다

BroadcastReceiver에서, 그건 그렇고, 뭔가를 끝내는 초경량 방법입니다 네트워크 또는 wakelocks가 보장되지는 않습니다 그래서 아직도해야 할 일이 많이 있습니다 DAN GALPIN : BroadcastReceiver에서 일정 잡기 WorkManager를 사용하여 프레드 (FRED CHUNG) : 그렇다면 외부에 즉각적인 사용자가 필요한 시간에 민감한 이벤트를 유발했습니다

관심, Firebase Cloud 사용 고려 앱에 알림 메시지 FCM은 높음 및 보통 우선 순위 메시징을 지원합니다 우선 순위가 높은 메시지의 경우 장치가 졸음에서 깨어 나면 많은 것을 의미합니다 시스템 건강에 좋지는 않을 것입니다 작업이 10 초 이내에 실행될 수 있다면, 바로 실행할 수 있습니다

또는 다음을 사용하여 작업을 예약하십시오 DAN GALPIN : WorkManager 실제로 전경 서비스 요구되거나 요구된다 이상적으로는 사용자가 시작한 작업입니다 오랜 시간 동안 뛰고 싶다

사용자에게 일종의 지속적인 업데이트를 제공합니다 예는지도, 탐색 피트니스 추적, 주악 ERIC KUXHAUSEN : Play 스토어에서 우리는 앱을 복원 할 때 전경 서비스 사용 장치를 설치 한 후 응답 시간이 길기 때문에 OK입니다 사용자 상호 작용 DAN GALPIN :하지만 음악을 듣는 것만 큼 재미있는 것은 아닙니다 FRED CHUNG : 좋은 소식은이 다른 것들이 이미 귀하의 애플 리케이션에 영향을 미칩니다

그러나 아마도 당신은 아직 눈치 채지 못했을 것입니다 그 따라서 Android N에서 새로운 사진 방송 더 이상 발생하지 않지만 TriggerContentUris로 대체 할 수 있습니다 일자리를 구하는 것은 일을 의미합니다 새로운 WorkManager API를 사용하면 다음과 같습니다

DAN GALPIN : 이제 앱이 백그라운드에서 실행중인 경우 Android O + 기기에서 위치 시스템 서비스 앱의 새 위치를 자주 계산하지 않으며, 앱이 더 자주 업데이트를 요청하더라도 백그라운드 앱에 대해서만 전체 Wi-Fi 스캔도 수행됩니다 매시간 몇 번 따라서 더 자주 전화를받는 경우 Wi-Fi 관리자 [INAUDIBLE] 실제로는 캐시 결과 만 제공하면됩니다 이제 사용자 도달 시간을 알아야하는 경우 특정 위치, 지오 펜싱 사용 자, 활성화 될 수있는 지오 펜스는 단지 100 개뿐입니다

그래서 당신이 그것보다 더 많은 사이트를 필요로한다면, 실제로 지역 지오 펜스를 사용할 수 있습니다 필요에 따라 다양한 지오 펜스 세트를 교환 할 수 있습니다 이제, 그것은 말하고 있습니다 – 비컨은 굉장합니다 주변 알림을 사용할 수 있습니다 API

특히 중요합니다 네가 특정 다작의 커피 공급업자라면 ERIC KUXHAUSEN : 배치 버전을 사용할 수도 있습니다 FusedLocationProvider의 최대 위치 업데이트 지정 귀하의 유스 케이스에 수용 가능한 대기 시간

그리고 시스템은 배치 업데이트를 시도 할 것이고, 앱의 빈도가 줄어 들었습니다 이렇게하면 배터리 사용이 최적화됩니다 수동 위치를 사용할 수도 있습니다 이를 통해 앱을 기회주의 적으로 피기 백 가능하게합니다 다른 앱의 위치 업데이트에서 가장 빠른 속도로 업데이트 지정된 간격

하지만 앱의 위치 업데이트가 네트워크와 같은 값 비싼 작업에 묶여 있어야합니다 전화를 걸면, 당신도 그들을 억제해야합니다 FRED CHUNG : 따라서 일괄 배치와 수동적 위치를 통해, 우리는 힘으로 위치 업데이트로 작업 할 수 있습니다 효율적인 방식 다음으로 몇 가지 관련 개선 사항을 살펴 보겠습니다

플랫폼에서 그래서 안드로이드의 과거 여러 버전에서, 우리는 일련의 배터리 최적화 기능을 도입했습니다 백그라운드 작업을 연기하고 제한하는 것을 기반으로합니다 따라서 이미 이들 중 일부에 익숙 할 것입니다 예를 들어, 장치가 도즈 (doze) 장치가 연결되지 않은 경우 및 장치가 연결되지 않은 경우 꽤 오랫동안 사용되었습니다

졸작에서 앱은 보류중인 모든 것을 끝내야합니다 정기적 인 유지 관리 기간의 일부 작업 DAN GALPIN : N +에서 이동 중에 doze가 연장됩니다 장치가 사용자의 주머니에 앉아있을 때와 같은 경우 자, app standby는 M에서 소개되었습니다

세금 제한을 부과하는 곳 앱 사용시 ERIC KUXHAUSEN : 브랜드에 대한 새로운 정보를 알려 드리겠습니다 Android P에서 사용 기반 제한 보다 세분화 된 방식으로 적용됩니다 이전 I / O에서 이미이 사실을 알았을 수도 있습니다 "앱이 사용자의 배터리를 소모시키지 않도록하십시오

" 앱이 앱의 대기 버킷 중 하나에 추가됩니다 사용량에 따라 시스템이 점차적으로 더 많은 제한을 앱에 적용합니다 활성에서 희귀 한 양동이로 이동함에 따라 또한 배터리 절약 기능이 향상되었습니다 사용자가 확장 할 수 있습니다 다른 모든 것보다 배터리 우선 순위를 지정하여 배터리 수명을 늘립니다

이로 인해 기능이 다소 저하되며, 사용할 수없는 위치 요청과 같은 화면이 꺼져있을 때 그러나이 모드는 정말 유용합니다 당신의 장치가 조금 더 오래 지속될 필요가있을 때 FRED CHUNG : 방금 이야기 한 기능 앱의 알람에 부가적인 영향을 주며, 작업, 동기화, 네트워크 액세스 및 FCM 메시지를 표시합니다 그래서 우리는 모든 사람들에게 이러한 시나리오를 철저히 테스트 귀하의 응용 프로그램 내에서

DAN GALPIN : 좋은 소식은이를위한 도구가 있다는 것입니다 예를 들어,이 ADB 명령 장치를 유휴 상태로 만들면서 모든 응용 프로그램을 잠잠하게 만듭니다 ERIC KUXHAUSEN : 애플리케이션 대기를 테스트하려면, 먼저 장치의 연결을 시뮬레이트합니다 그런 다음 get 및 set inactive 명령을 사용할 수 있습니다 앱 대기 상태에서 기기를 가져오고 나가기

FRED CHUNG : 앱 대기 버킷의 경우, 당신은 주어진 꾸러미에 대한 버켓을 가져 와서 설정할 수 있습니다 비슷한 광고 명령 하지만 플러그를 뽑는 것을 기억하십시오 테스트하기 전에 장치 또한이를 수행 할 수있는 프레임 워크 API가 있습니다

마지막으로 배터리 세이버를 테스트하는 명령입니다 한 가지 유의점은 앱의 UI에 어두운 테마가있는 경우, 어두운 테마 사용을 고려해 볼 수 있습니다 배터리 세이버가 전원을 절약하기 위해 추가로 켜지면 OLED 장치 PowerManager를 통해 API로 확인할 수 있습니다 그리고 방송을 듣고 그렇게해라

DAN GALPIN : 그래서, 많은 방법들이 있습니다 백그라운드에서 멋진 앱을 만들기 위해 전경 서비스를 사용하지 않고 WorkManager의 새로운 기능을 활용하십시오 효율적인 위치 전략 사용, 새로운 API 사용, 우리에게 무엇이 아닌지 알려주십시오 피드백을 제출하여 귀하의 요구를 충족 시키십시오

이슈 트래커를 통해 프레드 (FRED CHUNG) : 그래서, 아마 목표를 업데이트하는 중이다 SDKs, 모두 좋다 당신이 그것에있는 동안, 우리는 Android에서 선택한 최신 기능을 확인해보십시오 사용 사례와 관련이 있습니다 예를 들어 알림 채널을 추가해야합니다

귀하의 앱에 O 그렇지 않으면, 음, 알림 그냥하지 않습니다 쇼, 좋지 않을 것입니다 채널을 신중하게 계획하여 사용자가 선택적으로 할 수 있도록하십시오 원치 않는 알림을 끄십시오 DAL GALPIN : 한장 뒤로 젖히십시오

ERIC KUXHAUSEN : Play 스토어가 구현 된 기기에서 알림 채널 지원, 우리는 더 적은 비율의 사용자를 사용할 수 없게됩니다 우리의 모든 통지 DAN GALPIN : 앱에서 반투명 상태 표시 줄을 사용하는 경우, 삽입 된 API를 사용하여 코드에서 상태 표시 줄이 고정되어 있다고 가정하지 않습니다 크기 이제 탐색 서랍을 사용하는 경우, 이것은 실제로 실제로 일반적입니다

이제 P를 타겟팅하면 그 컷 아웃 영역에서 흥미로운 것을하십시오 이제 공익 광고 발표, 당신은 당신의 시스템을 넣을 필요가 없습니다 당신의 유일한 장치에 이미지 한동안 에뮬레이터를 사용하지 않았다면, 그것은 꽤 굉장합니다 최근에는 초고속 로딩에 대한 지원을 추가했습니다

P 개발자가있는 모든 장치에서 AR 지원과 함께 시스템 이미지 미리보기, DisplayCutout 시뮬레이션 가능 개발자 옵션을 통해 이것으로 공익 광고가 종료됩니다 FRED CHUNG : 좋아 그래서, 종횡비 화면 따라서 OEM이 출하하는 추세가되었습니다 16보다 긴 화면이있는 이러한 기기 화면 비율 9

앱이 몰입도 높은 경험을 제공하는지 확인하세요 이러한 화면 기능을 최대한 활용할 수 있습니다 그것은 꽤 굉장하다 따라서 최후의 수단으로 시스템은 여전히 ​​사용자를 제공합니다 지원되는 최대 종횡비를 선언하는 방법

하지만 응용 프로그램 주위에 레터 박스가 표시됩니다 ERIC KUXHAUSEN : 진지하게, 정말로 편지함을 원하십니까? DAN GALPIN : 더 큰 화면에서 책임감이 커집니다 자, 그림 활용을 고려해보십시오 화상 채팅, 영화 재생, 체력 추적 또는 Pokemon Go로 이동합니다 다중 디스플레이 지원은 또한 사용자가 애플리케이션에 대한 활동을 시작하는 방법 두 번째 디스플레이에

그리고 여기서 정말로 고려해야 할 유일한 것 그것이 두 번째 구성을 가지고 있는가? 가장 가능성이 큰 1 년 앱과 다를 것입니다 따라서 애플리케이션 전반에 걸친 가정을하지 않도록주의하십시오 근면 한 구성에 대해 결론적으로 Android 개발 최신 도구 및 API를 사용하여 더 나은 배터리 수명, 더 매끄러운 멀티 태스킹, 최신 하드웨어 및 플랫폼 기능 지원, Jetpack을 활용하여 구축 현대적이고 검증 가능한 아키텍처 고맙습니다

괜찮아 사실, 안돼, 안돼, 안돼 실제로 한 가지 더 있습니다 Android가 실제로 사용을 제한하고 있습니다 개발자 미리보기 1의 일부 비 SDK 인터페이스 그리고 당신은 이것을 보았습니다

우리가 실제로 토스트와 로그 엔트리로 너에게 경고했다 이 방법이 사용 된 경우 그러나 DP2에 대해 테스트한다면, 이 방법 중 일부는 작동을 멈추고, 앱이 다운 될 수 있습니다 따라서 문제가 있으면 테스트하고 파일을 보내주십시오 앱이 할 수있는 어떤 방법도 있다고 생각하지 마라

이러한 방법 이외의 작업 그리고, 당신을 미래에 돕기 위해, 우리는 실제로 StrictMode에 대한 새로운 VM 정책을 추가했습니다 SDK API가 아닌 모든 API를 켜고 감지하는 데 사용할 수있는 사용법은 정말로 중요합니다 이 비 SDK 사용은 실제로 당신의 도서관에서 일어나고 있습니다 그래서 실제로 확인하는 것은 정말 좋은 방법입니다

귀하의 앱은 앞으로도 호환 될 것입니다 우리는 비 SDK의 호환성을 보장하지 않기 때문에 API 그래서 이제 그게 사실입니다 지난 30 일에 관심을 기울이지 않았다면 분, 내 농담이 분명히 필요하기 때문에 괜찮습니다 ERIC KUXHAUSEN : 엔지니어라면 희망이 있습니다

오늘 공유 한 정보 중 귀하의 리뷰가있었습니다 그리고 유용한 정보를 찾길 바랍니다 프레드 (FRED CHUNG) : 그렇다면 PM입니다 26을 목표로 삼아, 계획을 세우는 것은 너무 늦지 않았습니다 팀과 협력하여 필요한 작업량을 파악합니다

그리고 실제로, 우리는 가이드를 준비했습니다 Android 개발자 사이트에서 사람들이 이해하고, 현재 릴리스, 필요한 작업량, 우리는 집합 적으로 생태계를 발전시킬 수 있습니다 고맙습니다 [음악 재생]