Slide 1

Slide 1 text

ஹನૉղࠗ۽੉೧ೞח୭੸ച࠺ߨ ✨૑ࢿ࠼

Slide 2

Slide 2 text

👋૑ࢿ࠼ 🏠TVOHCJO 🏰TVOHCJOMBOE 🐙HJUIVCDPNKJTVOHCJO

Slide 3

Slide 3 text

/PEF4ZTUFN $PNQPTF6* 4OBQTIPU4ZTUFN $PNQPTF$PNQJMFS 8SBQVQ 📖ݾର

Slide 4

Slide 4 text

/PEF4ZTUFN $PNQPTF6* 4OBQTIPU4ZTUFN $PNQPTF$PNQJMFS 8SBQVQ 📖ݾର $PNQPTF3VOUJNF $PNQPTF6* +FUQBDL$PNQPTF

Slide 5

Slide 5 text

↟ ӝળ ↟ ੗ࣁೠѐ֛ࢤۚ 📝द੘ೞӝ੹ী

Slide 6

Slide 6 text

1. Node System *OUSPEVDJOH/PEF 4MPU5BCMF(SPVQ !3FBE0OMZ$PNQPTBCMF $PNQPTJUJPO 3VOUJNF 3FDPNQPTJUJPO4NBSU %POVUIPMFTLJQQJOH

Slide 7

Slide 7 text

@Composable fun UiNodes() { Column { repeat(3) { index -> Text(text = "My index is $index") } } } Column Text Text Text

Slide 8

Slide 8 text

@Composable fun UiNodes() { Column { repeat(3) { index -> Text(text = "My index is $index") } } } Ui Node Ui Node Ui Node Ui Node

Slide 9

Slide 9 text

$PNQPTF3VOUJNF/PEFJOUFSGBDF $PNQPTF6*/PEFJNQMFNFOUBUJPO

Slide 10

Slide 10 text

/** * ஹನૉ੄ ݽٚ ؘ੉ఠܳ ੷੢ೞҊ ҙܻೞח ௿ېझ ੑפ׮. * Gap Buffer ੗ܐҳઑ৬ ےؒ ঘࣁझ۽ ҳഅعҊ, ղࠗ ؘ੉ఠח Array ী ੷੢ؾפ׮. */ internal class SlotTable : CompositionData, Iterable

Slide 11

Slide 11 text

Gap Buffer: ࢎਊೡ ҕрٜਸ ޷ܻ ഛࠁ೧ فҊ, ೧׼ ҕрীࢲ ੘সਸ ૓೯ೞח ੗ܐ ҳઑ. ਤఃೖ٣ইীࢲח زੌೠ ਤ஖ Ӕ୊ী ௿۞झఠ݂ػ ബਯ੸ੋ ࢗੑ ߂ ࢏ઁ ੘সਸ ೲਊೞח ز੸ ߓৌ ੉ۄҊ ੿੄ೞҊ ੓णפ׮.

Slide 12

Slide 12 text

Gap Buffer: زੌೠ ਤ஖ Ӕ୊ী ௿۞झఠ݂ػ ബਯ੸ੋ ࢗੑ ߂ ࢏ઁ ੘সਸ ೲਊೞח ز੸ ߓৌ 1, ୡӝ Gap ࢤࢿ: O(N) [(v)_, _, _, _, _, _, _, _, _, _] // _ ח Gap, (v) ח അ੤ cursor ܳ աఋն

Slide 13

Slide 13 text

Gap Buffer: زੌೠ ਤ஖ Ӕ୊ী ௿۞झఠ݂ػ ബਯ੸ੋ ࢗੑ ߂ ࢏ઁ ੘সਸ ೲਊೞח ز੸ ߓৌ 1, ୡӝ Gap ࢤࢿ: O(N) [(v)_, _, _, _, _, _, _, _, _, _] // _ ח Gap, (v) ח അ੤ cursor ܳ աఋն 2. 0ߣ૩ ੋؙझী Hi ࢗੑ [(v)H, i, _, _, _, _, _, _, _, _] // ݽف Gap ী ࢗੑغ޲۽ ୶о Gap ࢤࢿ੉ ೙ਃೞ૑ ঋই O(1) ী ৮ܐؽ

Slide 14

Slide 14 text

Gap Buffer: زੌೠ ਤ஖ Ӕ୊ী ௿۞झఠ݂ػ ബਯ੸ੋ ࢗੑ ߂ ࢏ઁ ੘সਸ ೲਊೞח ز੸ ߓৌ 1, ୡӝ Gap ࢤࢿ: O(N) [(v)_, _, _, _, _, _, _, _, _, _] // _ ח Gap, (v) ח അ੤ cursor ܳ աఋն 2. 0ߣ૩ ੋؙझী Hi ࢗੑ [(v)H, i, _, _, _, _, _, _, _, _] // ݽف Gap ী ࢗੑغ޲۽ ୶о Gap ࢤࢿ੉ ೙ਃೞ૑ ঋই O(1) ী ৮ܐؽ 3. 1ߣ૩ ੋؙझ੄ i ઁѢ [H, (v)_, _, _, _, _, _, _, _, _] // cursor ܳ i о ੓ח ਤ஖۽ ৤ӝӝ ਤ೧ O(N) ੉ ѦܻҊ // ੉റ Gap ীࢲ ч ઁѢо ૓೯غ޲۽ O(1) ݅ী ৮ܐؽ (ч ઁѢח ೧׼ чਸ Gap ਵ۽ ߸҃ೞח Ѫਵ۽ ҳഅؾפ׮)

Slide 15

Slide 15 text

Gap Buffer: زੌೠ ਤ஖ Ӕ୊ী ௿۞झఠ݂ػ ബਯ੸ੋ ࢗੑ ߂ ࢏ઁ ੘সਸ ೲਊೞח ز੸ ߓৌ 1, ୡӝ Gap ࢤࢿ: O(N) [(v)_, _, _, _, _, _, _, _, _, _] // _ ח Gap, (v) ח അ੤ cursor ܳ աఋն 2. 0ߣ૩ ੋؙझী Hi ࢗੑ [(v)H, i, _, _, _, _, _, _, _, _] // ݽف Gap ী ࢗੑغ޲۽ ୶о Gap ࢤࢿ੉ ೙ਃೞ૑ ঋই O(1) ী ৮ܐؽ 3. 1ߣ૩ ੋؙझ੄ i ઁѢ [H, (v)_, _, _, _, _, _, _, _, _] // cursor ܳ i о ੓ח ਤ஖۽ ৤ӝӝ ਤ೧ O(N) ੉ ѦܻҊ // ੉റ Gap ীࢲ ч ઁѢо ૓೯غ޲۽ O(1) ݅ী ৮ܐؽ (ч ઁѢח ೧׼ чਸ Gap ਵ۽ ߸҃ೞח Ѫਵ۽ ҳഅؾפ׮) 4. 0ߣ૩ ੋؙझ੄ H ܳ Bye ۽ ߸҃ [(v)B, y, e, _, _, _, _, _, _, _] // cursor ܳ H о ੓ח ਤ஖۽ ৤ӝӝ ਤ೧ O(N) ੉ ѦܻҊ // ੉റ ݽف Gap ীࢲ ч সؘ੉౟о ૓೯غ޲۽ O(1) ݅ী ৮ܐؽ

Slide 16

Slide 16 text

var isLoading = false @Composable fun Main() { Column { // 1ߣ૩ ਤ஖ (അ੤ cursor) Text(text = "Column Data") if (isLoading) { Text(text = "Loading...") } } } Column Text “Column Data” Gap Gap Gap Gap Gap Gap ߣ૩ਤ஖

Slide 17

Slide 17 text

var isLoading = true @Composable fun Main() { Column { // 1ߣ૩ ਤ஖ (੉੹ cursor) Text(text = "Column Data") if (isLoading) { // 2ߣ૩ ਤ஖ (അ੤ cursor) Text(text = "Loading...") } } } Column Text “Column Data” Gap Gap Gap Gap Text “Loading…” ߣ૩ਤ஖ ߣ૩ਤ஖

Slide 18

Slide 18 text

/** * Gap ਸ ޖदೞҊ ౠ੿ ਤ஖੄ ੺؀੸ੋ ੋؙझܳ оܰఃח ېಌੑפ׮. (ےؒ ঘࣁझ ഝࢿച) * * ےؒ ঘࣁझ: ؘ੉ఠܳ ੷੢ೞח ࠶۾ਸ ೠߣী ৈ۞ ѐ ঘࣁझೞח Ѫ੉ ইפۄ ౠ੿ ਤ஖۽ ߄۽ ੽Ӕೞৈ ೠ ߣী ೞա੄ ࠶۾݅ਸ ঘࣁझೞח ߑध */ internal class Anchor(loc: Int) { internal var location = loc val valid get() = location != Int.MIN_VALUE fun toIndexFor(slots: SlotTable) = slots.anchorIndex(this) fun toIndexFor(writer: SlotWriter) = writer.anchorIndex(this) }

Slide 19

Slide 19 text

var isLoading = true @Composable fun Main() { Column { Text(text = "Column Data") if (isLoading) { // Anchor ۽ ߄۽ ੽Ӕ Text(text = "Loading...") } } } Column “Column Data” Gap Gap Gap Gap Text “Loading…” "ODIPS۽߄۽੽Ӕ Text

Slide 20

Slide 20 text

@Composable fun Main() { Column { Text(text = "Column Data") } } Column Text “Column Data” Gap Gap Gap Gap Gap Gap

Slide 21

Slide 21 text

@Composable fun Main() { Column { Text(text = "Column Data") } } “Column Data” Gap Gap Gap Gap Gap Gap Group Group

Slide 22

Slide 22 text

@Composable fun Main() { Column { Text(text = "Column Data") } } “Column Data” Gap Gap Gap Gap Gap Gap Group Group 3FTUBSUBCMF(SPVQ 3FQMBDFBCMF(SPVQ .PWBCMF(SPVQ

Slide 23

Slide 23 text

// RestartableGroup: ܻஹನ૑࣌੉ ੌযզ ࣻ ੓ח ஹನ੷࠶ ઱ਤ۽ ࢤࢿػ׮. // ߹ب੄ ২࣌੉ হ׮ݶ ݽٚ ஹನ੷࠶ী ؀೧ ࢤࢿغח Ӓܛ੉Ҋ, // ܻஹನ૑࣌ ೞח ߑߨਸ оܰ஘׮. // ݽٚ RestartableGroup ਷ ೧׼ ߧਤ ݅ఀ // ੗୓੄ ܻஹನ૑࣌ झ௏೐(RecomposeScope)ܳ ഋࢿೠ׮. @Composable fun RestartableContainer() { Text(text = "SungbinLand") } RestartableGroup “SungbinLand” Gap Gap Gap Gap Gap Gap RestartableGroup 3FTUBSUBCMF$POUBJOFS 3FDPNQPTF4DPQF 5FYU 3FDPNQPTF4DPQF

Slide 24

Slide 24 text

// ReplaceableGroup: ࠙ӝী ٮۄ ੤ߓ஖ ؼ ࣻ ੓ח ஹನ੷࠶ ઱ਤ۽ ࢤࢿػ׮. // Ӓܛਸ Ү୓೧ঠ ೡ ٸ ੘ࢿػ ؘ੉ఠܳ ੿ܻೞח ߑߨਸ оܰ஘׮. @Composable fun ReplaceableContainer(isColumn: Boolean = true) { when (isColumn) { true -> Text(text = "Column") else -> Text(text = "Row") } } RestartableGroup “Column” Gap Gap Gap Gap Gap ReplaceableGroup 3FQMBDFBCMF$POUBJOFS XIFO RestartableGroup 5FYU

Slide 25

Slide 25 text

/** * ஹನ੷࠶੉ ߓ஖ػ ਤ஖о ׳ۄ૑ݶ ਤ஖ ݫݽ੉ઁ੉࣌੄ key о ׳ۄઉࢲ ؘ੉ఠо ୡӝചؾפ׮. * ؘ੉ఠܳ ਬ૑ೠ ࢚క۽ ਤ஖ܳ ৤ӝӝ ਤ೧ࢶ key ஹನ੷࠶ਸ ੉ਊ೧ * ਤ஖ ݫݽ੉ઁ੉࣌ীࢲ ଵҊೡ key ܳ ૒੽ ੿੄೧ঠ ೤פ׮. * * key ஹನ੷࠶ਸ ੉ਊ೧ ߓ஖ػ ஹನ੷࠶਷ ઱ਤ۽ MovableGroup ੉ ࢤࢿؾפ׮. * MovableGroup ਷ ஹನ੷࠶੉ ਤ஖ ݫݽ੉ઁ੉࣌ key ৬ ؘ੉ఠܳ ೦࢚ ࠁઓೞݴ * ੉زೞח ߑߨਸ оܰ஝פ׮. */ @Composable inline fun key( vararg keys: Any?, block: @Composable () -> T ) @Composable fun MovableContainer() { key(Any()) { Text(text = "Key") } } RestartableGroup “Key” Gap Gap Gap Gap Gap MovableGroup .PWBCMF$POUBJOFS LFZ RestartableGroup 5FYU

Slide 26

Slide 26 text

!3FBE0OMZ$PNQPTBCMF object MaterialTheme { val colors: Colors @Composable @ReadOnlyComposable get() = LocalColors.current val typography: Typography @Composable @ReadOnlyComposable get() = LocalTypography.current // … } @Composable @ReadOnlyComposable fun stringResource(@StringRes id: Int): String { val resources = resources() return resources.getString(id) }

Slide 27

Slide 27 text

var isLoading = false @Composable fun Main() { Column { Text(text = "Column Data") if (isLoading) { Text(text = "Loading...") } } } Column Text “Column Data” Gap Gap Gap Gap Gap Gap Composition

Slide 28

Slide 28 text

var isLoading = true @Composable fun Main() { Column { Text(text = "Column Data") if (isLoading) { Text(text = "Loading...") } } } Column Text “Column Data” Gap Gap Gap Gap Text “Loading…” Recomposition

Slide 29

Slide 29 text

@Composable fun Main() { var number by remember { mutableStateOf(0) } Button(onClick = { number++ }) { Text(text = number.toString()) } } Button Function0 Gap Gap Gap Gap Text “$number” Smart-Recomposition Gap

Slide 30

Slide 30 text

EPOVUIPMFTLJQQJOH setContent { var number by remember { mutableStateOf(0) } println("setContent recomposition") Text( modifier = Modifier.clickable { number++ }, text = number.toString() ).also { println("Text recomposition") } } /* ܻஹನ૑࣌੉ য٣ী ૓೯ؼөਃ? 1, setContent content ৔৉ 2. Text 3. setContent content ৔৉ + Text */

Slide 31

Slide 31 text

EPOVUIPMFTLJQQJOH setContent { var number by remember { mutableStateOf(0) } println("setContent recomposition") Text( modifier = Modifier.clickable { number++ }, text = number.toString() ).also { println("Text recomposition") } } /* [first-composition] setContent recomposition Text recomposition [re-composition] setContent recomposition Text recomposition ੉റ زੌ ۽Ӓ ߈ࠂ */

Slide 32

Slide 32 text

EPOVUIPMFTLJQQJOH setContent { var number by remember { mutableStateOf(0) } println("setContent recomposition") Button(onClick = { number++ }) { Text( text = number.toString() ).also { println("Text recomposition") } }.also { println("Button recomposition") } } /* [first-composition] setContent recomposition Text recomposition Button recomposition [re-composition] Text recomposition ੉റ زੌ ۽Ӓ ߈ࠂ */

Slide 33

Slide 33 text

EPOVUIPMFTLJQQJOH // ஹ౵ੌ ੹ @Composable fun TextWrapper(text: String) { Text(text = text) } // ஹ౵ੌ റ (೨ब ࠗ࠙݅ ಴द) fun TextWrapper(composer: Composer, text: String) { composer.startRestartGroup(-199242123) // ղࠗীࢲ addRecomposeScope() ۽ ܻஹನ૑࣌ झ௏೐ܳ ୶оೞҊ ੓਺ Text(text = text) composer.endRestartGroup() }

Slide 34

Slide 34 text

EPOVUIPMFTLJQQJOH setContent { var number by remember { mutableStateOf(0) } println("setContent recomposition") Text( modifier = Modifier.clickable { number++ }, text = number.toString() ).also { println("Text recomposition") } } setContent { var number by remember { mutableStateOf(0) } println("setContent recomposition") Button(onClick = { number++ }) { Text( text = number.toString() ).also { println("Text recomposition") } }.also { println("Button recomposition") } } Text RecomposeScope 
 Text RecomposeScope 


Slide 35

Slide 35 text

EPOVUIPMFTLJQQJOH setContent { var number by remember { mutableStateOf(0) } println("setContent recomposition") Button(onClick = { number++ }) { Text( text = number.toString() ).also { println("Text recomposition") } }.also { println("Button recomposition") } } Text RecomposeScope 
 Button RecomposeScope

Slide 36

Slide 36 text

2. Compose UI %SBXJOH1SPDFTT.PEJGJFSPQUJNJ[F $PNQPTJUJPO 6*

Slide 37

Slide 37 text

Composition Layout Draw @Composable fun Main() { Text( modifier = Modifier .clickable { getOne() }, text = "Hello, World!" ) } fun getOne() = 1

Slide 38

Slide 38 text

@Composable fun Main() { Text( modifier = Modifier .clickable { getOne() }, text = "Hello, World!" ) } fun getOne() = 1 RestartableGroup Function0 Gap Gap Composition Layout Draw “Hello, World!” Gap Gap Gap Gap

Slide 39

Slide 39 text

Modifier.offset { IntOffset(x = 0, y = 0) } Modifier.layout { measurable, constraints -> val placeable = measurable.measure(constraints) layout(width = 0, height = 0) { placeable.place(x = 0, y = 0, zIndex = 1f) } } Modifier.graphicsLayer { scaleX = 1f; rotationX = 0f; clip = false shape = RectangleShape; translationX = 0f alpha = 1f; shadowElevation = 0f } SomeGroup Function0 Gap Composition Layout Draw Function0 Gap Gap Gap Gap Function0

Slide 40

Slide 40 text

Modifier.offset { IntOffset(x = 0, y = 0) } Modifier.layout { measurable, constraints -> val placeable = measurable.measure(constraints) layout(width = 0, height = 0) { placeable.place(x = 0, y = 0, zIndex = 1f) } } Modifier.graphicsLayer { scaleX = 1f; rotationX = 0f; clip = false shape = RectangleShape; translationX = 0f alpha = 1f; shadowElevation = 0f } SomeGroup Function0 Gap Composition Layout Draw Function0 Gap Gap Gap Gap Function0 Skippable

Slide 41

Slide 41 text

RestartableGroup Function0 Gap Gap Composition Layout Draw “Hello, World!” Text Int “Hello, World!” ۨ੉ইਓઁডઑѤ DPOTUSBJOUT ҅࢑ ठܶప੉࠶ч҅࢑ JOWPLF 6*౟ܻҳ୷

Slide 42

Slide 42 text

Composition Layout Draw Text Int “Hello, World!”

Slide 43

Slide 43 text

@Composable fun Main() { Text( modifier = Modifier .clickable { getOne() }, text = "Hello, World!” ) } fun getOne() = 1 RestartableGroup Function0 Gap Gap Composition Layout Draw “Hello, World!” Gap Gap Gap Gap

Slide 44

Slide 44 text

Composition Layout (SPVQѐ

Slide 45

Slide 45 text

Composition Layout (SPVQѐ ҅࢑೧ঠೞח(SPVQѐ $PNQPTJUJPO௼ӝীٮۄ0 / ૐо

Slide 46

Slide 46 text

Composition Layout Draw SubComposition ࠗݽ੄ઁডઑѤ֢୹ ן਷ୡӝച

Slide 47

Slide 47 text

Composition Layout Draw Composition DPOTUSBJOUT ࠗݽ੄ઁডઑѤ֢୹ @Stable interface BoxWithConstraintsScope : BoxScope { val constraints: Constraints val minWidth: Dp val maxWidth: Dp val minHeight: Dp val maxHeight: Dp }

Slide 48

Slide 48 text

Composition Layout Draw ן਷ୡӝച @Composable fun LazyLayout() @Composable fun LazyRow() @Composable fun LazyColumn() -B[Z-BZPVU਷ചݶীաఋաӝ߄۽੹ী-BZPVU%SBX૓೯

Slide 49

Slide 49 text

Composition SubComposition

Slide 50

Slide 50 text

Composition SubComposition SubComposition SubComposition SubComposition 😅

Slide 51

Slide 51 text

3. Snapshot System *OUSPEVDJOH4OBQTIPU 5JNF$PNQMFYJUZ $PNQPTJUJPO-PDBM

Slide 52

Slide 52 text

State CompositionLocal SnapshotStateList

Slide 53

Slide 53 text

4OBQTIPU

Slide 54

Slide 54 text

4OBQTIPU ஹನ੷࠶਷प೯غחࣽࢲо੿೧ઉ੓૑ঋ׮ ೞա੄4UBUFоزदী߸҃ؼࣻ੓਺ ࢚క୽ج

Slide 55

Slide 55 text

4OBQTIPU ݒ࢚క߸҃ਸ೧׼DBMMTJUFীҊ݀غѱ૓೯ೞҊ ୶റҊ݀ػ߸҃ਸਗࠄ࢚కী߈৔ೞחӝࣿ ࢚క߸҃੄Ҋ݀ࢿदझమ

Slide 56

Slide 56 text

4OBQTIPU

Slide 57

Slide 57 text

4OBQTIPU 🤔

Slide 58

Slide 58 text

4OBQTIPU SomeGroup 1 Snapshot Gap Gap Gap Gap Gap Gap Gap

Slide 59

Slide 59 text

4OBQTIPU SomeGroup 1 Snapshot Gap Gap Gap Gap Gap Gap 4OBQTIPU 2 Snapshot

Slide 60

Slide 60 text

4OBQTIPU SomeGroup 1 Snapshot Gap Gap Gap Gap Gap 4OBQTIPU 2 Snapshot 4OBQTIPU 3 Snapshot

Slide 61

Slide 61 text

/4OBQTIPU SomeGroup 1 Snapshot 4 Snapshot 6 Snapshot 2 Snapshot 3 Snapshot 5 Snapshot N Snapshot 7 Snapshot

Slide 62

Slide 62 text

SomeGroup 1 Snapshot 4 Snapshot 6 Snapshot 2 Snapshot 3 Snapshot 5 Snapshot N Snapshot 7 Snapshot 4OBQTIPU3FBE 4OBQTIPU8SJUF

Slide 63

Slide 63 text

SomeGroup px - snapshot px4 - snapshot px2 - snapshot px3 - snapshot @Composable fun Main() { val px = 1.dp.px val px2 = 2.dp.px val px3 = 3.dp.px val px4 = 4.dp.px } inline val Dp.px @Composable @ReadOnlyComposable get() = with(LocalDensity.current) { toPx() } Gap Gap Gap Gap

Slide 64

Slide 64 text

SomeGroup density - snapshot @Composable fun Main() { val density = LocalDensity.current val px = with(density) { 1.dp.toPx() } val px2 = with(density) { 2.dp.toPx() } val px3 = with(density) { 3.dp.toPx() } val px4 = with(density) { 4.dp.toPx() } } Gap Gap Gap Gap Gap Gap Gap

Slide 65

Slide 65 text

DPNQPTJUJPO-PDBM0G val LocalTextSelectionColors = compositionLocalOf { DefaultTextSelectionColors } val LocalTextStyle = compositionLocalOf { TextStyle.Default } val LocalConfiguration = compositionLocalOf(neverEqualPolicy()) { noLocalProvidedFor("LocalConfiguration") } val LocalContentAlpha = compositionLocalOf { 1f } SomeGroup CompositionLocal CompositionLocal Composable CompositionLocal CompositionLocal Composable Composable Composable

Slide 66

Slide 66 text

TUBUJD$PNQPTJUJPO-PDBM0G val LocalContext = staticCompositionLocalOf { noLocalProvidedFor("LocalContext") } val LocalClipboardManager = staticCompositionLocalOf { noLocalProvidedFor("LocalClipboardManager") } val LocalDensity = staticCompositionLocalOf { noLocalProvidedFor("LocalDensity") } val LocalFocusManager = staticCompositionLocalOf { noLocalProvidedFor("LocalFocusManager") } StaticCompositionLocal Composable Composable Composable Composable Composable SomeGroup Composable Composable

Slide 67

Slide 67 text

4. Compose Compiler 4UBCJMJUZ*NNVUBCMF$PMMFDUJPOT

Slide 68

Slide 68 text

4UBCJMJUZ /** * উ੿ ࢚కח ௼ѱ 3о૑੄ ઑѤਸ ٮܵפ׮. * * - ч੉ ߸҃عਸ ҃਋ ஹನ੷࠶ীѱ ঌ۰ઉঠ ೤פ׮. (૊, [State] ۽ ੘زظঠ ೣ) * - чী ߸҃੉ হח ҃਋ ੉੹ ੋझఢझ৬ അ੤ ੋझఢझо زੌ೧ঠ ೤פ׮. * - ݽٚ ҕѐ ೙ٜ٘ب ׮ উ੿ ࢚కৈঠ ೤פ׮. * * ੉ 3о૑ ઑѤਸ ٮܲ׮ݶ ஹನૉח ೧׼ ೙٘о উ੿੸ੋ ࢚కۄҊ ౵ঈೞҊ, * ೧׼ ೙٘੄ ч੉ ߄Շ૑ ঋও׮ݶ ࢎਊػ ஹನ੷࠶੄ ܻஹನ૑࣌ਸ ࢤۚ೤פ׮. * * @see Immutable * @see Stable */ @Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) annotation class StableMarker

Slide 69

Slide 69 text

/** * ࢤࢿػ ੉റ۽ ݽٚ ҕѐ੸ੋ ೙٘о ੺؀ ߸ೞ૑ ঋח׮ח Ѫਸ աఋղݴ ௿ېझী ੸ਊؼ ࣻ ੓णפ׮. * * ࢤࢿ ੉റ ч੉ ߸҃غ૑ ঋਵ޲۽ উ੿੄ ୐ ߣ૩ ӏ஗ੋ * "ч੉ ߸҃عਸ ҃਋ ஹನ੷࠶ীѱ ঌ۰ઉঠ ೤פ׮." о ޖदؾפ׮. */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) @StableMarker annotation class Immutable fun main() { val list = mutableListOf(1) list.add(2) // ੋझఢझח زੌೞ૑݅ ч੉ ߄Չ ࣻ ੓णפ׮. // @Immutable ਷ ੉۞ೠ ߸҃ب ೲਊೞ૑ ঋणפ׮. }

Slide 70

Slide 70 text

/** * ч੉ ߸҃ؼ ࣻ ੓ח ࢚క੉ݴ, ੸ਊ ؀࢚ী ٮۄ ডрঀ ৉ೡ੉ ׳ۄ૘פ׮. * * ఋੑী ੸ਊػ׮ݶ ୶о ৉ೡ হ੉ [StableMarker] ੄ ৉ೡਸ Ӓ؀۽ оઉцפ׮. * * ೣࣻա ೐۽ಌ౭ী ੸ਊػ׮ݶ [StableMarker] ੄ ৉ೡী ୶оغח ৉ೡ੉ ࢤӤפ׮. * э਷ input ী ੓যࢲח ೦࢚ زੌೠ output ਸ ٜ݅যղݴ(ࣽࣻ ೣࣻ), ೣࣻ੄ ҃਋ ੋ੗ٜ ৉द ݽف উ੿੸ੋ ࢚కۄח Ѫਸ ডࣘ೤פ׮. * ݅ড input ੉ زੌೞ׮ݶ output ژೠ زੌೡ Ѫ੉ӝ ٸޙী ܻஹನ૑࣌ਸ झఈೞѱ ؾפ׮. */ @Target( AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY ) @Retention(AnnotationRetention.BINARY) @StableMarker annotation class Stable

Slide 71

Slide 71 text

// উ੿ࢿ਷ ੹౵ػ׮. @Immutable interface SungbinLand class SungbinLandImpl : SungbinLand // ߈ജೞח SungbinLand о উ੿ ࢚క੉ӝ ٸޙী // ೣࣻী StableMarker о হযب ੉ ೣࣻח উ੿ ࢚క۽ р઱ػ׮. fun provideSungbinLand(): SungbinLand = SungbinLandImpl() // data ੋ੗੄ ఋੑ੉ উ੿ ࢚క੉ӝ ٸޙী data ੋ੗ח উ੿ ࢚కо غҊ, // ੉ ஹನ੷࠶਷ skippable ࢚కо ػ׮. @Composable fun SungbinLandDisplay(data: SungbinLand = provideSungbinLand()) { Text(text = data.toString()) }

Slide 72

Slide 72 text

// উ੿ࢿ਷ ੹౵ػ׮. interface SungbinLand @Immutable class SungbinLandImpl : SungbinLand // ߈ജೞח SungbinLand ী ؀ೠ উ੿ࢿ ੿ࠁо হӝ ٸޙী ੉ ೣࣻח ࠛউ੿ ࢚కо ػ׮. fun provideSungbinLand(): SungbinLand = SungbinLandImpl() // data ੋ੗੄ ఋੑ਷ ࠛউ੿ ࢚క੉૑݅, provideSungbinLand() ೣࣻীࢲ чਸ ઁҕೞחؘ ࢎਊೞח // SungbinLandImpl ௿ېझח উ੿ ࢚క੉ӝ ٸޙী data ੋ੗੄ ӝࠄ ч੉ উ੿ ࢚కۄ // ੉ ஹನ੷࠶਷ skippable ࢚కо ػ׮. (ױ, ৈ੹൤ data ੋ੗ח ࠛউ੿ ࢚క۽ թח׮) @Composable fun SungbinLandDisplay(data: SungbinLand = provideSungbinLand()) { Text(text = data.toString()) }

Slide 73

Slide 73 text

@Composable fun ListDisplay(texts: List) { Text(text = texts.joinToString()) }

Slide 74

Slide 74 text

public interface MutableList : List, MutableCollection @Composable fun ListDisplay(texts: List = mutableListOf()) { Text(text = texts.joinToString()) }

Slide 75

Slide 75 text

@Immutable @JvmInline value class ImmutableListWrapper(val value: List) @Composable fun ListDisplay(texts: ImmutableListWrapper) { Text(text = texts.value.joinToString()) }

Slide 76

Slide 76 text

// https://github.com/Kotlin/kotlinx.collections.immutable @Composable fun ListDisplay(texts: ImmutableList) { Text(text = texts.joinToString()) }

Slide 77

Slide 77 text

/** * ஹ౵ੌ द੼ী ݽٚ ௿ېझٜ੄ উ੿ࢿਸ ੗زਵ۽ ୶ۿ೤פ׮. * * @param parameters উ੿ࢿਸ ୶ۿೞחؘ ب਑੉ ؼ ࣻ ੓ѱ ੋ੗ٜ੄ ࠺౟݃झ௼ܳ աఋշפ׮. */ @ComposeCompilerApi @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) annotation class StabilityInferred(val parameters: Int) // ਬੌೠ ೙٘ੋ value о উ੿ ࢚క੉Ҋ ࠛ߸ೞӝ ٸޙী Name ௿ېझח উ੿ ࢚క۽ ౸ױػ׮. class Name(val value: String) // ਬੌೠ ೙٘ੋ value ੄ ఋੑ੉ ઁ֎ܼ੉ۄ ఋੑਸ ౸ױೡ ࣻ হӝী ࢎ੹ী ࠺౟݃झఊػ чਸ ӝળਵ۽ উ੿ ࢚కܳ ୶ۿೠ׮. // ೞ૑݅ ೙٘о о߸ ࢚క੉ӝ ٸޙী T ఋੑ੉ উ੿੉ৈب NameWithGeneric ௿ېझח ࠛউ੿ ࢚క۽ ౸ױػ׮. class NameWithGeneric(var value: T)

Slide 78

Slide 78 text

8IZ উ੿ࢿ੿ࠁоহ਺೧׼ஹನ੷࠶੄ੋ੗ী߸ز੉হ׮Ҋഛनೡࣻহ਺ উ੿ࢿ੿ࠁоহ਺೦࢚ܻஹನ૑࣌૓೯ TLJQQBCMF࢚కࠛоמ

Slide 79

Slide 79 text

↟ೣԋࠁݶજਸ੗ܐ 5. Wrap-up -BNCEB0QUJNJ[JOH -JWF-JUFSBM $PNQJMFS.FUSJDT 4OBQTIPU4ZTUFNXJUI.7$$ #BTFMJOFQSPGJMFT $PNQPTF(SPVQT 50%0

Slide 80

Slide 80 text

5. Wrap-up ↟#0.ߡ੹ҙܻद੘ def composeBom = platform("androidx.compose:compose-bom:2022.10.00") implementation composeBom androidTestImplementation composeBom

Slide 81

Slide 81 text

5. Wrap-up ↟উ੹ೠ4UBUFࣻ૘DPMMFDU"T4UBUF8JUI-JGFDZDMF

Slide 82

Slide 82 text

%6$,*& IUUQTHJUIVCDPNEVDLJFUFBN IUUQTPQFOTPVSDFEVDLJFUFBN IUUQTMJOLEVDLJFUFBNTMBDL

Slide 83

Slide 83 text

хࢎ೤פ׮ ஹನૉ ղࠗ ௏ٜ٘਷ cs.android.com ীࢲ оઉ৳णפ׮. ੉ ೐ۨઃప੉࣌ীח షझ౱ীࢲ ઁҕೠ షझಕ੉झо ੸ਊغয ੓णפ׮. QnA🙋