序文
Kotlin Coroutinesは、Kotlinが発売した新しい非同期APIです。すべての問題に対する最良の解決策ではありませんが、うまくいけば、多くの場合、物事が少し簡単になるでしょう。ここでは、Androidのこのライブラリの特定の使用計画を単に示します。以下ではあまり言いません。詳細な紹介を一緒に見てみましょう。
コルーチンの紹介
// build.gradleファイルのbuild.gradleファイルkotlin {experimental {coroutines 'enable'}} //次の2行を依存関係実装に追加する "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.20" emformation "org.kotlinx:kotlinx:kotlinx-corutines:kotlinx:kotlinx-corutinesに次のコードを追加します。最初のコルーチンの例
通常、画像をImageViewにロードすると、非同期ロードタスクは次のとおりです。
Fun loadbitmapfrommediastore(imageId:int、imagesbaseuri:uri):bitmap {val uri = uri.withedendedpath(imagesbaseuri、mageid.tostring())return mediastore.images.media.getbitmap(contentresolver、uri)}}}この方法は、IO操作に属しているため、バックグラウンドスレッドで実行する必要があります。つまり、バックグラウンドタスクを開始するための多くのソリューションがあり、メソッドがビットマップを返すと、すぐにImageViewに表示する必要があります。
ImageView.setImageBitMap(bitmap)
このコード行はメインスレッドで実行する必要があります。そうしないと、クラッシュします。
上記の3行のコードが一緒に書かれている場合、プログラムは立ち往生またはクラッシュします。これは、スレッドの合理的な選択に依存します。次に、Kotlinを使用してCoroutinesがこの問題をどのように解決するかを見てみましょう。
val job = launch(background){val uri = uri.withedendedpath(imagesbaseuri、mageid.tostring())val bitmap = mediastore.images.media.getBitmap(ui){mageview.setimagebitmap(bitmap)}}}ここで最も重要なことは、launch()とパラメーターの背景とUIです。起動()は、Coroutineを作成して開始することを意味します。バックグラウンドパラメーターCoroutineContextを使用して、アプリケーションがスタックまたはクラッシュしないようにするために、バックグラウンドスレッドでの実行を確保します。以下に示すように、CoroutineContextを宣言できます。
内部val背景= newFixedThreadPoolContext(2、 "BG")
これにより、新しいコンテキストが作成され、タスクを実行するときに2つの通常のスレッドを使用します。
次に、起動(UI)。これは別のコルーチンをトリガーし、Androidで実行されます
メインスレッド。
キャンセル可能
次の課題は、活動宣言サイクルに関連するものに対処することです。実行が終了する前にタスクをロードしてアクティビティを残すと、 imageView.setImageBitmap(bitmap)を呼び出すとクラッシュが発生するため、アクティビティを離れる前にタスクをキャンセルする必要があります。ここでは、Launch()メソッドの返品値を使用します。アクティビティがオンストップメソッドを呼び出す場合、ジョブを使用してタスクをキャンセルする必要があります。
job.cancel()
rxjavaを使用しているときに処分を呼び出し、asynctaskを使用するときにキャンセル機能を呼び出すようなものです。
LifeCycleObserver
Androidアーキテクチャコンポーネントは、Android開発者に多くの強力なライブラリを提供します。その1つはライフサイクルAPIです。アクティビティやフラグメントのライフサイクルをリアルタイムで聴く簡単な方法を提供します。 Coroutinesで使用するコードを定義しましょう。
クラスCoroutineLifeCycleListener(val Deferred:Deferred <*>):LifeCycleObserver {@onlifeCycleEvent(LifeCycle.Event.on_Destroy)Fun CancelCoroutine(){if(!deferred.iscancelled){deferred.cancel()}}}}ライフサイクルオーナーの拡張機能を作成します。
fun <t> lifecycleawner.load(loader:() - > t):deferred <t> {val deferred = async(context = background、start = coroutinestart.lazy){loader()} lifecycle.addobserver(coroutinelifecyclelistener(deferred)returned}この方法にはあまりにも多くの新しいものがありますが、私はそれらを一つずつ説明します:
これで、アクティビティまたはフラグメントでload()を呼び出して、その関数からライフサイクルメンバーにアクセスして、オブザーバーとしてコルタイニーリフサイクリステナーを追加できます。
負荷方式では、パラメーターとしてローダーが必要であり、一般的なタイプTを返します。ロードメソッドでは、別のCoroutine Creator async()関数を呼び出します。この方法には別のパラメーターstart = coroutinestart.lazyがあります。つまり、コルーチンは呼び出されるまですぐに実行されないことを意味します。
Coroutineは、以前のジョブに似たDefered<T>オブジェクトを発信者に返しますが、JavaScript PromiseやFuture <T>通常のJava APIなどの遅延値を搭載することもできます。
次に、別の拡張関数を定義しますthen() 。今回はDeferen<T>の上に定義します。これは、上記の負荷方法によって返されるタイプです。また、Lambdaをパラメーターとして使用します。これは、Type Tの単一のオブジェクトをパラメーターとして使用する単一のオブジェクトです。
Infix fun <t> deferred <t> .then(block:(t) - > unit):job {return launch(context = ui){block([email protected]())}}}この関数はlaunch()関数を使用して別のコルーチンを作成し、今回はメインスレッドで実行されます。このコロウチンに渡されたラムダ(名前付きブロック)は、完成した繰延オブジェクトの値をそのパラメーターとして取得します。延期されたオブジェクトが値を返すまで、このコルーチンの実行を一時停止するためにawait()を呼び出します。
ここで、コルーチンがとても印象的になります。 await()への呼び出しはメインスレッドで行われますが、そのスレッドのさらなる実行をブロックしません。それは、それが準備ができるまで、それが再開され、遅延値をラムダに渡すまで、単に関数の実行を一時停止します。 Coroutineが吊り下げられると、メインスレッドは他のことを実行し続けることができます。待機機能は、コルーチンのコアコンセプトであり、全体を非常に魔法のように作成しています。
load()関数に追加されたライフサイクルオブザーバーは、アクティビティでonDestroy()呼び出した後、最初のコルーチンをキャンセルします。これにより、2番目のコルーチンがキャンセルされ、 block()が呼び出されなくなります。
Kotlin Coroutine DSL
これで、2つの拡張機能とコルーチンのキャンセルを処理するクラスができたので、それを使用する方法を見てみましょう。
load {loadbitmapfrommediastore(imageId、imagebaseuri)} then {mageview.setImageBitmap(it)}上記のコードでは、lambdaメソッドをロード関数に渡します。これは、メソッドがビットマップを返すまで背景スレッドで実行する必要があるLoadbitmapfrommediastoreメソッドをDeferred<Bitmap>ます。
拡張関数として、 then()メソッドはinfix宣言を使用します。負荷メソッドはDeferred<Bitmap>を返しますが、Then Methodにbitmap戻り値に渡されるため、Then MethodでimageView.setImageBitmap(it)を直接呼び出すことができます。
上記のコードは、上記の例のように、バックグラウンドスレッドで発生する必要がある非同期呼び出し、および戻り値をメインスレッドに返す必要がある場合に使用できます。 RXJavaのように複数の呼び出しは行われませんが、読みやすく、最も一般的なケースの多くをカバーする可能性があります。これで、すべての呼び出しでコンテキストリークやスレッドの処理を引き起こすことを心配することなく、このようなことを安全に行うことができます。
Load {retapi.fetchdata(query)} then {adapter.display(it)}次に、()およびLoad()メソッドは、この新しいライブラリの氷山の先端にすぎませんが、Coroutineバージョンが安定したバージョンに達すると、将来のKotlinベースのAndroidライブラリに似たようなものが表示されることを願っています。この前に、上記のコードを使用または変更するか、Anko Coroutinesをチェックしてください。また、GitHubでより完全なバージョンをリリースしました。 (https://github.com/erikhellman/kotlinasyncwithcoroutines(ローカルダウンロード))。
要約します
上記は、この記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。