@
- 反編譯后代碼分析
關(guān)于協(xié)程的一些理解
?協(xié)程掛起讓異步代碼可以像同步代碼一樣調(diào)用,但其本質(zhì)還是同步,即協(xié)程體中的代碼其實(shí)是同步。
?
?因?yàn)閰f(xié)程也只是對(duì)線(xiàn)程池的封裝,所以需要了解些線(xiàn)程的一些知識(shí)。線(xiàn)程本身已經(jīng)有的協(xié)程也會(huì)有,但是協(xié)程有的線(xiàn)程不一定有
?
?編譯器會(huì)為每一個(gè)掛起函數(shù)生成一個(gè)匿名內(nèi)部類(lèi),其繼承SuspendLabmba類(lèi)重寫(xiě)其invokeSuspend方法,這個(gè)方法里面即為協(xié)程體的代碼【大致內(nèi)容請(qǐng)先了解】
?
?編譯器會(huì)對(duì)協(xié)程體中的掛起函數(shù)和普通函數(shù)進(jìn)行切割,切割時(shí)進(jìn)行l(wèi)abel的自增來(lái)保證之后代碼的執(zhí)行順序,即協(xié)程保證運(yùn)行順序的本質(zhì)?!緦?duì)比線(xiàn)程:進(jìn)行PC程序計(jì)數(shù)器的控制來(lái)恢復(fù)執(zhí)行】
?
?協(xié)程體中會(huì)添加一個(gè)label字段,標(biāo)識(shí)接下來(lái)該運(yùn)行協(xié)程體中的哪行代碼【即協(xié)程如何知道自己執(zhí)行到哪步是用這個(gè)label完成的】(對(duì)比線(xiàn)程:線(xiàn)程存儲(chǔ)下一個(gè)代碼指令是用PC計(jì)數(shù)器來(lái)做的)
?
?協(xié)程體中的數(shù)據(jù),看過(guò)之前那篇文章的人應(yīng)該大致了解掛起函數(shù)其實(shí)就是匿名內(nèi)部類(lèi),數(shù)據(jù)是保存在棧幀中的,(對(duì)比線(xiàn)程:也是通過(guò)棧幀中的局部變量表和操作數(shù)棧來(lái)存儲(chǔ)數(shù)據(jù))
?
?協(xié)程體中碰到掛起函數(shù)會(huì)直接返回,等待掛起函數(shù)通知
?
?當(dāng)我們調(diào)用掛起函數(shù)時(shí)都會(huì)傳入一個(gè)Continuation,掛起函數(shù)執(zhí)行完正常退出或者拋異常退出這個(gè)時(shí)候外面的協(xié)程需要知道這個(gè)信息,怎么通知呢?通過(guò)Continuation的resumewith方法,這個(gè)方法會(huì)再次調(diào)用invokeSuspend取出label來(lái)保證之后執(zhí)行代碼的順序,即協(xié)程自動(dòng)恢復(fù)運(yùn)行的本質(zhì)
?
?(對(duì)比線(xiàn)程:方法正常執(zhí)行完成之后有兩種情況1、正常結(jié)束,2.異常退出。其里面的PC計(jì)數(shù)器保證之后執(zhí)行的代碼順序,也就是說(shuō)協(xié)程在原本線(xiàn)程之上又加了一層控制)
?
?協(xié)程體中可以在開(kāi)啟一個(gè)協(xié)程,也就是協(xié)程具有父子關(guān)系的本質(zhì)。在協(xié)程伊始的時(shí)候會(huì)默認(rèn)給一些默認(rèn)數(shù)據(jù)(包括協(xié)程體運(yùn)行在哪個(gè)線(xiàn)程即調(diào)度器其通過(guò)攔截器實(shí)現(xiàn),執(zhí)行狀態(tài)檢測(cè)用到的Job,攔截器等等)這些數(shù)據(jù)保存在協(xié)程的上下文中,
?
?當(dāng)在協(xié)程體中又開(kāi)啟了一個(gè)協(xié)程時(shí),其會(huì)獲取父協(xié)程的上下文進(jìn)行和自己的合并作為自己的上下文。
【簡(jiǎn)而言之,和協(xié)程本身有關(guān)的數(shù)據(jù)保存在上下文中,和業(yè)務(wù)有關(guān)的代碼會(huì)放在匿名內(nèi)部類(lèi)中?!?/p>
?
基礎(chǔ)框架層源碼分析
val createCoroutine = suspend {
//掛起函數(shù)代碼
}.createCoroutine(object : Continuation<Unit> {
override val context: CoroutineContext
get() = TODO("Not yet implemented")
override fun resumeWith(result: Result<Unit>) {
//可從result中獲取返回值或異常
}
})
createCoroutine.resume(Unit)
?1.編譯器會(huì)對(duì)掛起函數(shù)做處理,讓他繼承SuspendCorunting,重寫(xiě)其invokeSuspend方法,方法體為掛起函數(shù)中的代碼 2.當(dāng)手動(dòng)調(diào)用createCoroutine返回值的resume方法的時(shí)候,會(huì)調(diào)用到resumeWith函數(shù),其里面會(huì)調(diào)用invokeSuspend也就是掛起函數(shù)體里面的代碼,之后兩種情況:3.碰到普通函數(shù)直接執(zhí)行;碰到掛起函數(shù)傳入Continuation并直接返回一個(gè)標(biāo)識(shí)代表其為掛起函數(shù),這個(gè)時(shí)候協(xié)程直接退出,之后掛起函數(shù)執(zhí)行完調(diào)用Continuation的resumeWith繼續(xù)執(zhí)行方法體代碼【通過(guò)label確定順序】 4.在invokeSuepend中可以通過(guò)result獲取掛起函數(shù)執(zhí)行的結(jié)果:異?;蛘叻祷刂?。進(jìn)行對(duì)應(yīng)處理。
?
實(shí)戰(zhàn)分析
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
GlobalScope.launch {
println("掛起點(diǎn)1開(kāi)始")
delay(1000) //掛起點(diǎn)1
println("掛起點(diǎn)1結(jié)束")
hello() //掛起點(diǎn)2
println("掛起點(diǎn)2結(jié)束")
delay(1000) //掛起點(diǎn)3
println("掛起點(diǎn)3結(jié)束")
word() //掛起點(diǎn)4
}
}
//掛起函數(shù),編譯器默認(rèn)傳入Continuation
suspend fun hello(){
//再次掛起
withContext(Dispatchers.IO){
delay(1000)
println("hello")
}
}
suspend fun word(){
withContext(Dispatchers.IO){
delay(1000)
println("word")
}
}
-
封裝
+關(guān)注
關(guān)注
128文章
8651瀏覽量
145394 -
代碼
+關(guān)注
關(guān)注
30文章
4899瀏覽量
70658 -
線(xiàn)程
+關(guān)注
關(guān)注
0文章
508瀏覽量
20199
發(fā)布評(píng)論請(qǐng)先 登錄
一種用于反編譯代碼與源代碼的比較算法
8051系列單片機(jī)反編譯軟件(工具)

C32asm國(guó)產(chǎn)靜態(tài)反編譯工具源代碼
FoxPro編程愛(ài)好者的反編譯工具源代碼
8051 MCU反編譯開(kāi)發(fā)方法記錄[

java反編譯常用的保護(hù)技術(shù)
反編譯后代碼分析2
SpringBoot項(xiàng)目Jar包加密防止反編譯方案

評(píng)論