머리말
Kotlin Coroutines는 Kotlin이 시작한 새로운 비동기 API입니다. 모든 문제에 대한 최상의 솔루션은 아니지만 많은 경우에는 상황이 조금 더 쉬워지기를 바랍니다. 여기에 Android 에서이 라이브러리의 특정 사용 계획을 표시하겠습니다. 아래에서 많이 말하지 않겠습니다. 자세한 소개를 함께 살펴 보겠습니다.
코 루틴 소개
// Application의 Build.Gradle 파일에서 Android 노드에서 다음 코드를 추가합니다. Kotlin {Experimental {Coroutines 'enable'}} // 종속성 구현에 다음 두 줄을 추가하십시오.첫 번째 코 루틴 예
일반적으로 이미지를 ImageView에로드하고 비동기로드 작업은 다음과 같습니다.
재미있는 loadbitmapfrommediastore (imageId : int, imagesbaseuri : uri) : bitmap {val uri = uri.withApppedPath (imagesBaseUri, imageId.toString ()) return medicstore.images.media.getBitmap (contentResolver, uri)}이 방법은 IO 작업에 속하므로 백그라운드 스레드에서 실행해야하므로 배경 작업을 시작하기위한 많은 솔루션이 있으며 메소드가 비트 맵을 반환하면 즉시 이미지 뷰에 표시해야합니다.
ImageView.SetImageBitMap (BitMap)
이 코드 라인은 기본 스레드에서 실행되어야합니다. 그렇지 않으면 충돌합니다.
위의 세 줄의 코드 라인이 함께 기록되면 프로그램이 고정되거나 충돌하여 합리적인 스레드 선택에 따라 다릅니다. 다음으로 Kotlin을 사용하는 코 루틴 이이 문제를 해결하는 방법을 살펴 보겠습니다.
val job = launch (background) {val uri = uri.withApppedPath (imagesBaseUri, imageId.toString ()) val bitmap = mediaStore.images.media.getBitMap (contentResolver, univer (ui) {imageView.SetImageBitMap (bitmap)}}여기서 가장 중요한 것은 Launch () 및 매개 변수 배경 및 UI입니다. 런치 ()는 코 루틴을 생성하고 시작하는 것을 의미합니다. 배경 매개 변수 CoroutIneContext는 응용 프로그램이 고착되거나 충돌하지 않도록 백그라운드 스레드에서 실행을 보장하는 데 사용됩니다. 아래와 같이 CoroutIneContext를 선언 할 수 있습니다.
내부 VAL 배경 = NewFixedThreadPoolContext (2, "BG")
이것은 새로운 컨텍스트를 생성하고 작업을 실행할 때 두 개의 일반 스레드를 사용합니다.
다음으로, 다른 코 루틴을 트리거하는 발사 (UI)는 안드로이드에서 실행됩니다.
메인 스레드.
취소 가능
다음 과제는 활동 선언주기와 관련된 것들을 다루는 것입니다. 실행을 마치기 전에 작업을로드하고 활동을 떠날 때 imageView.setImageBitmap(bitmap) 호출 할 때 충돌이 발생하므로 활동을 떠나기 전에 작업을 취소해야합니다. 여기서 우리는 launch () 메소드의 반환 값을 사용합니다. 활동이 OnStop 메소드를 호출 할 때 작업을 사용하여 작업을 취소해야합니다.
job.cancel ()
rxjava를 사용할 때 Discope를 호출하고 Asynctask를 사용할 때 취소 기능을 호출하는 것과 같습니다.
라이프 사이클로브 서버
Android 아키텍처 구성 요소는 Android 개발자에게 많은 강력한 라이브러리를 제공하며 그 중 하나는 Lifecycle API입니다. 그것은 우리에게 활동과 조각의 수명주기를 실시간으로들을 수있는 쉬운 방법을 제공합니다. 코 루틴과 함께 사용할 코드를 정의해 봅시다.
클래스 CoroutIneLifeCyclElistener (Val Deferred : Deferred <*>) : LifeCycleObserver {@onlifecycleEvent (lifecycle.event.on_destroy) fun canclcoroutine () {if (! deferred.iscancelled) {deferred.cancel ()}}}.라이프 사이클 소유자 확장 기능을 만듭니다.
fun <t> lifecycleowner.load (로더 : () -> t) : DEFERRED <T> {VAL DEFERRED = ASYNC (Context = async (context = background, start = coroutInestart.lazy) {loader ()} lifecycle.addoBserver (CoroutinELifeCyclelistener (DEFERRED)) 리턴 DEFERRED}. 이 방법에는 너무 많은 새로운 것들이 있으며, 나는 그것들을 하나씩 설명하겠습니다.
이제 활동 또는 조각에서 load() 호출하고 해당 기능에서 수명주기 멤버에 액세스하고 CoroutIneLifeCyclElistener를 관찰자로 추가 할 수 있습니다.
로드 방법은 매개 변수로 로더를 요구하고 일반 유형 T를 반환합니다.로드 방법에서는 배경 코 루틴 컨텍스트를 사용하여 백그라운드 스레드에서 작업을 실행하는 다른 코 루틴 작성기 async () 함수를 호출합니다. 이 메소드에는 다른 매개 변수 시작 = coroutinestart.lazy가 있습니다. 즉, 코 루틴이 호출 될 때까지 즉시 실행되지 않습니다.
그런 다음 Coroutine은 이전 작업과 유사한 발신자에게 Defered<T> 객체를 반환하지만 정기적 인 Java API에서 JavaScript Promise 또는 Future <T> 와 같은 지연 값을 전달할 수도 있으며, 더 나은 방법이 있습니다.
다음으로 우리는 다른 확장 함수를 정의 한 then() 정의합니다. 이번에는이를 위에서 위 Deferen<T> 부하 방법으로 반환 한 유형입니다. 또한 Lambda를 매개 변수로 취하여 Block이라는 이름의 매개 변수로 Type T의 단일 객체를 매개 변수로 취합니다.
infix fun <T> DEFERRED <T> .then (블록 : (t) -> init) : job {return 런치 (context = ui) {block ([email protected] ())}} 이 함수는 이번에는 기본 스레드에서 실행되는 launch() 함수를 사용하여 다른 코 루틴을 생성합니다. 이 코 루틴에 전달 된 람다 (블록)는 완성 된 지연된 물체의 값을 매개 변수로 취합니다. 우리는 지연된 물체가 값을 반환 할 때 까지이 코 루틴의 실행을 중단하기 위해 await() 를 호출합니다.
여기에 코 루틴이 인상적이되는 곳입니다. await() 호출은 기본 스레드에서 수행되지만 해당 스레드의 추가 실행을 차단하지는 않습니다. 기능이 준비 될 때까지 함수의 실행을 일시 중지 할 때, 지연된 값을 Lambda에 전달할 때까지 일시 중지됩니다. 코 루틴이 매달리면 기본 스레드는 다른 일을 계속 수행 할 수 있습니다. Await 기능은 Coroutine의 핵심 개념이며, 모든 것을 마술처럼 만듭니다.
load() 함수에 추가 된 수명주기 옵저버는 활동에 onDestroy() 호출 한 후 첫 번째 코 루틴을 취소합니다. 또한 두 번째 코 루틴이 취소되어 block() 이 호출되는 것을 방지합니다.
KOTLIN COROUTINE DSL
이제 우리는 두 개의 확장 기능과 코 루틴의 취소를 처리하는 클래스가 있으므로 사용 방법을 살펴 보겠습니다.
로드 {loadBitMapFrommediastore (imageId, imagesBaseUri)} 그런 다음 {imageView.SetImageBitMap (it)} 위의 코드에서는 LABSDA 메소드를로드 함수로 전달합니다.로드 함수를 전달합니다.로드 함수는 LoadBitMapFrommediastore 메서드를 호출하며 메소드가 비트 맵을 반환 할 때까지 백그라운드 스레드에서 실행해야하며로드 메소드의 리턴 값이 Deferred<Bitmap> 됩니다.
확장 함수로서, then() 메소드는 Infix 선언을 사용합니다. 로드 메소드가 Deferred<Bitmap> 는 당시 메소드로 전달되므로 비트 맵 리턴 값으로 전달되므로 당시 메소드에서 imageView.setImageBitmap(it) 직접 호출 할 수 있습니다.
위의 코드는 배경 스레드에서 발생 해야하는 비동기 호출과 위의 예에서와 같이 반환 값을 기본 스레드로 반환 해야하는 비동기 호출에 사용될 수 있습니다. Rxjava와 마찬가지로 여러 번의 호출을하지는 않지만 읽기가 더 쉽고 가장 일반적인 사례를 많이 다룰 수 있습니다. 이제 모든 통화에서 컨텍스트 누출을 유발하거나 스레드를 처리하는 것에 대해 걱정하지 않고 이와 같은 일을 할 수 있습니다.
로드 {restapi.fetchdata (query)} 그런 다음 {adapter.display (it)}그런 다음 () 및 load () 메소드는이 새로운 라이브러리의 빙산의 일각 일 뿐이지 만 코 루틴 버전이 안정적인 버전에 도달하면 향후 Kotlin 기반 Android 라이브러리에서 비슷한 것이 나타나기를 바랍니다. 이 전에 위의 코드를 사용하거나 수정하거나 Anko Coroutines를 확인할 수 있습니다. 또한 Github에서 더 완전한 버전을 출시했습니다. (https://github.com/erikhellman/kotlinasyncwithcoroutines (로컬 다운로드)).
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.