記事ディレクトリ
1依存性注入Kodin
実際、この部分はコルーチンとは関係ありませんが、この記事では主にいくつかのKotlinの3者ライブラリを紹介していると思います。
依存性注入が何であるかわからない場合は、この記事をご覧ください。Java:Inversion of Control(IoC)とDependency Injection(DI)
は、Androidで依存性注入を提供します。誰もがDraggerを考え、Androidの関係者もこれを使用することをお勧めします依存性注入を行うため。
公式ドキュメントのベストプラクティスセクションで、依存関係注入モジュールはDraggerについて言及しています
。AndroidアプリケーションでDraggerを使用してください。
Androidでの依存性注入の使用| AndroidDevSummit中国語の字幕ビデオ
Androidは、JavaバージョンのDraggerを簡単に使用できるようにいくつかのパッケージを作成しましたが、それでも学習するにはコストがかかりすぎ、多くの概念があります。
しかし、Kotlinの時代には、依存性注入を少し簡単にするにはどうすればよいので、Kodinがあります。Kodeinの完全な名前はKOtlin DEpendency INjectionです。実際、これは依存性注入フレームワークではなく、依存関係取得コンテナーであり、次のコードで詳細に説明されています。
話は安いです、私にコードを見せて:
val di = DI {
bind<Dice>() with provider { RandomDice(0, 5) }
bind<DataSource>() with singleton { SqliteDS.open("path/to/file") }
}
class Controller(private di: DI) {
private val ds: DataSource by di.instance()
}
退屈で単純なプロセスが単純である理由は、それを使用するためであり、Draggerのモジュールとコンポーネントの概念を気にしないようにするためです。
当局はその利点を紹介しました:
- 非常にシンプルで読みやすい宣言型DSLを提供します
- 型消去による制限はありません(Javaと比較して)
- Androidと完全に統合します
- 非常にKotlinスタイルの慣用的なAPIを提案します
- 高速で最適化されています(インラインが広く使用されています)
- ピュアJavaで使用可能
要件:
Java 8以降
Qingmei Great Godの記事を読むことをお勧めします:Dagger2からKodeinに移行するAndroid開発の経験はDagger2に
別れを告げ、Kodeinは依存関係注入のためにAndroidのKotlinプロジェクトで使用されます。
公式ドキュメント参照:
Android
Kodein DIの公式ウェブサイトのKodein DI:https ://kodein.org / di /
Kodein Github:https : //github.com/Kodein-Framework/Kodein-DI
2画像読み込みフレームワークコイル
Androidの画像読み込みフレームワークに関しては、誰もがUIL(Universal Image Loader)、フレスコ、ピカソ、グライドなどを思い浮かべます。さまざまな比較を行った記事がインターネットで見つかりますが、なぜ画像読み込みライブラリが必要なのでしょうか。
Coil官网说明:Kotlin CoroutinesがサポートするAndroid向けの画像読み込み。
Coilは以下の頭字語です:コルーチン画像ローダー
上記のコード:
// URL
imageView.load("https://www.example.com/image.jpg")
// Resource
imageView.load(R.drawable.image)
// File
imageView.load(File("/path/to/image.jpg"))
imageView.load("https://www.example.com/image.jpg") {
crossfade(true)
placeholder(R.drawable.image)
transformations(CircleCropTransformation())
}
正式に導入された機能:
- 高速:コイルは、メモリとディスクのキャッシュ、メモリ内の画像のリサンプリング、ビットマップの多重化、自動一時停止/キャンセルリクエストなど、多くの最適化を実行しました。
- 軽量:CoilはAPKに約1500のメソッドを追加します(すでにOkHttpとコルーチンを使用しているアプリケーションの場合)。これはピカソに匹敵し、GlideやFrescoよりもはるかに小さいです。
- 使いやすさ:CoilのAPIは、Kotlinの言語機能を使用して、ボイラープレートコードを簡素化および最小化します。
- モダン:CoilはKotlinを使用し、コルーチン、OkHttp、Okio、AndroidXライフサイクルなどのモダンライブラリを使用しています。
要件:
AndroidX; Min SDK 14以降;コンパイルSDK:29以降; Java 8以降
現在、より多くのGlide公式Webサイトドキュメントを使用しています:http : //bumptech.github.io/glide/
対応する中国語バージョン:https : //muyangmin.github.io/glide-docs-cn/
3許可申請
Androidの動的アクセス許可アプリケーションについては、RxPremissionsを広く使用している可能性がありますが、コルーチンバージョンのアクセス許可アプリケーションフレームワークを導入する理由は何ですか。
もちろん、コルーチンを作成した後は、コルーチンを最大限に活用できます。
RxPremissionsの使用を見てください。
final RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity or Fragment instance
// Must be done during an initialization phase like onCreate
rxPermissions
.request(Manifest.permission.CAMERA)
.subscribe(granted -> {
if (granted) { // Always true pre-M
// I can control the camera now
} else {
// Oups permission denied
}
});
非常に単純で、複数の権限が同時に適用される場合、コードは次のようになります。
public void requsetPermissions(Activity activity) {
//RxPermission在目标activity里面添加了一个fragment用于拦截权限申请结果
RxPermissions permissions = new RxPermissions(activity);
permissions.setLogging(true);
permissions.requestEach(Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CALL_PHONE)
.subscribe(new Consumer<Permission>() {
@Override
public void accept(Permission permission) throws Exception {
//申请和返回的权限名
if (permission.name.equalsIgnoreCase(Manifest.permission.READ_EXTERNAL_STORAGE)) {
if (permission.granted) {
//权限被用户通过
} else if (permission.shouldShowRequestPermissionRationale){
//权限被用户禁止,但未选中‘不在提示’,则下次涉及此权限还会弹出权限申请框
}else {
//权限被用户禁止,且选择‘不在提示’,当下次涉及此权限,不会弹出权限申请框
}
}
if (permission.name.equalsIgnoreCase(Manifest.permission.CALL_PHONE)) {
if (permission.granted) {
} else if (permission.shouldShowRequestPermissionRationale){
}else {
}
}
}
});
}
//检查某个权限是否被申请
permissions.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)
はい、ネスト{}がたくさんあり、コード構造が不明確になっているので、コルーチンバージョンのパーミッションアプリケーションを見てみましょう。
GitHubでコルーチンを検索するための多くの許可アプリケーションがあります。ここに1つあります:
Assent:https : //github.com/afollestad/assent
モジュールのbuild.gradleに依存関係を追加します。
dependencies {
//core API
implementation 'com.afollestad.assent:core:3.0.0-RC4'
//协程调用方式API
implementation 'com.afollestad.assent:coroutines:3.0.0-RC4'
//Google建议在用户可能不明白为什么需要该权限时,显示权限的基本原理。
implementation 'com.afollestad.assent:rationales:3.0.0-RC4'
}
アクティビティでの使用:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rationaleHandler = createSnackBarRationale(rootView) {
onPermission(READ_CONTACTS, "Test rationale #1, please accept!")
onPermission(WRITE_EXTERNAL_STORAGE, "Test rationale #2, please accept!")
onPermission(READ_SMS, "Test rationale #3, please accept!")
}
requestPermissionButton.clicks()//
.debounce(200L)
.onEach {
val result = awaitPermissionsResult(
READ_CONTACTS, WRITE_EXTERNAL_STORAGE, READ_SMS,
rationaleHandler = rationaleHandler
)
statusText.text = result.toString()
}
.launchIn(lifecycleScope)
}
上記のコードではclicks()メソッドを使用してクリックイベントをフローに変換し、デバウンス(200L)を使用してジッターを削除して高速クリックを防止しています。使用されるライブラリは、flowBinding:"io.github.reactivecircus.flowbinding:flowbinding -Android:0.9.0 "は、によって createSnackBarRationale()メソッドパス構築され rationaleHandlerを返さの構造、ユーザーの許可を必要とするショーケース理由に結果があるAssentResultのタイプ、あなたは結果を導出するための許可を申請することができます:
val result: AssentResult = // ...
val permissions: List<Permission> = result.permissions
val grantResults: List<GrantResult> = result.grantResults
// Takes a single permission and returns if this result contains it in its set
val containsPermission: Boolean = result.containsPermission(WRITE_EXTERNAL_STORAGE)
// You can pass multiple permissions as varargs
val permissionGranted: Boolean = result.isAllGranted(WRITE_EXTERNAL_STORAGE)
// You can pass multiple permissions as varargs
val permissionDenied: Boolean = result.isAllDenied(WRITE_EXTERNAL_STORAGE)
// Returns GRANTED, DENIED, or PERMANENTLY_DENIED
val writeStorageGrantResult: GrantResult = result[WRITE_EXTERNAL_STORAGE]
val granted: Set<Permission> = result.granted()
val denied: Set<Permission> = result.denied()
val permanentlyDenied: Set<Permission> = result.permanentlyDenied()
PermissionとGrantResultが列挙型である場合:
@SuppressLint("InlinedApi")
enum class Permission(val value: String) {
UNKNOWN(""),
READ_CALENDAR(Manifest.permission.READ_CALENDAR),
WRITE_CALENDAR(Manifest.permission.WRITE_CALENDAR),
CAMERA(Manifest.permission.CAMERA),
READ_CONTACTS(Manifest.permission.READ_CONTACTS),
WRITE_CONTACTS(Manifest.permission.WRITE_CONTACTS),
GET_ACCOUNTS(Manifest.permission.GET_ACCOUNTS),
.
.
.
}
enum class GrantResult {
GRANTED,
DENIED,
PERMANENTLY_DENIED
}
上記のflowBindingライブラリを使用したくない場合は、コルーチンで直接呼び出すこともできます。
最初のawaitPermissionsResult(…)はaskForPermissions(…)と同じです。コルーチン形式で呼び出すだけです:
// Launch a coroutine in some scope...
launch {
val result: AssentResult = awaitPermissionsResult(
READ_CONTACTS, WRITE_EXTERNAL_STORAGE, READ_SMS,
rationaleHandler = rationaleHandler
)
// Use the result...
}
次に、awaitPermissionsGranted(...)は、runWithPermissions(...)のコルーチン形式と同等です。
// Launch a coroutine in some scope...
launch {
awaitPermissionsGranted(
READ_CONTACTS, WRITE_EXTERNAL_STORAGE, READ_SMS,
rationaleHandler = rationaleHandler
)
// All three permissions were granted...
}
4ネットワーク要求
ネットワーク要求はもちろんRetrofitですが、前回の記事ではコルーチンのサスペンド機能とRetrofitの組み合わせを紹介しましたので、ここでは詳しく説明しません。KotlinコルーチンとそれらのAndroidでの使用が要約されています(4つのコルーチンがRetrofit、Room、WorkManagerと組み合わせて使用されます)
5データベース
Androidの公式Roomを使用することをお勧めします。前回の記事では、コルーチンのサスペンド機能とRoomの組み合わせを紹介しましたので、ここでは詳しく説明しません。
6もっと
コルーチンを使用すると、コードを簡略化できます。基本的に、RxJavaの使用シナリオはコルーチンに置き換えることができます。昔、RxJavaは学習コストが高く、推奨されていないと言われていました。しかし、ほとんどすべてのAndroid開発者がRxJavaを知っています。次に、いくつかの演算子を確認することは大きな問題ではなく、RxJavaも多くのプロジェクトで広く使用されているので、RxJavaをコルーチンに変換する必要がありますか?
テクノロジーは単なるツールだと思います。元の方法でビジネスロジックをうまく処理できる場合は、コルーチンに変換する必要は特にありませんが、これが新しいテクノロジーを学ばない理由にはなりません。結局、コルーチンの利点はもちろん、コルーチンを学習するコストも非常に高くなります。基本的な中断機能に加えて、フローの使用、チャネルの使用、セレクターの使用など、すべて慎重に検討する必要があります。
チームがコルーチンの利点を認識でき、誰もが喜んで変更しようとすると、コードがよりフローフローになります(666)。
コードを改善するためのコルーチンのスキルをたくさん知っている場合は、誰もが一緒に進歩していることを教えてください。