Kotlin coroutine (1) compréhension de base


I. coroutine (coroutine) trame de commutation de fil Kotlin

Applications typiques:

  • Ouvrez un coroutine, le contexte désigné CoroutineContex de coroutine (comprenant un fil de la piscine de fil, etc.)
  • Comprenant en outre un coroutine interne (cette opération moins), la fonction en attente (plus), un code d'opération multithread (plus) et analogues;
  • Expérience fonction de suspension, il entrera dans les fils de commutateur de fonction de suspendre thread spécifié de fonction, et après la mise en œuvre, à l'époque coupé au fil d'origine pour continuer.

II. Fonction arrêt temporaire suspendre le plaisir

fonction de suspendre, coroutine pendre, pendre, au lieu de bloquer.
L'utilisation la plus directe est dans le thread principal, rencontré une fonction en attente, aller dans l'attente d' exécution dans une fonction;

Si la fonction de suspension, un coroutine a été désigné un fil, le fil basculera opération,
quelle que soit la coupe ne coupe pas le fil, fonction de suspension est terminée, elle continue vers le bas.
Cependant, si elle est de couper le fil désigné par l'enfant un coroutine, alors il ne sera pas pleinement mis en œuvre jusqu'à ce que le fil est terminé. (Tel que l'utilisation Thread, ThreadPoolExecutorpour démarrer le fil)

décompiler voir, suspendre la fonction emballés comme des Continuationobjets, par l' Continuation#resumeWith(result:Result<T>)obtention des résultats, result.isFailure/isSuccesssuspendre l' échec de la fonction / succès, pour obtenir le résultat de la fonction externe en attente après à nouveau après l' exécution.

se suspendent ne peut pas faire la fonction est suspendue. Utilisation en association avec coroutine, ou dans d' autres en attente de suspendre la fonction pour effectuer des opérations.
Fonction de suspension, nécessite un coroutine est suspendu ou d' un autre appel de fonction, le but ultime, ou à exécuter coroutine.

suspend fun m() {
	//withContext 是一个挂起函数
	withContext(Dispatchers.IO) {
		...
	}
}

Une fois que la fonction en attente coroutine suspension (commutation pas nécessairement threads) sera suspendu le code coroutine ne fonctionne pas vers le bas jusqu'à suspendre la fonction exécutée.

withContext (), Kotlin a fourni une fonction de suspension:

public suspend fun <T> withContext(
		context: kotlin.coroutines.CoroutineContext, 
		block: suspend kotlinx.coroutines.CoroutineScope.() -> T
	) : T {   }

III. Création coroutine

a. portée coroutine CoroutineScope

Création CoroutineScope:

  • runBlocking()Blocage. Attendrons jusqu'à ce que tous les sous coroutine interne avec l' attente de l' exécution de la fonction est terminée. Intérieur crée le BlockingCoroutineblocage des objets coroutine
  • MainScope()Il n'y a pas d'implémentation bibliothèque standard spécifique (écrire une démonstration de la console se plaindra). Android est là. Le fil conducteur de la portée coroutine.
  • GlobalScopeUne classe d'objets. portée mondiale. Il ne sera pas annuler la portée non globale au niveau du père et annulé.
  • la mise en œuvre personnalisée
class MyCoroutineScope(
		override val coroutineContext: CoroutineContext
	) : CoroutineScope

CoroutineScope Fonctions avancées:

  • launch()Non bloquante. La valeur par défaut dépend CoroutineContext CoroutineScope. Retour à l'emploi. intérieur StandaloneCoroutine crée un objet (qui met en œuvre le travail, la poursuite, CoroutineScope).
  • async()Non bloquante. Il crée une nouvelle CoroutineContext. Interne crée des objets DeferredCoroutine (ils Différé, Job, Poursuite, CoroutineScope DefaultDispatcher)

b. lancement()

public fun kotlinx.coroutines.CoroutineScope.launch(
		context: kotlin.coroutines.CoroutineContext, 
		start: kotlinx.coroutines.CoroutineStart, 
		block: suspend kotlinx.coroutines.CoroutineScope.() -> kotlin.Unit
	) : kotlinx.coroutines.Job {  }

A propos des paramètres:
context: CoroutineContext contexte de coroutine
start: CoroutineStart mode de démarrage de coroutine
block: a suspendu, CoroutineScope, fonction d'extension anonyme. Par la fonction interne coroutineScope(block){}pour créer un CoroutineScopeobjet de portée coroutine.
Remarque: la fonction CoroutineScope () identique à la longue déclaration, mais pas de nom de fonction. Cependant, au moyen de tests trouvés, bloc d'appel, en fait, est la nécessité de passer un objet CoroutineScope, donc lorsque vous appelez le bloc fonctionnel est créé objet CoroutineScope.
J'ai écrit exemple,

fun test(v: Int, block: Int.()  -> Double) {
   println(block(v * 2)) //println 2048.0
}
fun calc(a: Int): Double {
   return (a shl 10) * 1.0 //2<<10 = 2048
}
test(1) {
   calc(this)
   //18.5
}

Test d'appel (), en passant un paramètre int, et une fonction, à savoir {calc (this)} Ceci est un bloc entier de paramètres de test,
test () mise en œuvre, la valeur de retour bloc d'impression (); nécessite un Int en forme de bloc paramètre, où v est multiplié à 2;
Bloquer <==> {calc (la présente)}, à ce moment cette = 2, la fonction est obtenue après calc 2048,0;
Enfin, le bloc de la valeur de retour est 2048,0 println () sur si les notes la déclaration ouverte « 18,5 », qu'il est de bloquer la valeur de retour () de. grammaire Kotlin, où les résultats dernière ligne de code comme une valeur de retour.
 

c. async ()

public fun <T> kotlinx.coroutines.CoroutineScope.async(
		context: kotlin.coroutines.CoroutineContext, 
		start: kotlinx.coroutines.CoroutineStart, 
		block: suspend kotlinx.coroutines.CoroutineScope.() -> T
	): kotlinx.coroutines.Deferred<T> { }

ré. runBlocking ()

public fun <T> runBlocking(
		context: kotlin.coroutines.CoroutineContext,  
		block: suspend kotlinx.coroutines.CoroutineScope.() -> T
	): T {  }

Ces fonctions dans l'état, le contexte, RECOMMENCERA donné une valeur par défaut.
contexte: CoroutineContext = EmptyCoroutineContext,
Début: CoroutineStart = CoroutineStart.DEFAULT,

e. mode de démarrage coroutine CoroutineStart

public enum class CoroutineStart {
    DEFAULT, 						//默认的模式,立即执行协程体
    LAZY,							//只有在需要的情况下运行
    @ExperimentalCoroutinesApi		//实验性 协程 api
    ATOMIC,							//
    @ExperimentalCoroutinesApi
    UNDISPATCHED;					//
}

F. Emploi

Les principales fonctions membres:

  • jon()Attendez coroutine exécuté. (Discussion similaire # join ())
  • cancel()Annuler coroutine. Coroutine toutes les fonctions en attente sont résiliable. Ils chèques annulés coroutine et lancers francs annulé CancellationException.
  • cancelAndJoin()A l'intérieur est le premier cancel () puis rejoindre (). Attendez que l'annulation complète

g. différés

Il est un sous-interface de Job. Il y a await().
await()Est une fonction de suspension, il a un type de retour <T>.
Appelle, sera suspendu coroutine, après la mise en œuvre pour obtenir un résultat T.

h. planificateur Dispatchers

Atteindre l'auto CoroutineContext.

public actual object Dispatchers {
	public actual val Default: CoroutineDispatcher = createDefaultDispatcher()
	public actual val Main: MainCoroutineDispatcher get() = 
			MainDispatcherLoader.dispatcher
	public actual val Unconfined: CoroutineDispatcher = 
			kotlinx.coroutines.Unconfined
	public val IO: CoroutineDispatcher = DefaultScheduler.IO
}

Andrews principale consommation d'énergie que le fil interface utilisateur, la console ne peut pas être utilisé, n'est pas mis en œuvre.
Un fil répartiteur IO pool de threads interne; effectuer un disque ou d'un réseau d' entrée / sortie à haute intensité,
un pool de taraudage du filetage répartiteur par défaut, exécutée de forte intensité cpu;
unconfined sans restriction

i. D'autres fonctions Suspend

  • delay()Combien de millisecondes coroutine est suspendu. (Thread.sleep similaires ())
  • yield()Si possible, le fil de Dispatchers de coroutine courant (ou un pool de threads) disponible à d'autres programmes de coopération. (Thread.yield similaires ()). L'exemple suivant, sera sortie entrelacée:
// 同是 Main、Default、Unconfined,才会在 yield 切换运行的协程时,在同一线程中。
// IO 会创建新线程。 Default 内部是一个线程池。
runBlocking {
    launch(Dispatchers.Unconfined, CoroutineStart.LAZY) {
        for (i in 0..3) {
            println("aaaa ${Thread.currentThread().name}")
            yield()
        }
    }
    launch(Dispatchers.Unconfined, CoroutineStart.LAZY) {
        for (i in 0..3) {
            println("bbbb  ${Thread.currentThread().name}")
            yield()
        }
    }
}

IV. Procédé Utilisation

  • Tout d'abord créer la portée coroutine (en même temps, il va créer un coroutine interne)
  • portée Coroutine, en plus du code ordinaire et peut contenir d'autres coroutine suspendre la fonction (bien sûr, il peut y avoir d'autres sous-coroutine suspendre la fonction)
  • Vous pouvez spécifier CoroutineContext, Dispatchers, CoroutineStart
  • Nécessité de coroutine être rejoindre, annuler l'opération, ou d'attendre les résultats, lanuch utilisés pour sélectionner () ou async (),
    l'emploi différé est une sous - classe se joindre aussi, annuler l' opération, qui
  • withContext est une fonction en attente. Pour l'utiliser, à savoir soins non coroutine se joindre, annuler, opération await

Publié 400 articles originaux · louange 364 won · Vues 1,62 millions +

Je suppose que tu aimes

Origine blog.csdn.net/jjwwmlp456/article/details/104859936
conseillé
Classement