{"id":6101,"date":"2026-07-19T00:48:08","date_gmt":"2026-07-18T21:18:08","guid":{"rendered":"https:\/\/notes.yummybrands.studio\/?p=6101"},"modified":"2026-07-23T02:27:37","modified_gmt":"2026-07-22T22:57:37","slug":"%d8%b3%d8%a7%d8%ae%d8%aa-%d8%a7%d9%be%d9%84%db%8c%da%a9%db%8c%d8%b4%d9%86-%d8%a7%d9%86%d8%af%d8%b1%d9%88%d8%a6%db%8c%d8%af-%da%86%d9%87%d8%a7%d8%b1%d9%85","status":"publish","type":"post","link":"https:\/\/notes.yummybrands.studio\/?p=6101","title":{"rendered":"\u0633\u0627\u062e\u062a \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0627\u0646\u062f\u0631\u0648\u0626\u06cc\u062f (\u0686\u0647\u0627\u0631\u0645)"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">\u0628\u062e\u0634 \u0647\u0634\u062a\u0645 \u2014 \u0639\u0645\u0644\u06a9\u0631\u062f<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">\u062f\u0631\u0633 \u067e\u0646\u062c\u0627\u0647\u200c\u0648\u0686\u0647\u0627\u0631\u0645<\/h3>\n\n\n\n<h1 class=\"wp-block-heading\">Memory<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Memory \u062f\u0631 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u062f\u0642\u06cc\u0642\u0627\u064b \u0628\u0647 \u0686\u06cc \u0627\u0634\u0627\u0631\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647\u061f<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"768\" height=\"1024\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-03-1-768x1024.avif\" alt=\"\" class=\"wp-image-6157\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-03-1-768x1024.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-03-1-225x300.avif 225w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-03-1.avif 1086w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u062f\u0631 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0627\u0632 <strong>Memory<\/strong> \u062d\u0631\u0641 \u0645\u06cc\u200c\u0632\u0646\u06cc\u0645\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0645\u0646\u0638\u0648\u0631\u0645\u0648\u0646 \u062d\u0627\u0641\u0638\u0647 RAM\u06cc\u0647 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0646\u06af\u0627\u0645 \u0627\u062c\u0631\u0627 \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647\u061b \u06cc\u0639\u0646\u06cc \u062d\u0627\u0641\u0638\u0647\u200c\u0627\u06cc \u06a9\u0647 Object\u0647\u0627\u060c \u062a\u0635\u0648\u06cc\u0631\u0647\u0627\u060c \u0635\u0641\u062d\u0647\u200c\u0647\u0627\u06cc Compose\u060c \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0645\u0648\u0642\u062a\u060c Cache\u0647\u0627 \u0648 \u0646\u062a\u06cc\u062c\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647 \u062f\u0627\u062e\u0644\u0634 \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0646. \u0627\u06cc\u0646 \u062d\u0627\u0641\u0638\u0647 \u0628\u0627 Storage \u0641\u0631\u0642 \u062f\u0627\u0631\u0647. Storage \u0647\u0645\u0648\u0646 \u0641\u0636\u0627\u06cc \u062f\u0627\u0626\u0645\u06cc \u06af\u0648\u0634\u06cc\u0647 \u06a9\u0647 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u060c \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 Room \u0648 DataStore \u062f\u0627\u062e\u0644\u0634 \u0628\u0627\u0642\u06cc \u0645\u06cc\u200c\u0645\u0648\u0646\u0646\u060c \u0627\u0645\u0627 \u0627\u0637\u0644\u0627\u0639\u0627\u062a RAM \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0641\u0642\u0637 \u062a\u0627 \u0648\u0642\u062a\u06cc \u0641\u0631\u0627\u06cc\u0646\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0632\u0646\u062f\u0647 \u0627\u0633\u062a \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0628\u0631\u0627\u06cc \u0647\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u06cc\u06a9 \u0641\u0631\u0627\u06cc\u0646\u062f \u062c\u062f\u0627 \u0648 \u0645\u0642\u062f\u0627\u0631 \u0645\u062d\u062f\u0648\u062f\u06cc Heap \u062f\u0631 \u0646\u0638\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647. \u0627\u0646\u062f\u0627\u0632\u0647 \u062f\u0642\u06cc\u0642 \u0627\u06cc\u0646 \u062d\u0627\u0641\u0638\u0647 \u0631\u0648\u06cc \u0647\u0645\u0647 \u062f\u0633\u062a\u06af\u0627\u0647\u200c\u0647\u0627 \u06cc\u06a9\u0633\u0627\u0646 \u0646\u06cc\u0633\u062a \u0648 \u0628\u0647 RAM\u060c \u0646\u0633\u062e\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0648 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0633\u0627\u0632\u0646\u062f\u0647 \u0628\u0633\u062a\u06af\u06cc \u062f\u0627\u0631\u0647. \u0627\u06af\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0628\u06cc\u0634\u062a\u0631 \u0627\u0632 \u0638\u0631\u0641\u06cc\u062a \u0645\u062c\u0627\u0632\u0634 \u062d\u0627\u0641\u0638\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u0646\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 \u0628\u0627 OutOfMemoryError \u0645\u062a\u0648\u0642\u0641 \u0628\u0634\u0647. \u0627\u0632 \u0637\u0631\u0641 \u062f\u06cc\u06af\u0631\u060c \u0648\u0642\u062a\u06cc \u062d\u0627\u0641\u0638\u0647 \u0633\u06cc\u0633\u062a\u0645 \u06a9\u0645 \u0645\u06cc\u0634\u0647\u060c \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0641\u0631\u0627\u06cc\u0646\u062f \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u067e\u0633\u200c\u0632\u0645\u06cc\u0646\u0647 \u0631\u0648 \u0627\u0632 \u0628\u06cc\u0646 \u0628\u0628\u0631\u0647 \u062a\u0627 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u0645\u0647\u0645\u200c\u062a\u0631 \u062d\u0627\u0641\u0638\u0647 \u0622\u0632\u0627\u062f \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06cc\u0639\u0646\u06cc \u0646\u0628\u0627\u06cc\u062f \u062a\u0635\u0648\u0631 \u06a9\u0646\u06cc\u0645 \u0686\u0648\u0646 Kotlin \u0648 Android \u062f\u0627\u0631\u0627\u06cc Garbage Collector \u0647\u0633\u062a\u0646\u060c \u062f\u06cc\u06af\u0647 \u0647\u06cc\u0686 \u0645\u0633\u0626\u0648\u0644\u06cc\u062a\u06cc \u062f\u0631\u0628\u0627\u0631\u0647 \u062d\u0627\u0641\u0638\u0647 \u0646\u062f\u0627\u0631\u06cc\u0645. Garbage Collector \u0622\u0628\u062c\u06a9\u062a\u200c\u0647\u0627\u06cc\u06cc \u0631\u0648 \u067e\u0627\u06a9 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u06cc\u06af\u0647 \u0631\u0627\u0647\u06cc \u0628\u0631\u0627\u06cc \u062f\u0633\u062a\u0631\u0633\u06cc \u0628\u0647\u0634\u0648\u0646 \u0646\u062f\u0627\u0631\u0647. \u0627\u0645\u0627 \u0627\u06af\u0647 \u0645\u0627 \u0646\u0627\u062e\u0648\u0627\u0633\u062a\u0647 Reference \u06cc\u06a9 Activity\u060c Bitmap \u06cc\u0627 List \u0628\u0632\u0631\u06af \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645\u060c Garbage Collector \u062a\u0635\u0648\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0647\u0646\u0648\u0632 \u0628\u0647 \u0627\u0648\u0646 \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u06cc\u0645 \u0648 \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062d\u0627\u0641\u0638\u0647\u200c\u0627\u0634 \u0631\u0648 \u0622\u0632\u0627\u062f \u06a9\u0646\u0647. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Garbage Collector \u0686\u0637\u0648\u0631 \u062a\u0635\u0645\u06cc\u0645 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647 \u0686\u06cc \u0631\u0648 \u067e\u0627\u06a9 \u06a9\u0646\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u06cc\u06a9 Object \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645\u060c \u0641\u0636\u0627\u06cc \u0644\u0627\u0632\u0645 \u0628\u0631\u0627\u06cc \u0627\u0648\u0646 \u062f\u0627\u062e\u0644 Heap \u0628\u0631\u0646\u0627\u0645\u0647 \u06af\u0631\u0641\u062a\u0647 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" dir=\"ltr\">val product =\n    Product(\n        id = 42,\n        title = &#8220;Laptop&#8221;,\n        price = 58_000_000\n    )\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u0648\u0642\u062a\u06cc \u0645\u062a\u063a\u06cc\u0631 \u06cc\u0627 Object \u062f\u06cc\u06af\u0631\u06cc \u0628\u0647 <code>product<\/code> \u062f\u0633\u062a\u0631\u0633\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0627\u06cc\u0646 Object \u0632\u0646\u062f\u0647 \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0647. \u0648\u0642\u062a\u06cc \u062f\u06cc\u06af\u0647 \u0647\u06cc\u0686 \u0645\u0633\u06cc\u0631 \u0642\u0627\u0628\u0644\u200c\u062f\u0633\u062a\u0631\u0633\u06cc\u200c\u0627\u06cc \u0628\u0647 \u0627\u0648\u0646 \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c Garbage Collector \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062d\u0627\u0641\u0638\u0647\u200c\u0627\u0634 \u0631\u0648 \u067e\u0633 \u0628\u06af\u06cc\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u062f\u0631 \u0627\u06cc\u0646 \u062a\u0627\u0628\u0639\u060c \u0628\u0639\u062f \u0627\u0632 \u067e\u0627\u06cc\u0627\u0646 \u0627\u062c\u0631\u0627 \u0645\u0639\u0645\u0648\u0644\u0627\u064b Reference \u0645\u062d\u0644\u06cc \u0627\u0632 \u0628\u06cc\u0646 \u0645\u06cc\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun printTemporaryProduct() {\n    val product =\n        Product(\n            id = 42,\n            title = \"Laptop\",\n            price = 58_000_000\n        )\n\n    println(product.title)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">printTemporaryProduct<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> product <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            id <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">42<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            title <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Laptop&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            price <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">58_000_000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">println<\/span><span style=\"color: #24292E\">(product.title)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0627\u06af\u0647 \u0647\u0645\u0648\u0646 Object \u0631\u0648 \u062f\u0627\u062e\u0644 \u06cc\u06a9 Collection \u0633\u0631\u0627\u0633\u0631\u06cc \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645\u060c \u0647\u0645\u0686\u0646\u0627\u0646 \u0642\u0627\u0628\u0644\u200c\u062f\u0633\u062a\u0631\u0633\u06cc \u0628\u0627\u0642\u06cc \u0645\u06cc\u200c\u0645\u0648\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>object ProductMemoryCache {\n\n    private val products =\n        mutableListOf&lt;Product>()\n\n    fun add(product: Product) {\n        products.add(product)\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductMemoryCache<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">mutableListOf<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt;()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">add<\/span><span style=\"color: #24292E\">(product: <\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        products.<\/span><span style=\"color: #6F42C1\">add<\/span><span style=\"color: #24292E\">(product)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u0648\u0642\u062a\u06cc <code>products<\/code> \u067e\u0627\u06a9 \u0646\u0634\u0647\u060c \u062a\u0645\u0627\u0645 Object\u0647\u0627\u06cc \u062f\u0627\u062e\u0644\u0634 \u0647\u0645 \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u0628\u0627\u0642\u06cc \u0645\u06cc\u200c\u0645\u0648\u0646\u0646. Garbage Collector \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062a\u0634\u062e\u06cc\u0635 \u0628\u062f\u0647 \u06a9\u0647 \u0645\u0627 \u0627\u0632 \u0646\u0638\u0631 \u0645\u0646\u0637\u0642\u06cc \u062f\u06cc\u06af\u0647 \u0628\u0647 \u0627\u0648\u0646\u200c\u0647\u0627 \u0646\u06cc\u0627\u0632 \u0646\u062f\u0627\u0631\u06cc\u0645\u061b \u0641\u0642\u0637 \u0645\u06cc\u200c\u0628\u06cc\u0646\u0647 \u0647\u0646\u0648\u0632 \u06cc\u06a9 Reference \u0645\u0639\u062a\u0628\u0631 \u0628\u0647\u0634\u0648\u0646 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Android Runtime \u0627\u0632 Heap \u0646\u0633\u0644\u200c\u0628\u0646\u062f\u06cc\u200c\u0634\u062f\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647. Object\u0647\u0627\u06cc \u062a\u0627\u0632\u0647 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u062f\u0631 \u0646\u0633\u0644 \u062c\u0648\u0627\u0646 \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0646 \u0648 Object\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0645\u062f\u062a \u0628\u06cc\u0634\u062a\u0631\u06cc \u0632\u0646\u062f\u0647 \u0645\u06cc\u200c\u0645\u0648\u0646\u0646 \u0628\u0647 \u0646\u0633\u0644\u200c\u0647\u0627\u06cc \u0642\u062f\u06cc\u0645\u06cc\u200c\u062a\u0631 \u0645\u0646\u062a\u0642\u0644 \u0645\u06cc\u0634\u0646. \u0633\u0627\u062e\u062a \u062a\u0639\u062f\u0627\u062f \u0632\u06cc\u0627\u062f\u06cc Object \u06a9\u0648\u062a\u0627\u0647\u200c\u0639\u0645\u0631 \u0628\u0627\u0639\u062b \u0627\u062c\u0631\u0627\u06cc \u0628\u06cc\u0634\u062a\u0631 Garbage Collection \u0645\u06cc\u0634\u0647 \u0648 \u0627\u06af\u0647 \u0627\u06cc\u0646 \u0627\u062a\u0641\u0627\u0642 \u0648\u0633\u0637 Animation \u06cc\u0627 \u0627\u0633\u06a9\u0631\u0648\u0644 \u0631\u062e \u0628\u062f\u0647\u060c \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0628\u0627\u0639\u062b \u0627\u0641\u062a \u0641\u0631\u06cc\u0645 \u0648 \u06a9\u0646\u062f\u06cc \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Memory Leak \u06cc\u0639\u0646\u06cc \u062d\u0627\u0641\u0638\u0647 \u06af\u0645 \u0634\u062f\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0633\u0645 Memory Leak \u0645\u0645\u06a9\u0646\u0647 \u0627\u06cc\u0646 \u062a\u0635\u0648\u0631 \u0631\u0648 \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0647 \u06a9\u0647 \u062d\u0627\u0641\u0638\u0647 \u0648\u0627\u0642\u0639\u0627\u064b \u0627\u0632 \u0633\u06cc\u0633\u062a\u0645 \u0646\u0627\u067e\u062f\u06cc\u062f \u0634\u062f\u0647\u060c \u0627\u0645\u0627 \u062f\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc Kotlin \u0648 Java \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0645\u0634\u06a9\u0644 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u06cc\u06a9 Reference \u0628\u06cc\u0634\u062a\u0631 \u0627\u0632 \u0632\u0645\u0627\u0646 \u0644\u0627\u0632\u0645 \u0632\u0646\u062f\u0647 \u0645\u0648\u0646\u062f\u0647. \u0645\u062b\u0644\u0627\u064b Activity \u0628\u0633\u062a\u0647 \u0634\u062f\u0647\u060c \u0627\u0645\u0627 \u06cc\u06a9 Singleton \u0647\u0646\u0648\u0632 Reference \u0627\u0648\u0646 Activity \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0647. \u062f\u0631 \u0646\u062a\u06cc\u062c\u0647 Activity \u0647\u0645\u0631\u0627\u0647 \u062a\u0645\u0627\u0645 View\u0647\u0627\u060c \u062a\u0635\u0648\u06cc\u0631\u0647\u0627 \u0648 State\u0647\u0627\u06cc \u062e\u0648\u062f\u0634 \u0642\u0627\u0628\u0644 \u067e\u0627\u06a9 \u0634\u062f\u0646 \u0646\u06cc\u0633\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0645\u0648\u0646\u0647 \u0627\u0634\u062a\u0628\u0627\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>object AnalyticsManager {\n\n    private var context: Context? = null\n\n    fun initialize(context: Context) {\n        this.context = context\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AnalyticsManager<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> context: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">initialize<\/span><span style=\"color: #24292E\">(context: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">this<\/span><span style=\"color: #24292E\">.context <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> context<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0647 \u0627\u06cc\u0646 \u0645\u062a\u062f \u0631\u0648 \u0627\u0632 Activity \u0635\u062f\u0627 \u0628\u0632\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>AnalyticsManager.initialize(this)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">AnalyticsManager.<\/span><span style=\"color: #6F42C1\">initialize<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">this<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Singleton \u062a\u0627 \u067e\u0627\u06cc\u0627\u0646 \u0639\u0645\u0631 \u0641\u0631\u0627\u06cc\u0646\u062f \u0632\u0646\u062f\u0647 \u0645\u06cc\u200c\u0645\u0648\u0646\u0647 \u0648 Activity \u0631\u0648 \u0647\u0645 \u0647\u0645\u0631\u0627\u0647 \u062e\u0648\u062f\u0634 \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u0647. \u062d\u062a\u06cc \u0627\u06af\u0647 \u06a9\u0627\u0631\u0628\u0631 Activity \u0631\u0648 \u0628\u0628\u0646\u062f\u0647 \u06cc\u0627 \u06af\u0648\u0634\u06cc \u0628\u0686\u0631\u062e\u0647\u060c Activity \u0642\u0628\u0644\u06cc \u0645\u0645\u06a9\u0646\u0647 \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u0628\u0627\u0642\u06cc \u0628\u0645\u0648\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u0627\u0647 \u0628\u0647\u062a\u0631 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0641\u0642\u0637 ApplicationContext \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>object AnalyticsManager {\n\n    private lateinit var applicationContext: Context\n\n    fun initialize(context: Context) {\n        applicationContext =\n            context.applicationContext\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AnalyticsManager<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">lateinit<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> applicationContext: <\/span><span style=\"color: #6F42C1\">Context<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">initialize<\/span><span style=\"color: #24292E\">(context: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        applicationContext <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            context.applicationContext<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ApplicationContext<\/code> \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0628\u0647 \u0627\u0646\u062f\u0627\u0632\u0647 \u0641\u0631\u0627\u06cc\u0646\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0639\u0645\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0627\u0648\u0646 \u062f\u0627\u062e\u0644 Singleton \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0628\u0627\u0639\u062b Leak \u0634\u062f\u0646 Activity \u0646\u0645\u06cc\u0634\u0647. \u0627\u0635\u0644 \u06a9\u0644\u06cc \u0627\u06cc\u0646\u0647: <strong>Object \u06a9\u0648\u062a\u0627\u0647\u200c\u0639\u0645\u0631 \u0646\u0628\u0627\u06cc\u062f \u062a\u0648\u0633\u0637 Object \u0628\u0644\u0646\u062f\u0639\u0645\u0631 \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0634\u0647.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Activity \u0648 Fragment \u0639\u0645\u0631 \u0645\u062d\u062f\u0648\u062f\u06cc \u062f\u0627\u0631\u0646\u060c \u0627\u0645\u0627 Singleton\u060c Repository \u0633\u0631\u0627\u0633\u0631\u06cc\u060c Coroutine \u0628\u062f\u0648\u0646 Scope \u0645\u0646\u0627\u0633\u0628 \u0648 Callback \u062b\u0628\u062a\u200c\u0634\u062f\u0647 \u0645\u0645\u06a9\u0646\u0647 \u0645\u062f\u062a \u062e\u06cc\u0644\u06cc \u0628\u06cc\u0634\u062a\u0631\u06cc \u0632\u0646\u062f\u0647 \u0628\u0645\u0648\u0646\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u06cc\u06a9 Memory Leak \u0648\u0627\u0642\u0639\u06cc \u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0628\u0631\u0627\u06cc \u062f\u0631\u06cc\u0627\u0641\u062a \u062a\u063a\u06cc\u06cc\u0631 \u0642\u06cc\u0645\u062a\u200c\u0647\u0627 \u06cc\u06a9 Listener \u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface PriceUpdateListener {\n\n    fun onPriceUpdated(\n        productId: Long,\n        newPrice: Long\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceUpdateListener<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onPriceUpdated<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        newPrice: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Repository \u0647\u0645 Listener\u0647\u0627 \u0631\u0648 \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class PriceRepository {\n\n    private val listeners =\n        mutableSetOf&lt;PriceUpdateListener>()\n\n    fun addListener(\n        listener: PriceUpdateListener\n    ) {\n        listeners.add(listener)\n    }\n\n    fun removeListener(\n        listener: PriceUpdateListener\n    ) {\n        listeners.remove(listener)\n    }\n\n    fun notifyPriceChanged(\n        productId: Long,\n        newPrice: Long\n    ) {\n        listeners.forEach { listener ->\n            listener.onPriceUpdated(\n                productId,\n                newPrice\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceRepository<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> listeners <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">mutableSetOf<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">PriceUpdateListener<\/span><span style=\"color: #24292E\">&gt;()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">addListener<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        listener: <\/span><span style=\"color: #6F42C1\">PriceUpdateListener<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        listeners.<\/span><span style=\"color: #6F42C1\">add<\/span><span style=\"color: #24292E\">(listener)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">removeListener<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        listener: <\/span><span style=\"color: #6F42C1\">PriceUpdateListener<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        listeners.<\/span><span style=\"color: #6F42C1\">remove<\/span><span style=\"color: #24292E\">(listener)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">notifyPriceChanged<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        newPrice: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        listeners.<\/span><span style=\"color: #6F42C1\">forEach<\/span><span style=\"color: #24292E\"> { listener <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            listener.<\/span><span style=\"color: #6F42C1\">onPriceUpdated<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                productId,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                newPrice<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 Activity \u062e\u0648\u062f\u0634 \u0631\u0648 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 Listener \u062b\u0628\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductActivity :\n    AppCompatActivity(),\n    PriceUpdateListener {\n\n    override fun onCreate(\n        savedInstanceState: Bundle?\n    ) {\n        super.onCreate(savedInstanceState)\n\n        priceRepository.addListener(this)\n    }\n\n    override fun onPriceUpdated(\n        productId: Long,\n        newPrice: Long\n    ) {\n        \/\/ \u0628\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0635\u0641\u062d\u0647\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductActivity<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">AppCompatActivity<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">PriceUpdateListener<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        savedInstanceState: <\/span><span style=\"color: #6F42C1\">Bundle<\/span><span style=\"color: #24292E\">?<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">(savedInstanceState)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        priceRepository.<\/span><span style=\"color: #6F42C1\">addListener<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">this<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onPriceUpdated<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        newPrice: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6A737D\">\/\/ \u0628\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0635\u0641\u062d\u0647<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0634\u06a9\u0644 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0627\u06af\u0647 Activity \u0627\u0632 \u0628\u06cc\u0646 \u0628\u0631\u0647 \u0648\u0644\u06cc Listener \u062d\u0630\u0641 \u0646\u0634\u0647\u060c Repository \u0647\u0645\u0686\u0646\u0627\u0646 Reference \u0627\u0648\u0646 \u0631\u0648 \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u0647. \u067e\u0633 \u0628\u0627\u06cc\u062f \u062f\u0631 \u0632\u0645\u0627\u0646 \u0645\u0646\u0627\u0633\u0628 \u062b\u0628\u062a \u0631\u0648 \u0644\u063a\u0648 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>override fun onDestroy() {\n    priceRepository.removeListener(this)\n\n    super.onDestroy()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onDestroy<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    priceRepository.<\/span><span style=\"color: #6F42C1\">removeListener<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">this<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onDestroy<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0631\u0648\u0634 \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0627\u0645\u0627 \u0628\u0647 \u062d\u0627\u0641\u0638\u0647 \u0648 \u062f\u0642\u062a \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633 \u0648\u0627\u0628\u0633\u062a\u0647 \u0627\u0633\u062a. \u0641\u0631\u0627\u0645\u0648\u0634 \u06a9\u0631\u062f\u0646 \u0641\u0642\u0637 \u06cc\u06a9 <code>removeListener()<\/code> \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 Leak \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0647. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u062f\u0631 \u0645\u0639\u0645\u0627\u0631\u06cc\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f \u0645\u0639\u0645\u0648\u0644\u0627\u064b <code>Flow<\/code> \u0648 Lifecycle \u0631\u0648 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 Listener\u0647\u0627\u06cc \u062f\u0633\u062a\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Flow \u0631\u0648 \u0628\u0631\u0627\u0633\u0627\u0633 Lifecycle \u062c\u0645\u0639\u200c\u0622\u0648\u0631\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 Repository \u062a\u063a\u06cc\u06cc\u0631 \u0642\u06cc\u0645\u062a\u200c\u0647\u0627 \u0631\u0648 \u0628\u0627 StateFlow \u0645\u0646\u062a\u0634\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class PriceRepository {\n\n    private val _priceUpdates =\n        MutableStateFlow&lt;Map&lt;Long, Long>>(\n            emptyMap()\n        )\n\n    val priceUpdates:\n        StateFlow&lt;Map&lt;Long, Long>> =\n        _priceUpdates.asStateFlow()\n\n    fun updatePrice(\n        productId: Long,\n        newPrice: Long\n    ) {\n        _priceUpdates.update { current ->\n            current + (\n                productId to newPrice\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceRepository<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> _priceUpdates <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">MutableStateFlow<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Map<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">&gt;&gt;(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">emptyMap<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> priceUpdates:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        StateFlow<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">Map<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">Long, Long<\/span><span style=\"color: #D73A49\">&gt;&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        _priceUpdates.<\/span><span style=\"color: #6F42C1\">asStateFlow<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">updatePrice<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        newPrice: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        _priceUpdates.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> { current <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            current <\/span><span style=\"color: #D73A49\">+<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                productId to newPrice<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0627\u062e\u0644 Activity \u0646\u0628\u0627\u06cc\u062f \u06cc\u06a9 Coroutine \u0628\u062f\u0648\u0646 \u062a\u0648\u062c\u0647 \u0628\u0647 Lifecycle \u0628\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>lifecycleScope.launch {\n    priceRepository.priceUpdates.collect {\n        \/\/ \u0645\u0645\u06a9\u0646\u0647 \u062d\u062a\u06cc \u0648\u0642\u062a\u06cc \u0635\u0641\u062d\u0647 \u0642\u0627\u0628\u0644\u200c\u0645\u0634\u0627\u0647\u062f\u0647 \u0646\u06cc\u0633\u062a \u0627\u062f\u0627\u0645\u0647 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u0647\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">lifecycleScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    priceRepository.priceUpdates.<\/span><span style=\"color: #6F42C1\">collect<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6A737D\">\/\/ \u0645\u0645\u06a9\u0646\u0647 \u062d\u062a\u06cc \u0648\u0642\u062a\u06cc \u0635\u0641\u062d\u0647 \u0642\u0627\u0628\u0644\u200c\u0645\u0634\u0627\u0647\u062f\u0647 \u0646\u06cc\u0633\u062a \u0627\u062f\u0627\u0645\u0647 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u0647<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u0648\u0634 \u0628\u0647\u062a\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 <code>repeatOnLifecycle<\/code> \u0627\u0633\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>override fun onCreate(\n    savedInstanceState: Bundle?\n) {\n    super.onCreate(savedInstanceState)\n\n    lifecycleScope.launch {\n        repeatOnLifecycle(\n            Lifecycle.State.STARTED\n        ) {\n            priceRepository\n                .priceUpdates\n                .collect { prices ->\n                    renderPrices(prices)\n                }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    savedInstanceState: <\/span><span style=\"color: #6F42C1\">Bundle<\/span><span style=\"color: #24292E\">?<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">(savedInstanceState)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    lifecycleScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">repeatOnLifecycle<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Lifecycle.State.STARTED<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            priceRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .priceUpdates<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">collect<\/span><span style=\"color: #24292E\"> { prices <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #6F42C1\">renderPrices<\/span><span style=\"color: #24292E\">(prices)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc Activity \u0628\u0647 \u0648\u0636\u0639\u06cc\u062a <code>STARTED<\/code> \u0645\u06cc\u0631\u0633\u0647\u060c Collection \u0634\u0631\u0648\u0639 \u0645\u06cc\u0634\u0647. \u0648\u0642\u062a\u06cc \u0635\u0641\u062d\u0647 \u0645\u062a\u0648\u0642\u0641 \u0645\u06cc\u0634\u0647\u060c Coroutine \u062f\u0627\u062e\u0644\u06cc \u0644\u063a\u0648 \u0645\u06cc\u0634\u0647 \u0648 \u0648\u0642\u062a\u06cc \u0635\u0641\u062d\u0647 \u062f\u0648\u0628\u0627\u0631\u0647 \u0634\u0631\u0648\u0639 \u0634\u062f\u060c Collection \u062a\u0627\u0632\u0647\u200c\u0627\u06cc \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647. \u0628\u0647 \u0627\u06cc\u0646 \u062a\u0631\u062a\u06cc\u0628 \u0646\u0647 \u0644\u0627\u0632\u0645 \u0627\u0633\u062a Listener \u0631\u0648 \u062f\u0633\u062a\u06cc \u062d\u0630\u0641 \u06a9\u0646\u06cc\u0645 \u0648 \u0646\u0647 \u067e\u0631\u062f\u0627\u0632\u0634 \u0628\u06cc\u200c\u062f\u0644\u06cc\u0644 \u062f\u0631 \u067e\u0633\u200c\u0632\u0645\u06cc\u0646\u0647 \u0627\u062f\u0627\u0645\u0647 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Compose \u0647\u0645 \u0628\u0647\u062a\u0631\u0647 \u0627\u0632 API \u0633\u0627\u0632\u06af\u0627\u0631 \u0628\u0627 Lifecycle \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nfun ProductRoute(\n    viewModel: ProductViewModel\n) {\n    val uiState by\n        viewModel.uiState\n            .collectAsStateWithLifecycle()\n\n    ProductScreen(\n        uiState = uiState\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductRoute<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    viewModel: <\/span><span style=\"color: #6F42C1\">ProductViewModel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> uiState <\/span><span style=\"color: #D73A49\">by<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModel.uiState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">collectAsStateWithLifecycle<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">ProductScreen<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        uiState <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> uiState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0631\u0648\u0634 \u0628\u0647\u062a\u0631 \u0627\u0632 <code>collectAsState<\/code> \u062e\u0627\u0645\u0647\u060c \u0686\u0648\u0646 Collection \u0631\u0648 \u0628\u0627 Lifecycle \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0647\u0645\u0627\u0647\u0646\u06af \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Coroutine \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0628\u0627\u0639\u062b \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u062d\u0627\u0641\u0638\u0647 \u0628\u0634\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Coroutine \u0630\u0627\u062a\u0627\u064b Memory Leak \u0646\u06cc\u0633\u062a\u060c \u0627\u0645\u0627 \u0627\u06af\u0647 \u062f\u0627\u062e\u0644 Scope \u0627\u0634\u062a\u0628\u0627\u0647 \u0627\u062c\u0631\u0627 \u0628\u0634\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 Object\u0647\u0627 \u0631\u0648 \u0628\u06cc\u0634 \u0627\u0632 \u062d\u062f \u0644\u0627\u0632\u0645 \u0632\u0646\u062f\u0647 \u0646\u06af\u0647 \u062f\u0627\u0631\u0647. \u0646\u0645\u0648\u0646\u0647 \u062e\u0637\u0631\u0646\u0627\u06a9:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductActivity :\n    AppCompatActivity() {\n\n    override fun onCreate(\n        savedInstanceState: Bundle?\n    ) {\n        super.onCreate(savedInstanceState)\n\n        GlobalScope.launch {\n            val products =\n                repository.loadProducts()\n\n            runOnUiThread {\n                showProducts(products)\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductActivity<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">AppCompatActivity<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        savedInstanceState: <\/span><span style=\"color: #6F42C1\">Bundle<\/span><span style=\"color: #24292E\">?<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">(savedInstanceState)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        GlobalScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                repository.<\/span><span style=\"color: #6F42C1\">loadProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">runOnUiThread<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">showProducts<\/span><span style=\"color: #24292E\">(products)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><code>GlobalScope<\/code> \u0628\u0647 Lifecycle Activity \u0648\u0627\u0628\u0633\u062a\u0647 \u0646\u06cc\u0633\u062a. \u0627\u06af\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0635\u0641\u062d\u0647 \u0631\u0648 \u0628\u0628\u0646\u062f\u0647\u060c Coroutine \u0647\u0645\u0686\u0646\u0627\u0646 \u0627\u062f\u0627\u0645\u0647 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u0686\u0648\u0646 \u062f\u0627\u062e\u0644 Lambda \u0628\u0647 Activity \u062f\u0633\u062a\u0631\u0633\u06cc \u062f\u0627\u0631\u06cc\u0645\u060c Activity \u0645\u0645\u06a9\u0646\u0647 \u062a\u0627 \u067e\u0627\u06cc\u0627\u0646 \u0639\u0645\u0644\u06cc\u0627\u062a \u0632\u0646\u062f\u0647 \u0628\u0645\u0648\u0646\u0647. \u0639\u0644\u0627\u0648\u0647 \u0628\u0631 \u0627\u0648\u0646\u060c \u0645\u0645\u06a9\u0646\u0647 \u0628\u0639\u062f \u0627\u0632 \u0628\u0633\u062a\u0647 \u0634\u062f\u0646 \u0635\u0641\u062d\u0647 \u062a\u0644\u0627\u0634 \u06a9\u0646\u06cc\u0645 UI \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0633\u062e\u0647 \u062f\u0631\u0633\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>lifecycleScope.launch {\n    val products =\n        repository.loadProducts()\n\n    showProducts(products)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">lifecycleScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        repository.<\/span><span style=\"color: #6F42C1\">loadProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">showProducts<\/span><span style=\"color: #24292E\">(products)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Coroutine \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 <code>lifecycleScope<\/code> \u0648\u0642\u062a\u06cc Lifecycle \u0646\u0627\u0628\u0648\u062f \u0628\u0634\u0647 \u0644\u063a\u0648 \u0645\u06cc\u0634\u0647. \u062f\u0631 ViewModel \u0647\u0645 \u0627\u0632 <code>viewModelScope<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductViewModel(\n    private val repository: ProductRepository\n) : ViewModel() {\n\n    private val _uiState =\n        MutableStateFlow(\n            ProductUiState()\n        )\n\n    val uiState =\n        _uiState.asStateFlow()\n\n    fun loadProducts() {\n        viewModelScope.launch {\n            _uiState.update {\n                it.copy(\n                    isLoading = true\n                )\n            }\n\n            val result =\n                repository.loadProducts()\n\n            _uiState.update {\n                it.copy(\n                    isLoading = false,\n                    products =\n                        result.getOrDefault(\n                            emptyList()\n                        )\n                )\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> repository: <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ViewModel<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> _uiState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">MutableStateFlow<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">ProductUiState<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> uiState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        _uiState.<\/span><span style=\"color: #6F42C1\">asStateFlow<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">loadProducts<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModelScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            _uiState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    isLoading <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> result <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                repository.<\/span><span style=\"color: #6F42C1\">loadProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            _uiState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    isLoading <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        result.<\/span><span style=\"color: #6F42C1\">getOrDefault<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            <\/span><span style=\"color: #6F42C1\">emptyList<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc ViewModel \u0628\u0631\u0627\u06cc \u0647\u0645\u06cc\u0634\u0647 \u067e\u0627\u06a9 \u0628\u0634\u0647\u060c Coroutine\u0647\u0627\u06cc <code>viewModelScope<\/code> \u0647\u0645 \u0644\u063a\u0648 \u0645\u06cc\u0634\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ViewModel \u0646\u0628\u0627\u06cc\u062f Activity \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0631\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">ViewModel \u0645\u0645\u06a9\u0646\u0647 \u0647\u0646\u06af\u0627\u0645 \u0686\u0631\u062e\u0634 \u0635\u0641\u062d\u0647 \u0632\u0646\u062f\u0647 \u0628\u0645\u0648\u0646\u0647\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 Activity \u0642\u0628\u0644\u06cc \u0646\u0627\u0628\u0648\u062f \u0634\u062f\u0647 \u0648 Activity \u062c\u062f\u06cc\u062f \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0646\u0628\u0627\u06cc\u062f Context \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 Activity\u060c View\u060c NavController \u06cc\u0627 Binding \u0631\u0648 \u062f\u0627\u062e\u0644 ViewModel \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0645\u0648\u0646\u0647 \u0627\u0634\u062a\u0628\u0627\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductViewModel(\n    private val activity: Activity\n) : ViewModel() {\n\n    fun showMessage() {\n        Toast.makeText(\n            activity,\n            \"\u0642\u06cc\u0645\u062a \u0628\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0634\u062f\",\n            Toast.LENGTH_SHORT\n        ).show()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> activity: <\/span><span style=\"color: #6F42C1\">Activity<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ViewModel<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">showMessage<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Toast.<\/span><span style=\"color: #6F42C1\">makeText<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            activity,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;\u0642\u06cc\u0645\u062a \u0628\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0634\u062f&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Toast.LENGTH_SHORT<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ).<\/span><span style=\"color: #6F42C1\">show<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0647 Activity \u0628\u0686\u0631\u062e\u0647\u060c ViewModel \u0647\u0645\u0686\u0646\u0627\u0646 Activity \u0642\u0628\u0644\u06cc \u0631\u0648 \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u0647 \u0648 \u0628\u0627\u0639\u062b Leak \u0645\u06cc\u0634\u0647. ViewModel \u0628\u0647\u062a\u0631\u0647 \u0641\u0642\u0637 State \u0648 Event \u062a\u0648\u0644\u06cc\u062f \u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class ProductUiState(\n    val products: List&lt;Product> =\n        emptyList(),\n    val message: String? = null\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductUiState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt; <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">emptyList<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> message: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductViewModel(\n    private val repository: ProductRepository\n) : ViewModel() {\n\n    private val _uiState =\n        MutableStateFlow(\n            ProductUiState()\n        )\n\n    val uiState =\n        _uiState.asStateFlow()\n\n    fun priceUpdated() {\n        _uiState.update {\n            it.copy(\n                message =\n                    \"\u0642\u06cc\u0645\u062a \u0628\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0634\u062f\"\n            )\n        }\n    }\n\n    fun messageShown() {\n        _uiState.update {\n            it.copy(\n                message = null\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> repository: <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ViewModel<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> _uiState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">MutableStateFlow<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">ProductUiState<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> uiState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        _uiState.<\/span><span style=\"color: #6F42C1\">asStateFlow<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">priceUpdated<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        _uiState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                message <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;\u0642\u06cc\u0645\u062a \u0628\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0634\u062f&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">messageShown<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        _uiState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                message <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u0648\u062f UI \u067e\u06cc\u0627\u0645 \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u062f\u0647 \u0648 \u0628\u0639\u062f \u0628\u0647 ViewModel \u062e\u0628\u0631 \u0645\u06cc\u062f\u0647 \u06a9\u0647 Event \u0645\u0635\u0631\u0641 \u0634\u062f\u0647. \u062f\u0631 \u0645\u0648\u0627\u0631\u062f\u06cc \u06a9\u0647 \u0648\u0627\u0642\u0639\u0627\u064b Context \u0644\u0627\u0632\u0645 \u062f\u0627\u0631\u06cc\u0645\u060c \u0628\u0647\u062a\u0631\u0647 \u0648\u0627\u0628\u0633\u062a\u06af\u06cc \u0631\u0648 \u062a\u0627 \u062d\u062f \u0627\u0645\u06a9\u0627\u0646 \u0628\u0647 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627\u06cc \u0628\u06cc\u0631\u0648\u0646 ViewModel \u0645\u0646\u062a\u0642\u0644 \u06a9\u0646\u06cc\u0645. \u0627\u06af\u0647 Context \u0628\u0631\u0646\u0627\u0645\u0647 \u0644\u0627\u0632\u0645 \u0634\u062f\u060c \u0645\u06cc\u0634\u0647 <code>ApplicationContext<\/code> \u0631\u0648 \u0628\u0627 Dependency Injection \u0648\u0627\u0631\u062f \u06a9\u0631\u062f\u061b \u0646\u0647 Activity \u0631\u0648.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0631\u0627 \u062a\u0635\u0648\u06cc\u0631\u0647\u0627 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0628\u06cc\u0634\u062a\u0631\u06cc\u0646 Memory \u0631\u0648 \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0646\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Bitmap\u0647\u0627 \u06cc\u06a9\u06cc \u0627\u0632 \u0631\u0627\u06cc\u062c\u200c\u062a\u0631\u06cc\u0646 \u062f\u0644\u0627\u06cc\u0644 \u0645\u0635\u0631\u0641 \u0628\u0627\u0644\u0627\u06cc RAM \u0647\u0633\u062a\u0646. \u0627\u0646\u062f\u0627\u0632\u0647 \u0641\u0627\u06cc\u0644 \u062a\u0635\u0648\u06cc\u0631 \u0631\u0648\u06cc \u062f\u06cc\u0633\u06a9 \u0628\u0627 \u0645\u0642\u062f\u0627\u0631 \u062d\u0627\u0641\u0638\u0647\u200c\u0627\u06cc \u06a9\u0647 \u0628\u0639\u062f \u0627\u0632 Decode \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u06cc\u06a9\u0633\u0627\u0646 \u0646\u06cc\u0633\u062a. \u0645\u062b\u0644\u0627\u064b \u06cc\u06a9 \u0641\u0627\u06cc\u0644 JPEG \u0645\u0645\u06a9\u0646\u0647 \u0641\u0642\u0637 \u06f5\u06f0\u06f0 \u06a9\u06cc\u0644\u0648\u0628\u0627\u06cc\u062a \u0628\u0627\u0634\u0647\u060c \u0627\u0645\u0627 \u0648\u0642\u062a\u06cc \u0628\u0647 Bitmap \u0628\u0627 \u0627\u0628\u0639\u0627\u062f \u06f4\u06f0\u06f0\u06f0 \u062f\u0631 \u06f3\u06f0\u06f0\u06f0 \u062a\u0628\u062f\u06cc\u0644 \u0645\u06cc\u0634\u0647\u060c \u0686\u0646\u062f \u062f\u0647 \u0645\u06af\u0627\u0628\u0627\u06cc\u062a RAM \u0645\u0635\u0631\u0641 \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0642\u0631\u06cc\u0628 \u0633\u0627\u062f\u0647 \u0645\u0635\u0631\u0641 Bitmap \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u06cc\u0646 \u0634\u06a9\u0644\u06cc\u0647: <br>\u0639\u0631\u0636 \u00d7 \u0627\u0631\u062a\u0641\u0627\u0639 \u00d7 \u062a\u0639\u062f\u0627\u062f \u0628\u0627\u06cc\u062a \u0647\u0631 Pixel<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc Bitmap \u0646\u0648\u0639 <code>ARGB_8888<\/code> \u0647\u0631 Pixel \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0686\u0647\u0627\u0631 \u0628\u0627\u06cc\u062a \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u067e\u0633 \u062a\u0635\u0648\u06cc\u0631 \u06f4\u06f0\u06f0\u06f0 \u062f\u0631 \u06f3\u06f0\u06f0\u06f0 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0686\u0646\u06cc\u0646 \u062d\u0627\u0641\u0638\u0647\u200c\u0627\u06cc \u0645\u06cc\u200c\u062e\u0648\u0627\u062f:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>4000 \u00d7 3000 \u00d7 4 = 48,000,000 bytes\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0639\u0646\u06cc \u062d\u062f\u0648\u062f \u06f4\u06f8 \u0645\u06af\u0627\u0628\u0627\u06cc\u062a \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u06cc\u06a9 \u062a\u0635\u0648\u06cc\u0631. \u0627\u06af\u0647 \u0686\u0646\u062f \u062a\u0635\u0648\u06cc\u0631 \u0628\u0632\u0631\u06af \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u062f\u0627\u062e\u0644 \u0635\u0641\u062d\u0647 \u0628\u0627\u0634\u0646\u060c \u0631\u0633\u06cc\u062f\u0646 \u0628\u0647 <code>OutOfMemoryError<\/code> \u062e\u06cc\u0644\u06cc \u062f\u0648\u0631 \u0627\u0632 \u0630\u0647\u0646 \u0646\u06cc\u0633\u062a. \u0646\u0628\u0627\u06cc\u062f \u062a\u0635\u0648\u06cc\u0631 \u0627\u0635\u0644\u06cc \u0631\u0648 \u0628\u0627 \u0627\u0628\u0639\u0627\u062f \u06a9\u0627\u0645\u0644 Decode \u06a9\u0646\u06cc\u0645 \u0648 \u0628\u0639\u062f \u062f\u0627\u062e\u0644 \u06cc\u06a9 Image \u06a9\u0648\u0686\u06a9 \u06f1\u06f2\u06f0 \u067e\u06cc\u06a9\u0633\u0644\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u06cc\u0645. \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 Coil \u062a\u0635\u0648\u06cc\u0631 \u0631\u0648 \u0628\u0631\u0627\u0633\u0627\u0633 \u0627\u0646\u062f\u0627\u0632\u0647 \u0645\u0642\u0635\u062f Decode \u0648 Cache \u0645\u06cc\u200c\u06a9\u0646\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Compose:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nfun ProductImage(\n    imageUrl: String,\n    contentDescription: String\n) {\n    AsyncImage(\n        model =\n            ImageRequest.Builder(\n                LocalContext.current\n            )\n                .data(imageUrl)\n                .crossfade(true)\n                .size(\n                    width = 300,\n                    height = 300\n                )\n                .build(),\n        contentDescription =\n            contentDescription,\n        modifier =\n            Modifier.size(120.dp),\n        contentScale =\n            ContentScale.Crop\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductImage<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    imageUrl: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    contentDescription: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">AsyncImage<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        model <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ImageRequest.<\/span><span style=\"color: #6F42C1\">Builder<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                LocalContext.current<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">data<\/span><span style=\"color: #24292E\">(imageUrl)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">crossfade<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">size<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    width <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">300<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    height <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">300<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        contentDescription <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            contentDescription,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        modifier <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Modifier.<\/span><span style=\"color: #6F42C1\">size<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">120<\/span><span style=\"color: #24292E\">.dp),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        contentScale <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ContentScale.Crop<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u062e\u06cc\u0644\u06cc \u0627\u0632 \u062d\u0627\u0644\u062a\u200c\u0647\u0627 \u062e\u0648\u062f Coil \u0627\u0646\u062f\u0627\u0632\u0647 \u0645\u0642\u0635\u062f \u0631\u0648 \u062a\u0634\u062e\u06cc\u0635 \u0645\u06cc\u062f\u0647\u060c \u0627\u0645\u0627 \u062a\u0639\u06cc\u06cc\u0646 \u0627\u0646\u062f\u0627\u0632\u0647 \u0645\u0634\u062e\u0635 \u06a9\u0645\u06a9 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u062a\u0635\u0648\u06cc\u0631 \u063a\u0648\u0644\u200c\u067e\u06cc\u06a9\u0631 \u0628\u06cc\u200c\u062f\u0644\u06cc\u0644 Decode \u0646\u0634\u0647. \u0647\u0645\u0686\u0646\u06cc\u0646 \u0646\u0628\u0627\u06cc\u062f Bitmap \u0631\u0648 \u062f\u0627\u062e\u0644 ViewModel\u060c <code>rememberSaveable<\/code> \u06cc\u0627 Singleton \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0646\u06cc\u0645. \u0628\u0647\u062a\u0631\u0647 URL \u06cc\u0627 \u0634\u0646\u0627\u0633\u0647 \u062a\u0635\u0648\u06cc\u0631 \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645 \u0648 \u0627\u062c\u0627\u0632\u0647 \u0628\u062f\u06cc\u0645 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u062a\u0635\u0648\u06cc\u0631 Cache \u0631\u0648 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cache \u0628\u0627\u06cc\u062f \u0645\u062d\u062f\u0648\u062f \u0628\u0627\u0634\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Cache \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u062f\u0627\u062f\u0647\u200c\u0647\u0627 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0628\u0634\u0646\u060c \u0627\u0645\u0627 Cache \u0646\u0627\u0645\u062d\u062f\u0648\u062f \u06cc\u0639\u0646\u06cc Memory Leak \u0637\u0631\u0627\u062d\u06cc\u200c\u0634\u062f\u0647. \u0646\u0645\u0648\u0646\u0647 \u0628\u062f:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>object ProductCache {\n\n    val products =\n        mutableMapOf&lt;Long, ProductDetails>()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductCache<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">mutableMapOf<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">ProductDetails<\/span><span style=\"color: #24292E\">&gt;()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0647\u0632\u0627\u0631\u0627\u0646 \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 \u0628\u0627\u0632 \u06a9\u0646\u0647\u060c \u0627\u06cc\u0646 Map \u062f\u0627\u0626\u0645\u0627\u064b \u0628\u0632\u0631\u06af\u200c\u062a\u0631 \u0645\u06cc\u0634\u0647 \u0648 \u0647\u06cc\u0686 \u0686\u06cc\u0632\u06cc \u0627\u0632 \u0627\u0648\u0646 \u062d\u0630\u0641 \u0646\u0645\u06cc\u0634\u0647. \u0628\u0631\u0627\u06cc Cache \u062d\u0627\u0641\u0638\u0647 \u0628\u0647\u062a\u0631\u0647 \u06cc\u06a9 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0645\u0634\u062e\u0635 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645. <code>LruCache<\/code> \u0648\u0642\u062a\u06cc \u0638\u0631\u0641\u06cc\u062a \u067e\u0631 \u0645\u06cc\u0634\u0647\u060c \u0642\u062f\u06cc\u0645\u06cc\u200c\u062a\u0631\u06cc\u0646 \u0645\u0648\u0627\u0631\u062f \u06a9\u0645\u200c\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0631\u0648 \u062d\u0630\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductMemoryCache {\n\n    private val cache =\n        object : LruCache&lt;Long, ProductDetails>(\n            100\n        ) {}\n\n    fun put(\n        product: ProductDetails\n    ) {\n        cache.put(\n            product.id,\n            product\n        )\n    }\n\n    fun get(\n        productId: Long\n    ): ProductDetails? {\n        return cache.get(productId)\n    }\n\n    fun remove(\n        productId: Long\n    ) {\n        cache.remove(productId)\n    }\n\n    fun clear() {\n        cache.evictAll()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductMemoryCache<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> cache <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        object : <\/span><span style=\"color: #6F42C1\">LruCache<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">ProductDetails<\/span><span style=\"color: #24292E\">&gt;(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #005CC5\">100<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">put<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        product: <\/span><span style=\"color: #6F42C1\">ProductDetails<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        cache.<\/span><span style=\"color: #6F42C1\">put<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            product.id,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            product<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">get<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">ProductDetails<\/span><span style=\"color: #24292E\">? {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> cache.<\/span><span style=\"color: #6F42C1\">get<\/span><span style=\"color: #24292E\">(productId)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">remove<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        cache.<\/span><span style=\"color: #6F42C1\">remove<\/span><span style=\"color: #24292E\">(productId)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">clear<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        cache.<\/span><span style=\"color: #6F42C1\">evictAll<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646\u062c\u0627 \u062d\u062f\u0627\u06a9\u062b\u0631 \u06f1\u06f0\u06f0 \u0645\u062d\u0635\u0648\u0644 \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0647 \u0645\u06cc\u0634\u0647. \u0627\u0644\u0628\u062a\u0647 \u0628\u0647\u062a\u0631\u0647 \u0638\u0631\u0641\u06cc\u062a \u0628\u0631\u0627\u0633\u0627\u0633 \u0647\u0632\u06cc\u0646\u0647 \u0648\u0627\u0642\u0639\u06cc Object\u0647\u0627 \u0627\u0646\u062a\u062e\u0627\u0628 \u0628\u0634\u0647\u060c \u0646\u0647 \u06cc\u06a9 \u0639\u062f\u062f \u062a\u0635\u0627\u062f\u0641\u06cc. \u0627\u06af\u0647 ProductDetails \u0634\u0627\u0645\u0644 \u0686\u0646\u062f Bitmap \u06cc\u0627 \u0645\u062a\u0646 \u0628\u0633\u06cc\u0627\u0631 \u0628\u0632\u0631\u06af\u0647\u060c \u062d\u062a\u06cc \u06f1\u06f0\u06f0 \u0645\u0648\u0631\u062f \u0647\u0645 \u0645\u0645\u06a9\u0646\u0647 \u0632\u06cc\u0627\u062f \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0628\u0627\u06cc\u062f \u0645\u062f\u062a \u0628\u06cc\u0634\u062a\u0631\u06cc \u0628\u0627\u0642\u06cc \u0628\u0645\u0648\u0646\u0646\u060c Cache \u062d\u0627\u0641\u0638\u0647 \u0647\u0645\u06cc\u0634\u0647 \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u0646\u0627\u0633\u0628\u06cc \u0646\u06cc\u0633\u062a. \u062f\u0627\u062f\u0647 \u0631\u0648 \u062f\u0627\u062e\u0644 Room \u0630\u062e\u06cc\u0631\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0648 \u0641\u0642\u0637 \u0628\u062e\u0634 \u0645\u0648\u0631\u062f\u0646\u06cc\u0627\u0632 \u0635\u0641\u062d\u0647 \u0631\u0648 \u0648\u0627\u0631\u062f RAM \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0644\u06cc\u0633\u062a \u062e\u06cc\u0644\u06cc \u0628\u0632\u0631\u06af \u0631\u0648 \u06cc\u06a9\u200c\u062c\u0627 \u0648\u0627\u0631\u062f \u062d\u0627\u0641\u0638\u0647 \u0646\u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0633\u0631\u0648\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0635\u062f \u0647\u0632\u0627\u0631 \u0631\u06a9\u0648\u0631\u062f \u0642\u06cc\u0645\u062a \u062f\u0627\u0631\u0647. \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0627\u0634\u062a\u0628\u0627\u0647\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@GET(\"products\")\nsuspend fun getAllProducts():\n    List&lt;ProductResponse>\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@GET<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;products&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getAllProducts<\/span><span style=\"color: #24292E\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    List<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">ProductResponse<\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0686\u0648\u0646 \u067e\u0627\u0633\u062e \u06a9\u0627\u0645\u0644 \u0628\u0627\u06cc\u062f \u062f\u0631\u06cc\u0627\u0641\u062a\u060c Parse \u0648 \u062f\u0627\u062e\u0644 \u062d\u0627\u0641\u0638\u0647 \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0628\u0634\u0647. \u0628\u0639\u062f \u0645\u0645\u06a9\u0646\u0647 \u0647\u0645 \u0646\u0633\u062e\u0647 JSON\u060c \u0647\u0645 \u0645\u062f\u0644 \u0634\u0628\u06a9\u0647\u060c \u0647\u0645 Entity \u0648 \u0647\u0645 \u0645\u062f\u0644 UI \u0628\u0631\u0627\u06cc \u0645\u062f\u062a\u06cc \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u062f\u0631 RAM \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646. \u0631\u0627\u0647 \u0628\u0647\u062a\u0631 Pagination \u0627\u0633\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface ProductApi {\n\n    @GET(\"products\")\n    suspend fun getProducts(\n        @Query(\"page\")\n        page: Int,\n        @Query(\"limit\")\n        limit: Int\n    ): ProductPageResponse\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductApi<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@GET<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;products&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getProducts<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;page&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        page: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;limit&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        limit: <\/span><span style=\"color: #6F42C1\">Int<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">ProductPageResponse<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062f\u0644 \u067e\u0627\u0633\u062e:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class ProductPageResponse(\n    val items: List&lt;ProductResponse>,\n    val currentPage: Int,\n    val hasNextPage: Boolean\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductPageResponse<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> items: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">ProductResponse<\/span><span style=\"color: #24292E\">&gt;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> currentPage: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> hasNextPage: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u067e\u0631\u0648\u0698\u0647 \u0628\u0632\u0631\u06af\u200c\u062a\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0627\u0632 Paging 3 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645 \u062a\u0627 \u0641\u0642\u0637 \u0635\u0641\u062d\u0627\u062a \u0645\u0648\u0631\u062f\u0646\u06cc\u0627\u0632 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0628\u0634\u0646:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductPagingSource(\n    private val api: ProductApi\n) : PagingSource&lt;Int, Product>() {\n\n    override suspend fun load(\n        params: LoadParams&lt;Int>\n    ): LoadResult&lt;Int, Product> {\n        val page =\n            params.key ?: 1\n\n        return try {\n            val response =\n                api.getProducts(\n                    page = page,\n                    limit = params.loadSize\n                )\n\n            LoadResult.Page(\n                data =\n                    response.items.map {\n                        it.toDomain()\n                    },\n                prevKey =\n                    if (page == 1) {\n                        null\n                    } else {\n                        page - 1\n                    },\n                nextKey =\n                    if (\n                        response.hasNextPage\n                    ) {\n                        page + 1\n                    } else {\n                        null\n                    }\n            )\n        } catch (\n            exception: Exception\n        ) {\n            LoadResult.Error(exception)\n        }\n    }\n\n    override fun getRefreshKey(\n        state:\n            PagingState&lt;Int, Product>\n    ): Int? {\n        val anchorPosition =\n            state.anchorPosition\n                ?: return null\n\n        val anchorPage =\n            state.closestPageToPosition(\n                anchorPosition\n            )\n\n        return anchorPage?.prevKey\n            ?.plus(1)\n            ?: anchorPage?.nextKey\n                ?.minus(1)\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductPagingSource<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> api: <\/span><span style=\"color: #6F42C1\">ProductApi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">PagingSource<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt;() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">load<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        params: <\/span><span style=\"color: #6F42C1\">LoadParams<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">LoadResult<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt; {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> page <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            params.key ?: <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> response <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                api.<\/span><span style=\"color: #6F42C1\">getProducts<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    page <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> page,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    limit <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> params.loadSize<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            LoadResult.<\/span><span style=\"color: #6F42C1\">Page<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    response.items.<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        it.<\/span><span style=\"color: #6F42C1\">toDomain<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                prevKey <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (page <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        page <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                nextKey <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        response.hasNextPage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        page <\/span><span style=\"color: #D73A49\">+<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        } <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            exception: <\/span><span style=\"color: #6F42C1\">Exception<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            LoadResult.<\/span><span style=\"color: #6F42C1\">Error<\/span><span style=\"color: #24292E\">(exception)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getRefreshKey<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        state:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PagingState<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">Int, Product<\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">? {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> anchorPosition <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state.anchorPosition<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> anchorPage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state.<\/span><span style=\"color: #6F42C1\">closestPageToPosition<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                anchorPosition<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> anchorPage?.prevKey<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ?.<\/span><span style=\"color: #6F42C1\">plus<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ?: anchorPage?.nextKey<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?.<\/span><span style=\"color: #6F42C1\">minus<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Repository:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductRepository(\n    private val api: ProductApi\n) {\n\n    fun getProducts():\n        Flow&lt;PagingData&lt;Product>> {\n        return Pager(\n            config =\n                PagingConfig(\n                    pageSize = 20,\n                    prefetchDistance = 5,\n                    enablePlaceholders =\n                        false\n                ),\n            pagingSourceFactory = {\n                ProductPagingSource(api)\n            }\n        ).flow\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> api: <\/span><span style=\"color: #6F42C1\">ProductApi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getProducts<\/span><span style=\"color: #24292E\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">Flow<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">PagingData<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt;&gt; {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Pager<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            config <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">PagingConfig<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    pageSize <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">20<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    prefetchDistance <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">5<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    enablePlaceholders <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            pagingSourceFactory <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">ProductPagingSource<\/span><span style=\"color: #24292E\">(api)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ).flow<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">ViewModel:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductListViewModel(\n    repository: ProductRepository\n) : ViewModel() {\n\n    val products =\n        repository\n            .getProducts()\n            .cachedIn(viewModelScope)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductListViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    repository: <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ViewModel<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        repository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">getProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">cachedIn<\/span><span style=\"color: #24292E\">(viewModelScope)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Compose:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nfun ProductListRoute(\n    viewModel: ProductListViewModel\n) {\n    val products =\n        viewModel.products\n            .collectAsLazyPagingItems()\n\n    LazyColumn {\n        items(\n            count = products.itemCount,\n            key = { index ->\n                products&#91;index&#93;?.id\n                    ?: index\n            }\n        ) { index ->\n            val product =\n                products&#91;index&#93;\n\n            if (product != null) {\n                ProductItem(product)\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductListRoute<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    viewModel: <\/span><span style=\"color: #6F42C1\">ProductListViewModel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModel.products<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">collectAsLazyPagingItems<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">LazyColumn<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">items<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            count <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> products.itemCount,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            key <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> { index <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                products&#91;index&#93;?.id<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ?: index<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) { index <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> product <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                products&#91;index&#93;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (product <\/span><span style=\"color: #D73A49\">!=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">ProductItem<\/span><span style=\"color: #24292E\">(product)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Paging \u0647\u0645 \u0645\u0635\u0631\u0641 \u0634\u0628\u06a9\u0647 \u0631\u0648 \u06a9\u0645 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u0647\u0645 \u0627\u062c\u0627\u0632\u0647 \u0646\u0645\u06cc\u062f\u0647 \u06a9\u0644 \u062f\u06cc\u062a\u0627\u0633\u062a \u06cc\u06a9\u200c\u062c\u0627 \u0648\u0627\u0631\u062f \u062d\u0627\u0641\u0638\u0647 \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">State \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0631\u0648 \u0628\u06cc\u0634 \u0627\u0632 \u062d\u062f \u0628\u0632\u0631\u06af \u0646\u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06af\u0627\u0647\u06cc \u062e\u0648\u062f ViewModel \u062a\u0628\u062f\u06cc\u0644 \u0628\u0647 \u0627\u0646\u0628\u0627\u0631 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class ProductUiState(\n    val allProducts:\n        List&lt;Product>,\n    val allPriceHistory:\n        Map&lt;Long, List&lt;PricePoint>>,\n    val allImages:\n        Map&lt;Long, Bitmap>,\n    val allSearchResults:\n        List&lt;Product>\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductUiState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> allProducts:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        List<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">Product<\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> allPriceHistory:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Map<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">Long, List<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">PricePoint<\/span><span style=\"color: #D73A49\">&gt;&gt;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> allImages:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Map<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">Long, Bitmap<\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> allSearchResults:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        List<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">Product<\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0631 \u0628\u0627\u0631 \u06a9\u0647 State \u062c\u062f\u06cc\u062f \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 Collection\u0647\u0627\u06cc \u0628\u0632\u0631\u06af\u06cc \u06a9\u067e\u06cc \u06cc\u0627 \u0628\u0631\u0627\u06cc \u0645\u062f\u062a \u0637\u0648\u0644\u0627\u0646\u06cc \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0628\u0634\u0646. \u0628\u0647\u062a\u0631\u0647 State \u0641\u0642\u0637 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0644\u0627\u0632\u0645 \u0628\u0631\u0627\u06cc \u0635\u0641\u062d\u0647 \u0641\u0639\u0644\u06cc \u0631\u0648 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class ProductDetailsUiState(\n    val isLoading: Boolean = false,\n    val product:\n        ProductDetails? = null,\n    val recentPrices:\n        List&lt;PricePoint> =\n        emptyList(),\n    val errorMessage:\n        String? = null\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductDetailsUiState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isLoading: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> product:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ProductDetails? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> recentPrices:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        List<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">PricePoint<\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">emptyList<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> errorMessage:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        String? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0647 \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0642\u06cc\u0645\u062a \u0647\u0632\u0627\u0631\u0627\u0646 \u0646\u0642\u0637\u0647 \u062f\u0627\u0631\u0647\u060c \u0641\u0642\u0637 \u0628\u0627\u0632\u0647 \u0642\u0627\u0628\u0644\u200c\u0646\u0645\u0627\u06cc\u0634 \u0631\u0648 \u0645\u06cc\u200c\u06af\u06cc\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface PriceHistoryDao {\n\n    @Query(\n        \"\"\"\n        SELECT *\n        FROM price_history\n        WHERE product_id = :productId\n        ORDER BY created_at DESC\n        LIMIT :limit\n        \"\"\"\n    )\n    suspend fun getRecentPrices(\n        productId: Long,\n        limit: Int\n    ): List&lt;PriceHistoryEntity>\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceHistoryDao<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        SELECT *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        FROM price_history<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        WHERE product_id = :productId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        ORDER BY created_at DESC<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        LIMIT :limit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        &quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getRecentPrices<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        limit: <\/span><span style=\"color: #6F42C1\">Int<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">PriceHistoryEntity<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">remember \u0648 rememberSaveable \u0631\u0648 \u062f\u0631\u0633\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Compose\u060c <code>remember<\/code> \u0645\u0642\u062f\u0627\u0631 \u0631\u0648 \u062a\u0627 \u0648\u0642\u062a\u06cc Composable \u062f\u0631 Composition \u0628\u0627\u0642\u06cc \u0645\u0648\u0646\u062f\u0647 \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val expanded =\n    remember {\n        mutableStateOf(false)\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> expanded <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">remember<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">mutableStateOf<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><code>rememberSaveable<\/code> \u0639\u0644\u0627\u0648\u0647 \u0628\u0631 Recomposition\u060c \u062a\u0644\u0627\u0634 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0645\u0642\u062f\u0627\u0631 \u0631\u0648 \u0647\u0646\u06af\u0627\u0645 \u0628\u0627\u0632\u0633\u0627\u0632\u06cc Activity \u0647\u0645 \u0646\u06af\u0647 \u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var searchQuery by\n    rememberSaveable {\n        mutableStateOf(\"\")\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> searchQuery <\/span><span style=\"color: #D73A49\">by<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">rememberSaveable<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">mutableStateOf<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0646\u0628\u0627\u06cc\u062f Object\u0647\u0627\u06cc \u0628\u0632\u0631\u06af \u0631\u0648 \u062f\u0627\u062e\u0644 <code>rememberSaveable<\/code> \u0642\u0631\u0627\u0631 \u0628\u062f\u06cc\u0645\u060c \u0686\u0648\u0646 \u062f\u0627\u062f\u0647 \u0628\u0627\u06cc\u062f \u0648\u0627\u0631\u062f Bundle \u06cc\u0627 Saved State \u0628\u0634\u0647 \u0648 \u0639\u0644\u0627\u0648\u0647 \u0628\u0631 \u0645\u0635\u0631\u0641 \u062d\u0627\u0641\u0638\u0647 \u0645\u0645\u06a9\u0646\u0647 \u0628\u0627 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0627\u0646\u062f\u0627\u0632\u0647 State \u0631\u0648\u0628\u0647\u200c\u0631\u0648 \u0628\u0634\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0645\u0648\u0646\u0647 \u0628\u062f:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val products =\n    rememberSaveable {\n        mutableStateOf(\n            hugeProductList\n        )\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">rememberSaveable<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">mutableStateOf<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            hugeProductList<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647\u062a\u0631\u0647 \u0641\u0642\u0637 \u0634\u0646\u0627\u0633\u0647 \u06cc\u0627 \u0648\u0631\u0648\u062f\u06cc \u06a9\u0648\u0686\u06a9 \u0631\u0648 \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var selectedProductId by\n    rememberSaveable {\n        mutableLongStateOf(-1L)\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> selectedProductId <\/span><span style=\"color: #D73A49\">by<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">rememberSaveable<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">mutableLongStateOf<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">1L<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u0648\u062f \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u062d\u0635\u0648\u0644 \u0627\u0632 Repository \u06cc\u0627 ViewModel \u062f\u0648\u0628\u0627\u0631\u0647 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u0634\u0647. \u0647\u0645\u0686\u0646\u06cc\u0646 \u0646\u0628\u0627\u06cc\u062f Activity \u06cc\u0627 View \u0631\u0648 \u062f\u0627\u062e\u0644 <code>remember<\/code> \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val activity =\n    remember {\n        context as Activity\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> activity <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">remember<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        context <\/span><span style=\"color: #D73A49\">as<\/span><span style=\"color: #24292E\"> Activity<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0647\u0645\u0648\u0646 Context \u0641\u0639\u0644\u06cc \u0631\u0648 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0627\u0632 <code>LocalContext.current<\/code> \u0645\u06cc\u200c\u06af\u06cc\u0631\u06cc\u0645 \u0648 \u0641\u0642\u0637 \u062f\u0631 \u0644\u062d\u0638\u0647 \u0646\u06cc\u0627\u0632 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Callback\u0647\u0627\u06cc Compose \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u0645\u0642\u062f\u0627\u0631 \u0642\u062f\u06cc\u0645\u06cc \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0631\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u06cc\u06a9 \u0639\u0645\u0644\u06cc\u0627\u062a \u0632\u0645\u0627\u0646\u200c\u062f\u0627\u0631 \u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nfun PriceMessage(\n    onTimeout: () -> Unit\n) {\n    LaunchedEffect(Unit) {\n        delay(3000)\n        onTimeout()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceMessage<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onTimeout: () <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">LaunchedEffect<\/span><span style=\"color: #24292E\">(Unit) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">delay<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">3000<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">onTimeout<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0647 <code>onTimeout<\/code> \u062f\u0631 Recomposition \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647\u060c Coroutine \u0642\u0628\u0644\u06cc \u0645\u0645\u06a9\u0646\u0647 \u0647\u0646\u0648\u0632 Callback \u0642\u062f\u06cc\u0645\u06cc \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u0628\u0631\u0627\u06cc \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0646 \u0622\u062e\u0631\u06cc\u0646 \u0646\u0633\u062e\u0647 Callback \u0627\u0632 <code>rememberUpdatedState<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nfun PriceMessage(\n    onTimeout: () -> Unit\n) {\n    val currentOnTimeout by\n        rememberUpdatedState(\n            newValue = onTimeout\n        )\n\n    LaunchedEffect(Unit) {\n        delay(3000)\n        currentOnTimeout()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceMessage<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onTimeout: () <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> currentOnTimeout <\/span><span style=\"color: #D73A49\">by<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">rememberUpdatedState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            newValue <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> onTimeout<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">LaunchedEffect<\/span><span style=\"color: #24292E\">(Unit) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">delay<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">3000<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">currentOnTimeout<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0645\u0648\u0631\u062f \u0647\u0645\u06cc\u0634\u0647 \u06cc\u06a9 Memory Leak \u0628\u0632\u0631\u06af \u0627\u06cc\u062c\u0627\u062f \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0627\u0645\u0627 \u062c\u0644\u0648\u06cc \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0646\u0627\u062e\u0648\u0627\u0633\u062a\u0647 State \u06cc\u0627 Closure \u0642\u062f\u06cc\u0645\u06cc \u0631\u0648 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647 \u0648 \u0631\u0641\u062a\u0627\u0631 Composable \u0631\u0648 \u0642\u0627\u0628\u0644\u200c\u067e\u06cc\u0634\u200c\u0628\u06cc\u0646\u06cc\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resource\u0647\u0627\u06cc\u06cc \u06a9\u0647 Garbage Collector \u0646\u0645\u06cc\u200c\u0628\u0646\u062f\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Garbage Collector \u062d\u0627\u0641\u0638\u0647 Object\u0647\u0627 \u0631\u0648 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0627\u0645\u0627 Resource\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 \u0641\u0627\u06cc\u0644\u060c Cursor\u060c Stream\u060c Socket \u0648 \u0628\u0639\u0636\u06cc Object\u0647\u0627\u06cc Native \u0628\u0627\u06cc\u062f \u0635\u0631\u06cc\u062d\u0627\u064b \u0628\u0633\u062a\u0647 \u0628\u0634\u0646. \u0628\u0647\u062a\u0631\u0647 \u0627\u0632 <code>use<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645 \u062a\u0627 \u062d\u062a\u06cc \u062f\u0631 \u0635\u0648\u0631\u062a Exception \u0647\u0645 Resource \u0622\u0632\u0627\u062f \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u0648\u0627\u0646\u062f\u0646 \u0641\u0627\u06cc\u0644:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun readTextFile(\n    file: File\n): String {\n    return file\n        .bufferedReader()\n        .use { reader ->\n            reader.readText()\n        }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">readTextFile<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    file: <\/span><span style=\"color: #6F42C1\">File<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">): <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> file<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">bufferedReader<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">use<\/span><span style=\"color: #24292E\"> { reader <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            reader.<\/span><span style=\"color: #6F42C1\">readText<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u0648\u0627\u0646\u062f\u0646 Cursor:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun readProductNames(\n    cursor: Cursor\n): List&lt;String> {\n    return cursor.use {\n        val result =\n            mutableListOf&lt;String>()\n\n        val nameIndex =\n            it.getColumnIndexOrThrow(\n                \"name\"\n            )\n\n        while (it.moveToNext()) {\n            result.add(\n                it.getString(nameIndex)\n            )\n        }\n\n        result\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">readProductNames<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    cursor: <\/span><span style=\"color: #6F42C1\">Cursor<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">): <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">&gt; {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> cursor.<\/span><span style=\"color: #6F42C1\">use<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> result <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">mutableListOf<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">&gt;()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> nameIndex <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            it.<\/span><span style=\"color: #6F42C1\">getColumnIndexOrThrow<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;name&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">while<\/span><span style=\"color: #24292E\"> (it.<\/span><span style=\"color: #6F42C1\">moveToNext<\/span><span style=\"color: #24292E\">()) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            result.<\/span><span style=\"color: #6F42C1\">add<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                it.<\/span><span style=\"color: #6F42C1\">getString<\/span><span style=\"color: #24292E\">(nameIndex)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        result<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0647 Stream \u06cc\u0627 Cursor \u0628\u0633\u062a\u0647 \u0646\u0634\u0646\u060c \u0641\u0642\u0637 RAM \u0645\u0635\u0631\u0641 \u0646\u0645\u06cc\u0634\u0647\u061b \u0645\u0645\u06a9\u0646\u0647 File Descriptor\u0647\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645 \u062a\u0645\u0627\u0645 \u0628\u0634\u0646 \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627 \u062e\u0637\u0627\u0647\u0627\u06cc \u063a\u06cc\u0631\u0645\u0646\u062a\u0638\u0631\u0647 \u0631\u0648\u0628\u0647\u200c\u0631\u0648 \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0646\u06af\u0627\u0645 \u06a9\u0645\u0628\u0648\u062f \u062d\u0627\u0641\u0638\u0647 \u0686\u0647 \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u062d\u0627\u0641\u0638\u0647 \u0633\u06cc\u0633\u062a\u0645 \u06a9\u0645 \u0645\u06cc\u0634\u0647\u060c Android \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0641\u0631\u0627\u06cc\u0646\u062f\u0647\u0627\u06cc Cache\u0634\u062f\u0647 \u0631\u0648 \u0627\u0632 \u0628\u06cc\u0646 \u0628\u0628\u0631\u0647. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0646\u0628\u0627\u06cc\u062f \u0641\u0631\u0636 \u06a9\u0646\u06cc\u0645 Singleton\u0647\u0627\u060c Cache \u062d\u0627\u0641\u0638\u0647 \u06cc\u0627 \u0645\u062a\u063a\u06cc\u0631\u0647\u0627\u06cc \u0633\u0631\u0627\u0633\u0631\u06cc \u0628\u0631\u0627\u06cc \u0647\u0645\u06cc\u0634\u0647 \u0632\u0646\u062f\u0647 \u0645\u06cc\u200c\u0645\u0648\u0646\u0646. State \u0645\u0647\u0645 \u0628\u0627\u06cc\u062f \u062f\u0631 \u0645\u062d\u0644 \u067e\u0627\u06cc\u062f\u0627\u0631\u062a\u0631\u06cc \u0645\u062b\u0644 Room\u060c DataStore \u06cc\u0627 Saved State \u0630\u062e\u06cc\u0631\u0647 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0622\u0632\u0627\u062f \u06a9\u0631\u062f\u0646 Cache\u0647\u0627\u06cc \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u0647 <code>onTrimMemory<\/code> \u0648\u0627\u06a9\u0646\u0634 \u0646\u0634\u0648\u0646 \u0628\u062f\u06cc\u0645. Android \u0627\u06cc\u0646 Callback \u0631\u0648 \u0632\u0645\u0627\u0646\u06cc \u0635\u062f\u0627 \u0645\u06cc\u200c\u0632\u0646\u0647 \u06a9\u0647 \u0641\u0631\u0635\u062a \u0645\u0646\u0627\u0633\u0628\u06cc \u0628\u0631\u0627\u06cc \u06a9\u0627\u0647\u0634 \u0645\u0635\u0631\u0641 \u062d\u0627\u0641\u0638\u0647 \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class GheimatBanApplication :\n    Application(),\n    ComponentCallbacks2 {\n\n    lateinit var productMemoryCache:\n        ProductMemoryCache\n\n    override fun onCreate() {\n        super.onCreate()\n\n        productMemoryCache =\n            ProductMemoryCache()\n    }\n\n    override fun onTrimMemory(\n        level: Int\n    ) {\n        super.onTrimMemory(level)\n\n        when {\n            level >=\n                ComponentCallbacks2\n                    .TRIM_MEMORY_RUNNING_CRITICAL -> {\n                productMemoryCache.clear()\n                imageCache.clearMemory()\n            }\n\n            level >=\n                ComponentCallbacks2\n                    .TRIM_MEMORY_RUNNING_LOW -> {\n                productMemoryCache.trimToHalf()\n            }\n\n            level >=\n                ComponentCallbacks2\n                    .TRIM_MEMORY_UI_HIDDEN -> {\n                temporaryScreenCache.clear()\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">GheimatBanApplication<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">Application<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">ComponentCallbacks2<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">lateinit<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> productMemoryCache:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ProductMemoryCache<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productMemoryCache <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">ProductMemoryCache<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onTrimMemory<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        level: <\/span><span style=\"color: #6F42C1\">Int<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onTrimMemory<\/span><span style=\"color: #24292E\">(level)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            level <\/span><span style=\"color: #D73A49\">&gt;=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ComponentCallbacks2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .TRIM_MEMORY_RUNNING_CRITICAL <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                productMemoryCache.<\/span><span style=\"color: #6F42C1\">clear<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                imageCache.<\/span><span style=\"color: #6F42C1\">clearMemory<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            level <\/span><span style=\"color: #D73A49\">&gt;=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ComponentCallbacks2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .TRIM_MEMORY_RUNNING_LOW <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                productMemoryCache.<\/span><span style=\"color: #6F42C1\">trimToHalf<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            level <\/span><span style=\"color: #D73A49\">&gt;=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ComponentCallbacks2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .TRIM_MEMORY_UI_HIDDEN <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                temporaryScreenCache.<\/span><span style=\"color: #6F42C1\">clear<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Cache \u0631\u0648 \u06a9\u0645\u06cc \u06a9\u0627\u0645\u0644\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductMemoryCache {\n\n    private val maximumSize = 100\n\n    private val cache =\n        LruCache&lt;Long, ProductDetails>(\n            maximumSize\n        )\n\n    fun put(\n        product: ProductDetails\n    ) {\n        cache.put(\n            product.id,\n            product\n        )\n    }\n\n    fun get(\n        productId: Long\n    ): ProductDetails? {\n        return cache.get(productId)\n    }\n\n    fun trimToHalf() {\n        cache.trimToSize(\n            maximumSize \/ 2\n        )\n    }\n\n    fun clear() {\n        cache.evictAll()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductMemoryCache<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> maximumSize <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">100<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> cache <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">LruCache<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">ProductDetails<\/span><span style=\"color: #24292E\">&gt;(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            maximumSize<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">put<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        product: <\/span><span style=\"color: #6F42C1\">ProductDetails<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        cache.<\/span><span style=\"color: #6F42C1\">put<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            product.id,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            product<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">get<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">ProductDetails<\/span><span style=\"color: #24292E\">? {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> cache.<\/span><span style=\"color: #6F42C1\">get<\/span><span style=\"color: #24292E\">(productId)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">trimToHalf<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        cache.<\/span><span style=\"color: #6F42C1\">trimToSize<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            maximumSize <\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">clear<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        cache.<\/span><span style=\"color: #6F42C1\">evictAll<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0628\u0627\u06cc\u062f \u062f\u0631 <code>onTrimMemory<\/code> \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0647\u0645 \u06a9\u0627\u0631\u0628\u0631 \u0631\u0648 \u067e\u0627\u06a9 \u06a9\u0646\u06cc\u0645 \u06cc\u0627 \u0639\u0645\u0644\u06cc\u0627\u062a \u0637\u0648\u0644\u0627\u0646\u06cc \u0627\u0646\u062c\u0627\u0645 \u0628\u062f\u06cc\u0645. \u0627\u06cc\u0646\u062c\u0627 \u0641\u0642\u0637 Resource\u0647\u0627\u06cc\u06cc \u0631\u0648 \u0622\u0632\u0627\u062f \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u06a9\u0647 \u062f\u0648\u0628\u0627\u0631\u0647 \u0642\u0627\u0628\u0644\u200c\u0633\u0627\u062e\u062a\u0646 \u06cc\u0627 \u062f\u0631\u06cc\u0627\u0641\u062a \u0647\u0633\u062a\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">OutOfMemoryError \u0631\u0648 \u0628\u0627 Try\/Catch \u062d\u0644 \u0646\u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0645\u06a9\u0646\u0647 \u0648\u0633\u0648\u0633\u0647 \u0628\u0634\u06cc\u0645 \u0686\u0646\u06cc\u0646 \u06a9\u0627\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u0628\u062f\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>try {\n    val bitmap =\n        loadHugeBitmap()\n} catch (\n    error: OutOfMemoryError\n) {\n    System.gc()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> bitmap <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">loadHugeBitmap<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">} <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    error: <\/span><span style=\"color: #6F42C1\">OutOfMemoryError<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    System.<\/span><span style=\"color: #6F42C1\">gc<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0631\u0627\u0647\u200c\u062d\u0644 \u0642\u0627\u0628\u0644\u200c\u0627\u0639\u062a\u0645\u0627\u062f \u0646\u06cc\u0633\u062a. \u0648\u0642\u062a\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647 <code>OutOfMemoryError<\/code> \u0631\u0633\u06cc\u062f\u0647\u060c \u0648\u0636\u0639\u06cc\u062a \u062d\u0627\u0641\u0638\u0647 \u0645\u0645\u06a9\u0646\u0647 \u0628\u0647\u200c\u0634\u062f\u062a \u0646\u0627\u067e\u0627\u06cc\u062f\u0627\u0631 \u0628\u0627\u0634\u0647 \u0648 \u062d\u062a\u06cc \u0633\u0627\u062e\u062a Object \u0644\u0627\u0632\u0645 \u0628\u0631\u0627\u06cc \u0646\u0645\u0627\u06cc\u0634 \u067e\u06cc\u0627\u0645 \u062e\u0637\u0627 \u0647\u0645 \u0634\u06a9\u0633\u062a \u0628\u062e\u0648\u0631\u0647. \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc <code>System.gc<\/code> \u0647\u0645 \u062a\u0636\u0645\u06cc\u0646 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647 \u062d\u0627\u0641\u0638\u0647 \u06a9\u0627\u0641\u06cc \u0622\u0632\u0627\u062f \u0628\u0634\u0647\u060c \u0686\u0648\u0646 \u0645\u0634\u06a9\u0644 \u0645\u0645\u06a9\u0646\u0647 Object\u0647\u0627\u06cc \u0647\u0645\u0686\u0646\u0627\u0646 \u0642\u0627\u0628\u0644\u200c\u062f\u0633\u062a\u0631\u0633\u06cc \u06cc\u0627 Allocation \u0628\u0633\u06cc\u0627\u0631 \u0628\u0632\u0631\u06af \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u0627\u0647 \u062f\u0631\u0633\u062a \u067e\u06cc\u0634\u06af\u06cc\u0631\u06cc\u0647: \u062a\u0635\u0648\u06cc\u0631 \u0631\u0648 \u062f\u0631 \u0627\u0646\u062f\u0627\u0632\u0647 \u0645\u0646\u0627\u0633\u0628 Decode \u06a9\u0646\u06cc\u0645\u060c \u0644\u06cc\u0633\u062a\u200c\u0647\u0627 \u0631\u0648 \u0635\u0641\u062d\u0647\u200c\u0628\u0646\u062f\u06cc \u06a9\u0646\u06cc\u0645\u060c Cache \u0631\u0648 \u0645\u062d\u062f\u0648\u062f \u06a9\u0646\u06cc\u0645\u060c Reference\u0647\u0627\u06cc \u0627\u0636\u0627\u0641\u06cc \u0631\u0648 \u0622\u0632\u0627\u062f \u06a9\u0646\u06cc\u0645 \u0648 Memory Leak\u0647\u0627 \u0631\u0648 \u0628\u0627 \u0627\u0628\u0632\u0627\u0631 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Memory Profiler \u0631\u0648 \u0686\u0637\u0648\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Android Studio \u0627\u0628\u0632\u0627\u0631 Memory Profiler \u062f\u0627\u0631\u0647 \u06a9\u0647 \u0645\u0635\u0631\u0641 \u062d\u0627\u0641\u0638\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u062f\u0631 \u0637\u0648\u0644 \u0632\u0645\u0627\u0646 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u062f\u0647. \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u0628\u06cc\u0646\u06cc\u0645 \u062d\u0627\u0641\u0638\u0647 Java\/Kotlin\u060c Native\u060c Graphics \u0648 Stack \u0686\u0637\u0648\u0631 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c Garbage Collection \u0686\u0647 \u0632\u0645\u0627\u0646\u06cc \u0631\u062e \u0645\u06cc\u062f\u0647 \u0648 \u0686\u0647 \u062a\u0639\u062f\u0627\u062f Object \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647. \u0647\u0645\u0686\u0646\u06cc\u0646 \u0645\u06cc\u0634\u0647 Heap Dump \u06af\u0631\u0641\u062a \u0648 Object\u0647\u0627\u06cc\u06cc \u0631\u0648 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f \u06a9\u0647 \u0646\u0628\u0627\u06cc\u062f \u0647\u0646\u0648\u0632 \u0632\u0646\u062f\u0647 \u0628\u0627\u0634\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0628\u0631\u0631\u0633\u06cc Leak \u06cc\u06a9 \u0633\u0646\u0627\u0631\u06cc\u0648\u06cc \u0645\u0634\u062e\u0635 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u0635\u0641\u062d\u0647 \u062c\u0632\u0626\u06cc\u0627\u062a \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 \u0628\u0627\u0632 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645.<\/li>\n\n\n\n<li>\u0627\u0632 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0645\u06cc\u0634\u06cc\u0645.<\/li>\n\n\n\n<li>\u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0631\u0648 \u0686\u0646\u062f \u0628\u0627\u0631 \u062a\u06a9\u0631\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645.<\/li>\n\n\n\n<li>Garbage Collection \u0631\u0648 \u0627\u0632 Profiler \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645.<\/li>\n\n\n\n<li>Heap Dump \u0645\u06cc\u200c\u06af\u06cc\u0631\u06cc\u0645.<\/li>\n\n\n\n<li>\u062f\u0646\u0628\u0627\u0644 \u0686\u0646\u062f \u0646\u0645\u0648\u0646\u0647 \u0627\u0632 <code>ProductActivity<\/code> \u06cc\u0627 \u0635\u0641\u062d\u0647 \u0642\u0628\u0644\u06cc \u0645\u06cc\u200c\u06af\u0631\u062f\u06cc\u0645.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0647 \u0628\u0639\u062f \u0627\u0632 \u062e\u0631\u0648\u062c \u0647\u0645\u0686\u0646\u0627\u0646 \u0686\u0646\u062f Activity \u0642\u062f\u06cc\u0645\u06cc \u0632\u0646\u062f\u0647 \u0628\u0627\u0634\u0646\u060c Retaining Path \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u062a\u0627 \u0628\u0641\u0647\u0645\u06cc\u0645 \u0686\u0647 Object\u06cc Reference \u0627\u0648\u0646\u200c\u0647\u0627 \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0647. \u0645\u0645\u06a9\u0646\u0647 Singleton\u060c Listener\u060c Handler\u060c Coroutine \u06cc\u0627 Callback \u06cc\u06a9 SDK \u0639\u0627\u0645\u0644 Leak \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Android Studio \u0647\u0645\u0686\u0646\u06cc\u0646 \u0627\u0645\u06a9\u0627\u0646 \u0628\u0631\u0631\u0633\u06cc Allocation\u0647\u0627 \u0631\u0648 \u0645\u06cc\u062f\u0647\u061b \u06cc\u0639\u0646\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u0641\u0647\u0645\u06cc\u0645 \u06cc\u06a9 \u06a9\u0644\u0627\u0633 \u0627\u0632 \u06a9\u062f\u0648\u0645 \u062e\u0637 \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647 \u0648 \u0686\u0631\u0627 \u062a\u0639\u062f\u0627\u062f \u0632\u06cc\u0627\u062f\u06cc \u0646\u0645\u0648\u0646\u0647 \u0627\u0632 \u0627\u0648\u0646 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">LeakCanary \u0631\u0648 \u0628\u0647 \u0646\u0633\u062e\u0647 Debug \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">LeakCanary \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0627\u06cc\u0647 \u06a9\u0647 \u0628\u0639\u062f \u0627\u0632 \u0646\u0627\u0628\u0648\u062f \u0634\u062f\u0646 Activity\u060c Fragment \u06cc\u0627 View \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0622\u06cc\u0627 Object \u0647\u0645\u0686\u0646\u0627\u0646 \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u0628\u0627\u0642\u06cc \u0645\u0648\u0646\u062f\u0647 \u06cc\u0627 \u0646\u0647. \u0627\u06cc\u0646 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0631\u0648 \u0641\u0642\u0637 \u0628\u0647 \u0646\u0633\u062e\u0647 Debug \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>dependencies {\n    debugImplementation(\n        \"com.squareup.leakcanary:\" +\n            \"leakcanary-android:\" +\n            \"CURRENT_VERSION\"\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">dependencies<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">debugImplementation<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;com.squareup.leakcanary:&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">+<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;leakcanary-android:&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">+<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;CURRENT_VERSION&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 \u0627\u0636\u0627\u0641\u0647 \u0634\u062f\u0646\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0646\u06cc\u0627\u0632 \u0628\u0647 Initialization \u062f\u0633\u062a\u06cc \u0646\u062f\u0627\u0631\u0647. \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0648 \u0635\u0641\u062d\u0647\u200c\u0647\u0627 \u0631\u0648 \u0628\u0627\u0632 \u0648 \u0628\u0633\u062a\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. \u0627\u06af\u0647 Leak \u0634\u0646\u0627\u0633\u0627\u06cc\u06cc \u0628\u0634\u0647\u060c LeakCanary \u0632\u0646\u062c\u06cc\u0631\u0647 Reference\u0647\u0627 \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0645\u0645\u06a9\u0646\u0647 \u0686\u0646\u06cc\u0646 \u0645\u0633\u06cc\u0631\u06cc \u067e\u06cc\u062f\u0627 \u0628\u0634\u0647:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">AnalyticsManager\n\u2193\nactivityContext\n\u2193\nProductActivity\n\u2193\nComposeView\n\u2193\nComposition\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0645\u0633\u06cc\u0631 \u0646\u0634\u0648\u0646 \u0645\u06cc\u062f\u0647 <code>AnalyticsManager<\/code> \u0628\u0627\u0639\u062b \u0634\u062f\u0647 Activity \u0642\u0627\u0628\u0644 \u067e\u0627\u06a9 \u0634\u062f\u0646 \u0646\u0628\u0627\u0634\u0647. \u062e\u0648\u062f \u0639\u062f\u062f \u0645\u0635\u0631\u0641 \u062d\u0627\u0641\u0638\u0647 \u0628\u0647 \u062a\u0646\u0647\u0627\u06cc\u06cc \u0647\u0645\u06cc\u0634\u0647 \u0639\u0644\u062a \u0645\u0634\u06a9\u0644 \u0631\u0648 \u0646\u0634\u0648\u0646 \u0646\u0645\u06cc\u062f\u0647\u061b \u0632\u0646\u062c\u06cc\u0631\u0647 Reference\u0647\u0627\u0633\u062a \u06a9\u0647 \u0628\u0647 \u0645\u0627 \u0645\u06cc\u06af\u0647 \u06a9\u062f\u0648\u0645 Object\u060c Object \u0642\u0628\u0644\u06cc \u0631\u0648 \u0632\u0646\u062f\u0647 \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0633\u062a\u0646\u062f\u0627\u062a Android Studio \u0647\u0645 LeakCanary \u0631\u0648 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc \u0645\u0641\u06cc\u062f \u062a\u0634\u062e\u06cc\u0635 Memory Leak \u0645\u0639\u0631\u0641\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u062f\u0631 Memory \u0686\u0647 \u0648\u0636\u0639\u06cc\u062a\u06cc \u062f\u0627\u0631\u0646\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u062f\u0631\u0633 \u0642\u0628\u0644\u06cc \u062f\u0627\u062f\u0647\u200c\u0647\u0627 \u0631\u0648 \u0628\u0627 Android Keystore \u0631\u0645\u0632 \u06a9\u0631\u062f\u06cc\u0645\u060c \u0627\u0645\u0627 \u0648\u0642\u062a\u06cc Token \u0628\u0631\u0627\u06cc \u0627\u0631\u0633\u0627\u0644 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647\u060c \u0628\u0627\u06cc\u062f \u0628\u0631\u0627\u06cc \u0644\u062d\u0638\u0647\u200c\u0627\u06cc \u0628\u0647 \u0635\u0648\u0631\u062a \u0631\u0645\u0632\u06af\u0634\u0627\u06cc\u06cc\u200c\u0634\u062f\u0647 \u0648\u0627\u0631\u062f RAM \u0628\u0634\u0647. \u0647\u06cc\u0686 \u0631\u0627\u0647\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u0647 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0632 \u06cc\u06a9 \u0645\u0642\u062f\u0627\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0647 \u0648\u0644\u06cc \u0627\u0648\u0646 \u0645\u0642\u062f\u0627\u0631 \u0647\u06cc\u0686\u200c\u0648\u0642\u062a \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u0642\u0627\u0628\u0644\u200c\u062f\u0633\u062a\u0631\u0633\u06cc \u0646\u0628\u0627\u0634\u0647. \u0631\u0648\u06cc \u062f\u0633\u062a\u06af\u0627\u0647 Root\u0634\u062f\u0647 \u06cc\u0627 \u0641\u0631\u0627\u06cc\u0646\u062f Hook\u0634\u062f\u0647\u060c \u0645\u0647\u0627\u062c\u0645 \u0645\u0645\u06a9\u0646\u0647 Token \u0631\u0648 \u062f\u0631 \u0647\u0645\u06cc\u0646 \u0644\u062d\u0638\u0647 \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u067e\u0633 \u0647\u062f\u0641 \u0645\u0627 \u062d\u0630\u0641 \u06a9\u0627\u0645\u0644 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u0627\u0632 RAM \u0646\u06cc\u0633\u062a\u061b \u0647\u062f\u0641 \u06a9\u0627\u0647\u0634 \u0632\u0645\u0627\u0646 \u0648 \u062a\u0639\u062f\u0627\u062f \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u0627\u0648\u0646 \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u0627\u0633\u062a. \u0646\u0628\u0627\u06cc\u062f Token \u0631\u0648 \u062f\u0627\u062e\u0644 State \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc\u060c Log\u060c Singleton \u0639\u0645\u0648\u0645\u06cc\u060c Bundle \u06cc\u0627 \u0686\u0646\u062f \u0645\u062f\u0644 \u0645\u062e\u062a\u0644\u0641 \u06a9\u067e\u06cc \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0645\u0648\u0646\u0647 \u0628\u062f:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class AuthUiState(\n    val email: String = \"\",\n    val accessToken: String = \"\",\n    val refreshToken: String = \"\"\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AuthUiState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> email: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> accessToken: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> refreshToken: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">UI \u0647\u06cc\u0686 \u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 Token \u0646\u062f\u0627\u0631\u0647. State \u0628\u0647\u062a\u0631:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class AuthUiState(\n    val email: String = \"\",\n    val isAuthenticated: Boolean =\n        false,\n    val isLoading: Boolean = false,\n    val errorMessage: String? = null\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AuthUiState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> email: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isAuthenticated: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isLoading: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> errorMessage: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Token \u0641\u0642\u0637 \u062f\u0631 \u0644\u0627\u06cc\u0647 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class AuthHeaderProvider(\n    private val tokenStore:\n        SecureTokenStore\n) {\n\n    suspend fun createHeader():\n        String? {\n        val token =\n            tokenStore\n                .getAccessToken()\n                ?: return null\n\n        return \"Bearer $token\"\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AuthHeaderProvider<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> tokenStore:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        SecureTokenStore<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">createHeader<\/span><span style=\"color: #24292E\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        String? {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> token <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            tokenStore<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">getAccessToken<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Bearer <\/span><span style=\"color: #005CC5\">$token<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 \u0627\u06cc\u0646\u06a9\u0647 String \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u060c JVM \u0632\u0645\u0627\u0646 \u062f\u0642\u06cc\u0642 \u067e\u0627\u06a9 \u0634\u062f\u0646 \u062d\u0627\u0641\u0638\u0647 \u0627\u0648\u0646 \u0631\u0648 \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 \u0645\u0627 \u0646\u0645\u06cc\u200c\u0630\u0627\u0631\u0647. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0646\u0628\u0627\u06cc\u062f \u0627\u0645\u0646\u06cc\u062a \u0631\u0648 \u0628\u0631 \u00ab\u067e\u0627\u06a9 \u06a9\u0631\u062f\u0646 \u06a9\u0627\u0645\u0644 RAM\u00bb \u0628\u0646\u0627 \u06a9\u0646\u06cc\u0645. Access Token \u06a9\u0648\u062a\u0627\u0647\u200c\u0639\u0645\u0631\u060c Refresh Token \u0642\u0627\u0628\u0644\u200c\u0644\u063a\u0648 \u0648 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0633\u0645\u062a \u0633\u0631\u0648\u0631 \u0647\u0645\u0686\u0646\u0627\u0646 \u062f\u0641\u0627\u0639 \u0627\u0635\u0644\u06cc \u0647\u0633\u062a\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc Secret\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u062e\u0648\u062f\u0645\u0648\u0646 \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0648 API \u0627\u062c\u0627\u0632\u0647 \u0645\u06cc\u062f\u0647\u060c <code>CharArray<\/code> \u06cc\u0627 <code>ByteArray<\/code> \u0627\u0632 String \u06a9\u0646\u062a\u0631\u0644\u200c\u067e\u0630\u06cc\u0631\u062a\u0631\u0647\u060c \u0686\u0648\u0646 \u0645\u06cc\u0634\u0647 \u0645\u062d\u062a\u0648\u0627\u06cc \u0622\u0631\u0627\u06cc\u0647 \u0631\u0648 \u0628\u0639\u062f \u0627\u0632 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0628\u0627\u0632\u0646\u0648\u06cc\u0633\u06cc \u06a9\u0631\u062f:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun processSecret(\n    secret: CharArray\n) {\n    try {\n        authenticate(secret)\n    } finally {\n        secret.fill('\\u0000')\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">processSecret<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    secret: <\/span><span style=\"color: #6F42C1\">CharArray<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">authenticate<\/span><span style=\"color: #24292E\">(secret)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    } <\/span><span style=\"color: #D73A49\">finally<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        secret.<\/span><span style=\"color: #6F42C1\">fill<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&#39;<\/span><span style=\"color: #005CC5\">\\u<\/span><span style=\"color: #032F62\">0000&#39;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0647\u0645 \u062a\u0636\u0645\u06cc\u0646 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647 \u0647\u06cc\u0686 \u0646\u0633\u062e\u0647 \u062f\u06cc\u06af\u0631\u06cc \u062a\u0648\u0633\u0637 Keyboard\u060c \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u06cc\u0627 Runtime \u0633\u0627\u062e\u062a\u0647 \u0646\u0634\u062f\u0647 \u0628\u0627\u0634\u0647. \u0641\u0642\u0637 \u0632\u0645\u0627\u0646 \u0645\u0627\u0646\u062f\u06af\u0627\u0631\u06cc \u0646\u0633\u062e\u0647\u200c\u0627\u06cc \u0631\u0648 \u06a9\u0647 \u062e\u0648\u062f\u0645\u0648\u0646 \u06a9\u0646\u062a\u0631\u0644 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u06a9\u0627\u0647\u0634 \u0645\u06cc\u062f\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u06cc\u06a9 Memory Policy \u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 <\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0645\u062f\u06cc\u0631\u06cc\u062a \u062d\u0627\u0641\u0638\u0647 \u067e\u0631\u0627\u06a9\u0646\u062f\u0647 \u0648 \u0633\u0644\u06cc\u0642\u0647\u200c\u0627\u06cc \u0646\u0628\u0627\u0634\u0647\u060c \u0628\u0647\u062a\u0631\u0647 \u06cc\u06a9 \u0633\u06cc\u0627\u0633\u062a \u0633\u0627\u062f\u0647 \u0628\u0631\u0627\u06cc \u067e\u0631\u0648\u0698\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645. \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0639\u0645\u0648\u0645\u06cc \u0642\u06cc\u0645\u062a \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u062f\u0627\u062e\u0644 Room \u0628\u0627\u0642\u06cc \u0628\u0645\u0648\u0646\u0646 \u0648 \u0641\u0642\u0637 \u0635\u0641\u062d\u0647 \u0641\u0639\u0644\u06cc \u0648\u0627\u0631\u062f RAM \u0628\u0634\u0647. \u062a\u0635\u0627\u0648\u06cc\u0631 \u062a\u0648\u0633\u0637 Coil \u0648 \u0628\u0627 \u0627\u0646\u062f\u0627\u0632\u0647 \u0645\u0642\u0635\u062f \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0628\u0634\u0646. \u0644\u06cc\u0633\u062a\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af \u0628\u0627 Paging \u062f\u0631\u06cc\u0627\u0641\u062a \u0628\u0634\u0646. Cache\u0647\u0627\u06cc \u062d\u0627\u0641\u0638\u0647 \u0645\u062d\u062f\u0648\u062f \u0648 \u0642\u0627\u0628\u0644\u200c\u067e\u0627\u06a9 \u0634\u062f\u0646 \u0628\u0627\u0634\u0646. Activity \u0648 View \u062f\u0627\u062e\u0644 Singleton\u060c Repository \u06cc\u0627 ViewModel \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0646\u0634\u0646. Coroutine\u0647\u0627 \u0628\u0647 <code>lifecycleScope<\/code> \u06cc\u0627 <code>viewModelScope<\/code> \u0645\u062a\u0635\u0644 \u0628\u0627\u0634\u0646. Listener\u0647\u0627 \u062d\u062a\u0645\u0627\u064b \u062d\u0630\u0641 \u0628\u0634\u0646 \u06cc\u0627 \u0628\u0627 Flow \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u0628\u0634\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u0645\u062b\u0644 Access Token \u0641\u0642\u0637 \u062f\u0631 \u0644\u0627\u06cc\u0647 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0631\u0645\u0632\u06af\u0634\u0627\u06cc\u06cc \u0628\u0634\u0646 \u0648 \u0648\u0627\u0631\u062f UI State \u0646\u0634\u0646. \u0647\u0645\u0686\u0646\u06cc\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627\u06cc\u062f \u0622\u0645\u0627\u062f\u0647 \u0628\u0627\u0634\u0647 \u06a9\u0647 \u0641\u0631\u0627\u06cc\u0646\u062f\u0634 \u0647\u0631 \u0644\u062d\u0638\u0647 \u062f\u0631 \u067e\u0633\u200c\u0632\u0645\u06cc\u0646\u0647 \u0645\u062a\u0648\u0642\u0641 \u0628\u0634\u0647\u061b \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 Cache \u062d\u0627\u0641\u0638\u0647 \u0646\u0628\u0627\u06cc\u062f \u062a\u0646\u0647\u0627 \u0646\u0633\u062e\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0647\u0645 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Memory \u062f\u0631 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0641\u0642\u0637 \u06cc\u06a9 \u0639\u062f\u062f \u062f\u0627\u062e\u0644 Profiler \u0646\u06cc\u0633\u062a. \u0647\u0631 Object\u06cc \u06a9\u0647 \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645\u060c \u0647\u0631 \u062a\u0635\u0648\u06cc\u0631\u060c \u0647\u0631 List\u060c \u0647\u0631 Coroutine \u0648 \u0647\u0631 Callback \u0628\u062e\u0634\u06cc \u0627\u0632 RAM \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647. Garbage Collector Object\u0647\u0627\u06cc\u06cc \u0631\u0648 \u0622\u0632\u0627\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647 \u06a9\u0647 \u062f\u06cc\u06af\u0647 \u0642\u0627\u0628\u0644\u200c\u062f\u0633\u062a\u0631\u0633\u06cc \u0646\u06cc\u0633\u062a\u0646\u060c \u0627\u0645\u0627 \u0627\u06af\u0647 Reference \u0627\u0648\u0646\u200c\u0647\u0627 \u0631\u0648 \u062f\u0627\u062e\u0644 Singleton\u060c Listener\u060c ViewModel \u06cc\u0627 Coroutine \u0628\u0644\u0646\u062f\u0639\u0645\u0631 \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645\u060c \u062d\u0627\u0641\u0638\u0647 \u0622\u0632\u0627\u062f \u0646\u0645\u06cc\u0634\u0647 \u0648 Memory Leak \u0634\u06a9\u0644 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u062f\u0631\u0633 \u062f\u06cc\u062f\u06cc\u0645 \u06a9\u0647 Activity Context \u0646\u0628\u0627\u06cc\u062f \u062f\u0627\u062e\u0644 Singleton \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0628\u0634\u0647\u060c Collection\u0647\u0627\u06cc Flow \u0628\u0627\u06cc\u062f \u0628\u0627 Lifecycle \u0647\u0645\u0627\u0647\u0646\u06af \u0628\u0634\u0646\u060c Coroutine\u0647\u0627 \u0628\u0627\u06cc\u062f Scope \u0645\u0646\u0627\u0633\u0628\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646 \u0648 ViewModel \u0646\u0628\u0627\u06cc\u062f Activity \u06cc\u0627 View \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0631\u0647. \u062a\u0635\u0627\u0648\u06cc\u0631 \u0628\u0627\u06cc\u062f \u062f\u0631 \u0627\u0628\u0639\u0627\u062f \u0648\u0627\u0642\u0639\u06cc \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc Decode \u0628\u0634\u0646\u060c Cache\u0647\u0627 \u0628\u0627\u06cc\u062f \u0645\u062d\u062f\u0648\u062f \u0628\u0627\u0634\u0646 \u0648 \u0644\u06cc\u0633\u062a\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af \u0628\u0627\u06cc\u062f \u0628\u0627 Pagination \u06cc\u0627 Paging 3 \u062f\u0631\u06cc\u0627\u0641\u062a \u0628\u0634\u0646. \u0647\u0645\u0686\u0646\u06cc\u0646 \u0628\u0627 <code>onTrimMemory<\/code> \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 Cache\u0647\u0627\u06cc \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u0631\u0648 \u0647\u0646\u06af\u0627\u0645 \u0641\u0634\u0627\u0631 \u062d\u0627\u0641\u0638\u0647 \u06a9\u0645 \u06a9\u0646\u06cc\u0645 \u0648 \u0628\u0627 Memory Profiler \u0648 LeakCanary \u0639\u0644\u062a Leak\u0647\u0627 \u0631\u0648 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0635\u0644 \u0645\u0647\u0645 \u0627\u06cc\u0646 \u062f\u0631\u0633 \u0627\u06cc\u0646\u0647: <strong>Garbage Collector \u0641\u0642\u0637 \u0622\u0628\u062c\u06a9\u062a\u200c\u0647\u0627\u06cc \u0628\u062f\u0648\u0646 Reference \u0631\u0648 \u067e\u0627\u06a9 \u0645\u06cc\u200c\u06a9\u0646\u0647\u061b \u0627\u06cc\u0646 \u0645\u0627 \u0647\u0633\u062a\u06cc\u0645 \u06a9\u0647 \u0628\u0627\u06cc\u062f \u062a\u0635\u0645\u06cc\u0645 \u0628\u06af\u06cc\u0631\u06cc\u0645 \u0647\u0631 \u062f\u0627\u062f\u0647 \u0648 \u0647\u0631 Object \u062a\u0627 \u0686\u0647 \u0632\u0645\u0627\u0646\u06cc \u0648\u0627\u0642\u0639\u0627\u064b \u0628\u0627\u06cc\u062f \u0632\u0646\u062f\u0647 \u0628\u0645\u0648\u0646\u0647.<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u062f\u0631\u0633 \u067e\u0646\u062c\u0627\u0647\u200c\u0648\u067e\u0646\u062c\u0645<\/h3>\n\n\n\n<h1 class=\"wp-block-heading\">Image Cache<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Image Cache \u0686\u06cc\u0633\u062a\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u062f\u0627\u062e\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0635\u0641\u062d\u0647\u200c\u0627\u06cc \u062f\u0627\u0631\u06cc\u0645 \u06a9\u0647 \u0635\u062f \u06a9\u0627\u0644\u0627 \u0631\u0627 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u200c\u062f\u0647\u062f \u0648 \u06a9\u0646\u0627\u0631 \u0647\u0631 \u06a9\u0627\u0644\u0627 \u0647\u0645 \u062a\u0635\u0648\u06cc\u0631 \u0622\u0646 \u0642\u0631\u0627\u0631 \u06af\u0631\u0641\u062a\u0647 \u0627\u0633\u062a. \u0627\u06af\u0631 \u0647\u0631 \u0628\u0627\u0631 \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0627\u06cc\u0646 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0628\u0627\u0632 \u06a9\u0646\u062f\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u062c\u0628\u0648\u0631 \u0628\u0627\u0634\u062f \u062a\u0645\u0627\u0645 \u062a\u0635\u0627\u0648\u06cc\u0631 \u0631\u0627 \u062f\u0648\u0628\u0627\u0631\u0647 \u0627\u0632 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u062f\u0627\u0646\u0644\u0648\u062f \u06a9\u0646\u062f\u060c \u0635\u0641\u062d\u0647 \u062f\u06cc\u0631\u062a\u0631 \u0628\u0627\u0632 \u0645\u06cc\u200c\u0634\u0648\u062f\u060c \u0645\u0635\u0631\u0641 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0628\u0627\u0644\u0627 \u0645\u06cc\u200c\u0631\u0648\u062f\u060c \u0627\u0633\u06a9\u0631\u0648\u0644 \u06a9\u0631\u062f\u0646 \u0631\u0648\u0627\u0646 \u0646\u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f \u0648 \u062d\u062a\u06cc \u0641\u0634\u0627\u0631 \u0628\u06cc\u0634\u062a\u0631\u06cc \u0628\u0647 \u0633\u0631\u0648\u0631 \u0648\u0627\u0631\u062f \u0645\u06cc\u200c\u0634\u0648\u062f. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u062f\u0646\u06cc\u0627 \u0627\u0632 \u0645\u0641\u0647\u0648\u0645\u06cc \u0628\u0647 \u0646\u0627\u0645 <strong>Image Cache<\/strong> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f. \u0627\u06cc\u062f\u0647 \u0622\u0646 \u0647\u0645 \u0628\u0633\u06cc\u0627\u0631 \u0633\u0627\u062f\u0647 \u0627\u0633\u062a\u061b \u0627\u06af\u0631 \u0642\u0628\u0644\u0627\u064b \u06cc\u06a9 \u062a\u0635\u0648\u06cc\u0631 \u0631\u0627 \u062f\u0627\u0646\u0644\u0648\u062f \u06a9\u0631\u062f\u0647\u200c\u0627\u06cc\u0645\u060c \u062f\u0641\u0639\u0647 \u0628\u0639\u062f \u0628\u0647 \u062c\u0627\u06cc \u062f\u0627\u0646\u0644\u0648\u062f \u062f\u0648\u0628\u0627\u0631\u0647\u060c \u0647\u0645\u0627\u0646 \u0646\u0633\u062e\u0647 \u0630\u062e\u06cc\u0631\u0647\u200c\u0634\u062f\u0647 \u0631\u0627 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u200c\u062f\u0647\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0639\u0645\u0644\u060c Image Cache \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u062f\u0644\u0627\u06cc\u0644 \u0631\u0648\u0627\u0646 \u0628\u0648\u062f\u0646 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0627\u0633\u062a. \u0634\u0627\u06cc\u062f \u06a9\u0627\u0631\u0628\u0631 \u0627\u0635\u0644\u0627\u064b \u0645\u062a\u0648\u062c\u0647 \u0648\u062c\u0648\u062f \u0622\u0646 \u0646\u0634\u0648\u062f\u060c \u0627\u0645\u0627 \u0627\u06af\u0631 \u0622\u0646 \u0631\u0627 \u062d\u0630\u0641 \u06a9\u0646\u06cc\u0645\u060c \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0627\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u06a9\u0646\u062f\u062a\u0631\u060c \u067e\u0631\u0645\u0635\u0631\u0641\u200c\u062a\u0631 \u0648 \u0622\u0632\u0627\u0631\u062f\u0647\u0646\u062f\u0647\u200c\u062a\u0631 \u062e\u0648\u0627\u0647\u0646\u062f \u0634\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Image Cache \u0686\u06af\u0648\u0646\u0647 \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0631\u0627\u06cc \u0627\u0648\u0644\u06cc\u0646 \u0628\u0627\u0631 \u0635\u0641\u062d\u0647 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0627 \u0628\u0627\u0632 \u0645\u06cc\u200c\u06a9\u0646\u062f. \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u06cc\u0686 \u0646\u0633\u062e\u0647\u200c\u0627\u06cc \u0627\u0632 \u062a\u0635\u0627\u0648\u06cc\u0631 \u0631\u0627 \u0646\u062f\u0627\u0631\u062f\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0622\u0646\u200c\u0647\u0627 \u0631\u0627 \u0627\u0632 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u062f\u0627\u0646\u0644\u0648\u062f \u0645\u06cc\u200c\u06a9\u0646\u062f. \u0627\u0645\u0627 \u0628\u0639\u062f \u0627\u0632 \u062f\u0627\u0646\u0644\u0648\u062f\u060c \u0641\u0642\u0637 \u062a\u0635\u0648\u06cc\u0631 \u0631\u0627 \u0646\u0645\u0627\u06cc\u0634 \u0646\u0645\u06cc\u200c\u062f\u0647\u062f\u061b \u0628\u0644\u06a9\u0647 \u06cc\u06a9 \u0646\u0633\u062e\u0647 \u0627\u0632 \u0622\u0646 \u0631\u0627 \u0647\u0645 \u0630\u062e\u06cc\u0631\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f \u062a\u0627 \u062f\u0641\u0639\u0647 \u0628\u0639\u062f \u062f\u0648\u0628\u0627\u0631\u0647 \u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 \u062f\u0627\u0646\u0644\u0648\u062f \u0646\u0628\u0627\u0634\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0633\u0647 \u0645\u0631\u062d\u0644\u0647 \u0631\u0627 \u0637\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f. \u0627\u0628\u062a\u062f\u0627 \u062d\u0627\u0641\u0638\u0647 RAM \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u0634\u0648\u062f\u060c \u0686\u0648\u0646 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631\u06cc\u0646 \u0645\u062d\u0644 \u062f\u0633\u062a\u0631\u0633\u06cc \u0627\u0633\u062a. \u0627\u06af\u0631 \u062a\u0635\u0648\u06cc\u0631 \u0622\u0646\u062c\u0627 \u067e\u06cc\u062f\u0627 \u0646\u0634\u0648\u062f\u060c \u062d\u0627\u0641\u0638\u0647 \u062f\u0627\u062e\u0644\u06cc \u06af\u0648\u0634\u06cc \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0627\u06af\u0631 \u0628\u0627\u0632 \u0647\u0645 \u062a\u0635\u0648\u06cc\u0631\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0634\u062a\u060c \u0641\u0627\u06cc\u0644 \u0627\u0632 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u062f\u0627\u0646\u0644\u0648\u062f \u0645\u06cc\u200c\u0634\u0648\u062f. \u0628\u0639\u062f \u0627\u0632 \u062f\u0627\u0646\u0644\u0648\u062f \u0646\u06cc\u0632 \u062a\u0635\u0648\u06cc\u0631 \u0647\u0645 \u062f\u0627\u062e\u0644 \u062d\u0627\u0641\u0638\u0647 \u0648 \u0647\u0645 \u062f\u0627\u062e\u0644 Disk Cache \u0630\u062e\u06cc\u0631\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f \u062a\u0627 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0628\u0639\u062f\u06cc \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u0627\u0646\u062c\u0627\u0645 \u0634\u0648\u0646\u062f.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Image Request\n      \u2502\n      \u25bc\nMemory Cache\n      \u2502\n      \u251c\u2500\u2500 \u067e\u06cc\u062f\u0627 \u0634\u062f \u2192 \u0646\u0645\u0627\u06cc\u0634 \u062a\u0635\u0648\u06cc\u0631\n      \u2502\n      \u25bc\nDisk Cache\n      \u2502\n      \u251c\u2500\u2500 \u067e\u06cc\u062f\u0627 \u0634\u062f \u2192 \u0646\u0645\u0627\u06cc\u0634 \u062a\u0635\u0648\u06cc\u0631\n      \u2502\n      \u25bc\nNetwork\n      \u2502\n      \u25bc\n\u062f\u0627\u0646\u0644\u0648\u062f \u062a\u0635\u0648\u06cc\u0631\n      \u2502\n      \u25bc\n\u0630\u062e\u06cc\u0631\u0647 \u062f\u0631 Disk Cache\n      \u2502\n      \u25bc\n\u0630\u062e\u06cc\u0631\u0647 \u062f\u0631 Memory Cache\n      \u2502\n      \u25bc\n\u0646\u0645\u0627\u06cc\u0634 \u062a\u0635\u0648\u06cc\u0631\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u0648\u0644\u06cc\u0646 \u0628\u0627\u0631 \u06a9\u0647 \u0635\u0641\u062d\u0647 \u0628\u0627\u0632 \u0645\u06cc\u200c\u0634\u0648\u062f \u06a9\u0645\u06cc \u0632\u0645\u0627\u0646 \u0645\u06cc\u200c\u0628\u0631\u062f\u060c \u0627\u0645\u0627 \u062f\u0641\u0639\u0627\u062a \u0628\u0639\u062f \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0645\u0647 \u0686\u06cc\u0632 \u0628\u0644\u0627\u0641\u0627\u0635\u0644\u0647 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Memory Cache \u0648 Disk Cache \u0686\u0647 \u062a\u0641\u0627\u0648\u062a\u06cc \u062f\u0627\u0631\u0646\u062f\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Memory Cache<\/strong> \u062f\u0627\u062e\u0644 RAM \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u062f \u0648 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631\u06cc\u0646 \u0646\u0648\u0639 Cache \u0627\u0633\u062a. \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0628\u06cc\u0646 \u0686\u0646\u062f \u0635\u0641\u062d\u0647 \u062c\u0627\u0628\u0647\u200c\u062c\u0627 \u0634\u0648\u062f \u0648 \u062f\u0648\u0628\u0627\u0631\u0647 \u0628\u0647 \u0647\u0645\u0627\u0646 \u062a\u0635\u0648\u06cc\u0631 \u0646\u06cc\u0627\u0632 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u062a\u0635\u0648\u06cc\u0631 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0627\u0632 RAM \u062e\u0648\u0627\u0646\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u062d\u062a\u06cc \u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 \u062f\u0633\u062a\u0631\u0633\u06cc \u0628\u0647 \u062d\u0627\u0641\u0638\u0647 \u06af\u0648\u0634\u06cc \u0647\u0645 \u0646\u06cc\u0633\u062a. \u0627\u0644\u0628\u062a\u0647 \u0627\u06cc\u0646 Cache \u062f\u0627\u0626\u0645\u06cc \u0646\u06cc\u0633\u062a \u0648 \u0647\u0631 \u0632\u0645\u0627\u0646 \u0633\u06cc\u0633\u062a\u0645 \u0628\u0647 \u062d\u0627\u0641\u0638\u0647 \u0628\u06cc\u0634\u062a\u0631\u06cc \u0646\u06cc\u0627\u0632 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f \u06cc\u0627 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0633\u062a\u0647 \u0634\u0648\u062f\u060c \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u067e\u0627\u06a9 \u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0645\u0642\u0627\u0628\u0644\u060c <strong>Disk Cache<\/strong> \u062f\u0627\u062e\u0644 \u062d\u0627\u0641\u0638\u0647 \u062f\u0627\u062e\u0644\u06cc \u06af\u0648\u0634\u06cc \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u062f. \u0633\u0631\u0639\u062a \u0622\u0646 \u0627\u0632 RAM \u06a9\u0645\u062a\u0631 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u0647\u0645\u0686\u0646\u0627\u0646 \u0686\u0646\u062f\u06cc\u0646 \u0628\u0631\u0627\u0628\u0631 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u0627\u0632 \u062f\u0627\u0646\u0644\u0648\u062f \u062f\u0648\u0628\u0627\u0631\u0647 \u062a\u0635\u0648\u06cc\u0631 \u0627\u0632 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0627\u0633\u062a. \u0645\u0632\u06cc\u062a \u0645\u0647\u0645 Disk Cache \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u062d\u062a\u06cc \u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0628\u0628\u0646\u062f\u06cc\u0645 \u0648 \u062f\u0648\u0628\u0627\u0631\u0647 \u0627\u062c\u0631\u0627 \u06a9\u0646\u06cc\u0645\u060c \u062a\u0635\u0627\u0648\u06cc\u0631 \u062f\u0627\u0646\u0644\u0648\u062f\u0634\u062f\u0647 \u0647\u0645\u0686\u0646\u0627\u0646 \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u062e\u0648\u0627\u0647\u0646\u062f \u0628\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0627\u06cc\u0646 \u062f\u0648 Cache \u0645\u06a9\u0645\u0644 \u06cc\u06a9\u062f\u06cc\u06af\u0631 \u0647\u0633\u062a\u0646\u062f\u061b Memory Cache \u0628\u0631\u0627\u06cc \u0633\u0631\u0639\u062a \u0648 Disk Cache \u0628\u0631\u0627\u06cc \u0645\u0627\u0646\u062f\u06af\u0627\u0631\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0631\u0627 \u062e\u0648\u062f\u0645\u0627\u0646 Image Cache \u0646\u0645\u06cc\u200c\u0646\u0648\u06cc\u0633\u06cc\u0645\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0632 \u0646\u0638\u0631 \u062a\u0626\u0648\u0631\u06cc \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u0645 \u062a\u0635\u0627\u0648\u06cc\u0631 \u0631\u0627 \u062e\u0648\u062f\u0645\u0627\u0646 \u062f\u0627\u0646\u0644\u0648\u062f \u06a9\u0646\u06cc\u0645\u060c \u062f\u0627\u062e\u0644 \u0641\u0627\u06cc\u0644 \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0646\u06cc\u0645 \u0648 \u0647\u0631 \u0628\u0627\u0631 \u0627\u0632 \u0647\u0645\u0627\u0646 \u0641\u0627\u06cc\u0644 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645. \u0627\u0645\u0627 \u0648\u0642\u062a\u06cc \u067e\u0631\u0648\u0698\u0647 \u06a9\u0645\u06cc \u0628\u0632\u0631\u06af\u200c\u062a\u0631 \u0634\u0648\u062f\u060c \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u200c\u0634\u0648\u06cc\u0645 \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0628\u0633\u06cc\u0627\u0631 \u067e\u06cc\u0686\u06cc\u062f\u0647\u200c\u062a\u0631 \u0627\u0632 \u0686\u06cc\u0632\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0628\u0647 \u0646\u0638\u0631 \u0645\u06cc\u200c\u0631\u0633\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0628\u0627\u06cc\u062f \u062a\u0635\u0645\u06cc\u0645 \u0628\u06af\u06cc\u0631\u06cc\u0645 \u0627\u06af\u0631 \u062d\u0627\u0641\u0638\u0647 RAM \u067e\u0631 \u0634\u062f\u060c \u06a9\u062f\u0627\u0645 \u062a\u0635\u0627\u0648\u06cc\u0631 \u062d\u0630\u0641 \u0634\u0648\u0646\u062f. \u0628\u0627\u06cc\u062f \u062a\u0635\u0627\u0648\u06cc\u0631 \u062e\u0631\u0627\u0628 \u06cc\u0627 \u0646\u0627\u0642\u0635 \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc\u0645\u060c \u0627\u0646\u062f\u0627\u0632\u0647 \u0645\u0646\u0627\u0633\u0628 \u0628\u0631\u0627\u06cc \u0647\u0631 \u062a\u0635\u0648\u06cc\u0631 \u0631\u0627 \u0627\u0646\u062a\u062e\u0627\u0628 \u06a9\u0646\u06cc\u0645\u060c \u062f\u0627\u0646\u0644\u0648\u062f\u0647\u0627\u06cc \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0631\u0627 \u06a9\u0646\u062a\u0631\u0644 \u06a9\u0646\u06cc\u0645\u060c \u0627\u0632 \u062f\u0627\u0646\u0644\u0648\u062f \u062a\u06a9\u0631\u0627\u0631\u06cc \u06cc\u06a9 \u062a\u0635\u0648\u06cc\u0631 \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u06a9\u0646\u06cc\u0645 \u0648 \u062d\u0648\u0627\u0633\u0645\u0627\u0646 \u0628\u0647 \u0645\u0635\u0631\u0641 \u062d\u0627\u0641\u0638\u0647 \u0647\u0645 \u0628\u0627\u0634\u062f \u062a\u0627 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627 <strong>OutOfMemoryError<\/strong> \u0645\u0648\u0627\u062c\u0647 \u0646\u0634\u0648\u062f. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u06cc\u0686 \u067e\u0631\u0648\u0698\u0647 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0627\u06cc\u0646 \u0633\u06cc\u0633\u062a\u0645 \u0631\u0627 \u0627\u0632 \u0635\u0641\u0631 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0646\u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u0627\u0632 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc \u062a\u062e\u0635\u0635\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0631\u0627 Coil \u0628\u0647\u062a\u0631\u06cc\u0646 \u0627\u0646\u062a\u062e\u0627\u0628 \u0628\u0631\u0627\u06cc \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc Compose \u0627\u0633\u062a\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u067e\u0631\u0648\u0698\u0647 \u0628\u0627 <strong>Jetpack Compose<\/strong> \u0646\u0648\u0634\u062a\u0647 \u0634\u062f\u0647 \u0628\u0627\u0634\u062f\u060c \u06cc\u06a9\u06cc \u0627\u0632 \u0628\u0647\u062a\u0631\u06cc\u0646 \u0627\u0646\u062a\u062e\u0627\u0628\u200c\u0647\u0627 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 <strong>Coil<\/strong> \u0627\u0633\u062a. Coil \u06a9\u0627\u0645\u0644\u0627\u064b \u0628\u0631\u0627\u06cc Kotlin \u0648 Compose \u0637\u0631\u0627\u062d\u06cc \u0634\u062f\u0647\u060c \u0633\u0628\u06a9 \u0627\u0633\u062a\u060c \u0627\u0632 Coroutine \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u06a9\u0627\u0631\u0647\u0627\u06cc \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 \u062f\u0627\u0646\u0644\u0648\u062f \u0648 \u0645\u062f\u06cc\u0631\u06cc\u062a \u062a\u0635\u0627\u0648\u06cc\u0631 \u0631\u0627 \u0628\u0647 \u0635\u0648\u0631\u062a \u062e\u0648\u062f\u06a9\u0627\u0631 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u200c\u062f\u0647\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0628\u062a\u062f\u0627 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>implementation(\"io.coil-kt:coil-compose:2.7.0\")\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">implementation<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;io.coil-kt:coil-compose:2.7.0&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0646\u0645\u0627\u06cc\u0634 \u062a\u0635\u0648\u06cc\u0631 \u0641\u0642\u0637 \u0628\u0647 \u0686\u0646\u062f \u062e\u0637 \u06a9\u062f \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u062f.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>AsyncImage(\n    model = product.imageUrl,\n    contentDescription = product.name\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">AsyncImage<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    model <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> product.imageUrl,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    contentDescription <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> product.name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0634\u0627\u06cc\u062f \u0627\u06cc\u0646 \u06a9\u062f \u062e\u06cc\u0644\u06cc \u0633\u0627\u062f\u0647 \u0628\u0647 \u0646\u0638\u0631 \u0628\u0631\u0633\u062f\u060c \u0627\u0645\u0627 \u067e\u0634\u062a \u0647\u0645\u06cc\u0646 \u0686\u0646\u062f \u062e\u0637\u060c Coil \u06a9\u0627\u0631\u0647\u0627\u06cc \u0632\u06cc\u0627\u062f\u06cc \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u200c\u062f\u0647\u062f. \u0627\u06af\u0631 \u062a\u0635\u0648\u06cc\u0631 \u0642\u0628\u0644\u0627\u064b \u062f\u0627\u062e\u0644 Memory Cache \u0628\u0627\u0634\u062f\u060c \u0647\u0645\u0627\u0646 \u0631\u0627 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u200c\u062f\u0647\u062f. \u0627\u06af\u0631 \u062f\u0627\u062e\u0644 Disk Cache \u0628\u0627\u0634\u062f\u060c \u0622\u0646 \u0631\u0627 \u0627\u0632 \u062d\u0627\u0641\u0638\u0647 \u0645\u06cc\u200c\u062e\u0648\u0627\u0646\u062f. \u0627\u06af\u0631 \u0647\u06cc\u0686 \u0646\u0633\u062e\u0647\u200c\u0627\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f\u060c \u062a\u0635\u0648\u06cc\u0631 \u0631\u0627 \u062f\u0627\u0646\u0644\u0648\u062f \u0645\u06cc\u200c\u06a9\u0646\u062f\u060c Decode \u0645\u06cc\u200c\u06a9\u0646\u062f\u060c \u0627\u0646\u062f\u0627\u0632\u0647 \u0622\u0646 \u0631\u0627 \u0645\u062a\u0646\u0627\u0633\u0628 \u0628\u0627 View \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u062f\u0647\u062f \u0648 \u062f\u0631 \u0646\u0647\u0627\u06cc\u062a \u062f\u0627\u062e\u0644 \u0647\u0631 \u062f\u0648 Cache \u0630\u062e\u06cc\u0631\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0646\u0645\u0627\u06cc\u0634 Placeholder \u0647\u0646\u06af\u0627\u0645 \u062f\u0627\u0646\u0644\u0648\u062f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u062a\u0627 \u0632\u0645\u0627\u0646 \u062f\u0627\u0646\u0644\u0648\u062f \u062a\u0635\u0648\u06cc\u0631\u060c \u06cc\u06a9 \u0641\u0636\u0627\u06cc \u062e\u0627\u0644\u06cc \u0646\u0645\u0627\u06cc\u0634 \u062f\u0647\u06cc\u0645. \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0628\u0627\u0639\u062b \u0645\u06cc\u200c\u0634\u0648\u062f \u0635\u0641\u062d\u0647 \u0645\u062f\u0627\u0645 \u0686\u0634\u0645\u06a9 \u0628\u0632\u0646\u062f \u0648 \u062d\u0633 \u06a9\u0646\u062f\u06cc \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0645\u0646\u062a\u0642\u0644 \u0634\u0648\u062f. Coil \u0627\u062c\u0627\u0632\u0647 \u0645\u06cc\u200c\u062f\u0647\u062f \u0647\u0646\u06af\u0627\u0645 \u062f\u0627\u0646\u0644\u0648\u062f \u06cc\u06a9 Placeholder \u0646\u0645\u0627\u06cc\u0634 \u062f\u0647\u06cc\u0645 \u0648 \u0627\u06af\u0631 \u062f\u0627\u0646\u0644\u0648\u062f \u0628\u0627 \u062e\u0637\u0627 \u0645\u0648\u0627\u062c\u0647 \u0634\u062f\u060c \u062a\u0635\u0648\u06cc\u0631 \u062f\u06cc\u06af\u0631\u06cc \u0631\u0627 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>AsyncImage(\n    model = ImageRequest.Builder(LocalContext.current)\n        .data(product.imageUrl)\n        .crossfade(true)\n        .build(),\n    placeholder = painterResource(R.drawable.loading),\n    error = painterResource(R.drawable.no_image),\n    contentDescription = product.name\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">AsyncImage<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    model <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> ImageRequest.<\/span><span style=\"color: #6F42C1\">Builder<\/span><span style=\"color: #24292E\">(LocalContext.current)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">data<\/span><span style=\"color: #24292E\">(product.imageUrl)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">crossfade<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    placeholder <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">painterResource<\/span><span style=\"color: #24292E\">(R.drawable.loading),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    error <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">painterResource<\/span><span style=\"color: #24292E\">(R.drawable.no_image),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    contentDescription <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> product.name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0627\u06cc\u0646 \u062a\u0631\u062a\u06cc\u0628 \u06a9\u0627\u0631\u0628\u0631 \u0647\u0645\u06cc\u0634\u0647 \u0686\u06cc\u0632\u06cc \u0631\u0648\u06cc \u0635\u0641\u062d\u0647 \u0645\u06cc\u200c\u0628\u06cc\u0646\u062f \u0648 \u062a\u062c\u0631\u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0631\u0648\u0627\u0646\u200c\u062a\u0631 \u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u06af\u0631 \u062a\u0635\u0648\u06cc\u0631 \u0631\u0648\u06cc \u0633\u0631\u0648\u0631 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f \u0686\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u06a9\u0627\u0631\u0628\u0631 \u0639\u06a9\u0633 \u067e\u0631\u0648\u0641\u0627\u06cc\u0644\u0634 \u0631\u0627 \u0639\u0648\u0636 \u06a9\u0631\u062f\u0647 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 URL \u062a\u0635\u0648\u06cc\u0631 \u0647\u0645\u0627\u0646 \u0642\u0628\u0644\u06cc \u0627\u0633\u062a. \u062f\u0631 \u0627\u06cc\u0646 \u062d\u0627\u0644\u062a \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645\u0686\u0646\u0627\u0646 \u0646\u0633\u062e\u0647 Cache\u0634\u062f\u0647 \u0631\u0627 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0647\u062f. \u0631\u0627\u06cc\u062c\u200c\u062a\u0631\u06cc\u0646 \u0631\u0627\u0647\u200c\u062d\u0644 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0646\u0633\u062e\u0647 \u0641\u0627\u06cc\u0644 \u0631\u0627 \u062f\u0627\u062e\u0644 URL \u0642\u0631\u0627\u0631 \u062f\u0647\u06cc\u0645.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;example.com\/avatar.jpg?v=2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;example.com\/avatar.jpg?updated=1723456\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0632 \u062f\u06cc\u062f Coil \u0627\u06cc\u0646 \u06cc\u06a9 \u0622\u062f\u0631\u0633 \u062c\u062f\u06cc\u062f \u0627\u0633\u062a\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u062a\u0635\u0648\u06cc\u0631 \u062f\u0648\u0628\u0627\u0631\u0647 \u062f\u0627\u0646\u0644\u0648\u062f \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 Cache \u0647\u0645 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u062e\u0648\u0627\u0647\u062f \u0634\u062f. \u0627\u06cc\u0646 \u0631\u0648\u0634 \u0628\u0633\u06cc\u0627\u0631 \u0633\u0627\u062f\u0647\u200c\u062a\u0631 \u0648 \u0645\u0637\u0645\u0626\u0646\u200c\u062a\u0631 \u0627\u0632 \u067e\u0627\u06a9 \u06a9\u0631\u062f\u0646 \u062f\u0633\u062a\u06cc Cache \u0627\u0633\u062a.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0647 \u062a\u0635\u0627\u0648\u06cc\u0631\u06cc \u0631\u0627 \u0628\u0647\u062a\u0631 \u0627\u0633\u062a Cache \u0646\u06a9\u0646\u06cc\u0645\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u062a\u0635\u0627\u0648\u06cc\u0631 \u0646\u0628\u0627\u06cc\u062f \u0648\u0627\u0631\u062f Cache \u0634\u0648\u0646\u062f. \u0628\u0639\u0636\u06cc \u062a\u0635\u0627\u0648\u06cc\u0631 \u0641\u0642\u0637 \u06cc\u06a9 \u0628\u0627\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u0646\u062f \u06cc\u0627 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633\u06cc \u062f\u0627\u0631\u0646\u062f. \u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644 Captcha\u060c QR Code\u0647\u0627\u06cc \u0645\u0648\u0642\u062a\u060c \u062a\u0635\u0627\u0648\u06cc\u0631 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u06cc\u0627 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0641\u0642\u0637 \u0686\u0646\u062f \u062f\u0642\u06cc\u0642\u0647 \u0627\u0639\u062a\u0628\u0627\u0631 \u062f\u0627\u0631\u0646\u062f\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u06af\u0632\u06cc\u0646\u0647 \u0645\u0646\u0627\u0633\u0628\u06cc \u0628\u0631\u0627\u06cc Cache \u0634\u062f\u0646 \u0646\u06cc\u0633\u062a\u0646\u062f. \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0648\u0627\u0631\u062f \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0627\u062c\u0627\u0632\u0647 \u062f\u0647\u06cc\u0645 \u0647\u0631 \u0628\u0627\u0631 \u062a\u0635\u0648\u06cc\u0631 \u062c\u062f\u06cc\u062f \u0627\u0632 \u0633\u0631\u0648\u0631 \u062f\u0631\u06cc\u0627\u0641\u062a \u0634\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Image Cache \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u0628\u062e\u0634\u200c\u0647\u0627\u06cc \u0647\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u06cc \u0627\u0633\u062a\u060c \u0686\u0648\u0646 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0631\u0648\u06cc \u0633\u0631\u0639\u062a\u060c \u0645\u0635\u0631\u0641 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a\u060c \u0645\u0635\u0631\u0641 \u0628\u0627\u062a\u0631\u06cc \u0648 \u062a\u062c\u0631\u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u06cc \u062a\u0623\u062b\u06cc\u0631 \u0645\u06cc\u200c\u06af\u0630\u0627\u0631\u062f. \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0627\u0628\u062a\u062f\u0627 Memory Cache\u060c \u0633\u067e\u0633 Disk Cache \u0648 \u062f\u0631 \u0646\u0647\u0627\u06cc\u062a Network \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f \u062a\u0627 \u0627\u0632 \u062f\u0627\u0646\u0644\u0648\u062f\u0647\u0627\u06cc \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0634\u0648\u062f. \u062f\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0645\u0628\u062a\u0646\u06cc \u0628\u0631 Compose \u0646\u06cc\u0632 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 <strong>Coil<\/strong> \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u0627\u06cc\u0646 \u067e\u06cc\u0686\u06cc\u062f\u06af\u06cc\u200c\u0647\u0627 \u0631\u0627 \u0628\u0647 \u0635\u0648\u0631\u062a \u062e\u0648\u062f\u06a9\u0627\u0631 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0645\u06cc\u200c\u06a9\u0646\u062f\u061b \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0628\u0647 \u062c\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0632\u0645\u0627\u0646 \u0632\u06cc\u0627\u062f\u06cc \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u06cc\u06a9 \u0633\u06cc\u0633\u062a\u0645 Cache \u0635\u0631\u0641 \u06a9\u0646\u06cc\u0645\u060c \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0627\u0632 \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc \u0627\u0633\u062a\u0627\u0646\u062f\u0627\u0631\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645 \u0648 \u062a\u0645\u0631\u06a9\u0632\u0645\u0627\u0646 \u0631\u0627 \u0631\u0648\u06cc \u062a\u0648\u0633\u0639\u0647 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc \u0627\u0635\u0644\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u06af\u0630\u0627\u0631\u06cc\u0645.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u062f\u0631\u0633 \u067e\u0646\u062c\u0627\u0647\u200c\u0648\u0634\u0634\u0645<\/h3>\n\n\n\n<h1 class=\"wp-block-heading\">Lazy Loading<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Lazy Loading \u0686\u06cc\u0633\u062a\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u062f\u0627\u062e\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0635\u0641\u062d\u0647\u200c\u0627\u06cc \u062f\u0627\u0631\u06cc\u0645 \u06a9\u0647 \u0647\u0632\u0627\u0631 \u06a9\u0627\u0644\u0627 \u0631\u0627 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u200c\u062f\u0647\u062f. \u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u062e\u0648\u0627\u0647\u062f \u0627\u0632 \u0647\u0645\u0627\u0646 \u0644\u062d\u0638\u0647 \u0648\u0631\u0648\u062f \u06a9\u0627\u0631\u0628\u0631\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0647\u0631 \u0647\u0632\u0627\u0631 \u06a9\u0627\u0644\u0627 \u0631\u0627 \u0627\u0632 \u0633\u0631\u0648\u0631 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u062f\u060c \u0686\u0646\u062f \u0627\u062a\u0641\u0627\u0642 \u0628\u062f \u0645\u06cc\u200c\u0627\u0641\u062a\u062f\u061b \u0632\u0645\u0627\u0646 \u0632\u06cc\u0627\u062f\u06cc \u0635\u0631\u0641 \u062f\u0627\u0646\u0644\u0648\u062f \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u06cc\u200c\u0634\u0648\u062f\u060c \u0645\u0635\u0631\u0641 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0628\u0627\u0644\u0627 \u0645\u06cc\u200c\u0631\u0648\u062f\u060c \u062d\u0627\u0641\u0638\u0647 \u0628\u06cc\u0634\u062a\u0631\u06cc \u0627\u0634\u063a\u0627\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0645\u0647\u0645\u200c\u062a\u0631 \u0627\u0632 \u0647\u0645\u0647\u060c \u06a9\u0627\u0631\u0628\u0631 \u0628\u0627\u06cc\u062f \u0645\u062f\u062a \u0632\u06cc\u0627\u062f\u06cc \u0645\u0646\u062a\u0638\u0631 \u0628\u0645\u0627\u0646\u062f \u062a\u0627 \u0627\u0648\u0644\u06cc\u0646 \u0635\u0641\u062d\u0647 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646\u062c\u0627\u0633\u062a \u06a9\u0647 \u0645\u0641\u0647\u0648\u0645 <strong>Lazy Loading<\/strong> \u0648\u0627\u0631\u062f \u0645\u06cc\u200c\u0634\u0648\u062f. \u0627\u06cc\u062f\u0647 \u0622\u0646 \u0628\u0633\u06cc\u0627\u0631 \u0633\u0627\u062f\u0647 \u0627\u0633\u062a\u061b \u0641\u0642\u0637 \u0686\u06cc\u0632\u06cc \u0631\u0627 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u06a9\u0646 \u06a9\u0647 \u0647\u0645\u06cc\u0646 \u062d\u0627\u0644\u0627 \u0628\u0647 \u0622\u0646 \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u06cc \u0648 \u0628\u0642\u06cc\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0627 \u0632\u0645\u0627\u0646\u06cc \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646 \u06a9\u0647 \u0648\u0627\u0642\u0639\u0627\u064b \u0644\u0627\u0632\u0645 \u0634\u0648\u0646\u062f. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af \u062f\u0646\u06cc\u0627\u060c \u0627\u0632 \u0627\u06cc\u0646\u0633\u062a\u0627\u06af\u0631\u0627\u0645 \u0648 \u06cc\u0648\u062a\u06cc\u0648\u0628 \u06af\u0631\u0641\u062a\u0647 \u062a\u0627 \u062f\u06cc\u062c\u06cc\u200c\u06a9\u0627\u0644\u0627 \u0648 \u0622\u0645\u0627\u0632\u0648\u0646\u060c \u0627\u0632 Lazy Loading \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0641\u0627\u0648\u062a Lazy Loading \u0648 Eager Loading<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0633\u0631\u0648\u0631 \u0647\u0632\u0627\u0631 \u0645\u062d\u0635\u0648\u0644 \u062f\u0627\u0631\u062f. \u062f\u0631 \u0631\u0648\u0634 <strong>Eager Loading<\/strong> \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0632 \u0647\u0645\u0627\u0646 \u0627\u0628\u062a\u062f\u0627 \u0647\u0631 \u0647\u0632\u0627\u0631 \u0645\u062d\u0635\u0648\u0644 \u0631\u0627 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u062f\u061b \u062d\u062a\u06cc \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0641\u0642\u0637 \u062f\u0647 \u0645\u062d\u0635\u0648\u0644 \u0627\u0648\u0644 \u0631\u0627 \u0628\u0628\u06cc\u0646\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u062f\u0631 <strong>Lazy Loading<\/strong> \u0627\u0628\u062a\u062f\u0627 \u0641\u0642\u0637 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0648\u0631\u062f\u0646\u06cc\u0627\u0632\u060c \u0645\u062b\u0644\u0627\u064b \u0628\u06cc\u0633\u062a \u0645\u062d\u0635\u0648\u0644 \u0627\u0648\u0644\u060c \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u0634\u0648\u062f. \u0648\u0642\u062a\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0628\u0647 \u0627\u0646\u062a\u0647\u0627\u06cc \u0644\u06cc\u0633\u062a \u0646\u0632\u062f\u06cc\u06a9 \u0634\u062f\u060c \u0628\u06cc\u0633\u062a \u0645\u062d\u0635\u0648\u0644 \u0628\u0639\u062f\u06cc \u062f\u0627\u0646\u0644\u0648\u062f \u0645\u06cc\u200c\u0634\u0648\u0646\u062f \u0648 \u0627\u06cc\u0646 \u0631\u0648\u0646\u062f \u062a\u0627 \u0632\u0645\u0627\u0646\u06cc \u0627\u062f\u0627\u0645\u0647 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u062f \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0648\u0627\u0642\u0639\u0627\u064b \u0628\u0647 \u0622\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0646\u06cc\u0627\u0632 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f. \u062f\u0631 \u0646\u062a\u06cc\u062c\u0647\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u0634\u0648\u062f\u060c \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u06a9\u0645\u062a\u0631\u06cc \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u062d\u0627\u0641\u0638\u0647 \u0646\u06cc\u0632 \u0628\u06cc\u200c\u062f\u0644\u06cc\u0644 \u0627\u0634\u063a\u0627\u0644 \u0646\u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Lazy Loading \u062f\u0631 Compose<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Jetpack Compose \u06cc\u06a9\u06cc \u0627\u0632 \u0633\u0627\u062f\u0647\u200c\u062a\u0631\u06cc\u0646 \u0627\u0628\u0632\u0627\u0631\u0647\u0627 \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc Lazy Loading\u060c \u06a9\u0627\u0645\u067e\u0648\u0646\u0646\u062a <strong>LazyColumn<\/strong> \u0627\u0633\u062a.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>LazyColumn {\n    items(products) { product ->\n\n        ProductItem(product)\n\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">LazyColumn<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">items<\/span><span style=\"color: #24292E\">(products) { product <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">ProductItem<\/span><span style=\"color: #24292E\">(product)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0634\u0627\u06cc\u062f \u0627\u0633\u0645 <strong>LazyColumn<\/strong> \u0627\u06cc\u0646 \u062a\u0635\u0648\u0631 \u0631\u0627 \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u062f \u06a9\u0647 \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0627\u0633\u06a9\u0631\u0648\u0644 \u06a9\u0631\u062f\u0646 \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u0648\u06cc\u0698\u06af\u06cc \u0622\u0646 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0622\u06cc\u062a\u0645\u200c\u0647\u0627\u06cc\u06cc \u0631\u0627 \u06a9\u0647 \u062e\u0627\u0631\u062c \u0627\u0632 \u0635\u0641\u062d\u0647 \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u0646\u062f\u060c \u0628\u06cc\u200c\u062f\u0644\u06cc\u0644 \u0627\u06cc\u062c\u0627\u062f \u0646\u0645\u06cc\u200c\u06a9\u0646\u062f. \u0641\u0642\u0637 \u0648\u06cc\u0648\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u062f \u0628\u0628\u06cc\u0646\u062f \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u200c\u0634\u0648\u0646\u062f \u0648 \u0628\u0627 \u0627\u0633\u06a9\u0631\u0648\u0644 \u06a9\u0631\u062f\u0646\u060c \u0622\u06cc\u062a\u0645\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u0622\u06cc\u062a\u0645\u200c\u0647\u0627\u06cc \u0642\u0628\u0644\u06cc \u0645\u06cc\u200c\u0634\u0648\u0646\u062f. \u0647\u0645\u06cc\u0646 \u0645\u0648\u0636\u0648\u0639 \u0628\u0627\u0639\u062b \u0645\u06cc\u200c\u0634\u0648\u062f \u0645\u0635\u0631\u0641 \u062d\u0627\u0641\u0638\u0647 \u0628\u0647 \u0634\u06a9\u0644 \u0645\u062d\u0633\u0648\u0633\u06cc \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062f\u0631\u06cc\u0627\u0641\u062a \u0635\u0641\u062d\u0647 \u0628\u0639\u062f\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0647\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a API \u0641\u0642\u0637 \u0628\u06cc\u0633\u062a \u0645\u062d\u0635\u0648\u0644 \u0628\u0631\u0645\u06cc\u200c\u06af\u0631\u062f\u0627\u0646\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0648\u0644\u06cc\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/products?page=1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06a9\u0627\u0631\u0628\u0631 \u0627\u0633\u06a9\u0631\u0648\u0644 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u0628\u0647 \u0627\u0646\u062a\u0647\u0627\u06cc \u0644\u06cc\u0633\u062a \u0646\u0632\u062f\u06cc\u06a9 \u0645\u06cc\u200c\u0634\u0648\u062f. \u062f\u0631 \u0627\u06cc\u0646 \u0644\u062d\u0638\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0639\u062f\u06cc \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/products?page=2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 \u0622\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/products?page=3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u0647\u0645\u06cc\u0646 \u0631\u0648\u0646\u062f \u062a\u0627 \u067e\u0627\u06cc\u0627\u0646 \u0644\u06cc\u0633\u062a \u0627\u062f\u0627\u0645\u0647 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u062f. \u0628\u0647 \u0627\u06cc\u0646 \u0631\u0648\u0634 <strong>Pagination<\/strong> \u0647\u0645 \u06af\u0641\u062a\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0647\u0645\u0631\u0627\u0647 \u0628\u0627 Lazy Loading \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0634\u062e\u06cc\u0635 \u0646\u0632\u062f\u06cc\u06a9 \u0634\u062f\u0646 \u0628\u0647 \u0627\u0646\u062a\u0647\u0627\u06cc \u0644\u06cc\u0633\u062a<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0628\u062f\u0627\u0646\u06cc\u0645 \u0686\u0647 \u0632\u0645\u0627\u0646\u06cc \u0628\u0627\u06cc\u062f \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0635\u0641\u062d\u0647 \u0628\u0639\u062f \u0631\u0627 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u06cc\u0645\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u0645 \u0648\u0636\u0639\u06cc\u062a \u0627\u0633\u06a9\u0631\u0648\u0644 \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val listState = rememberLazyListState()\n\nLazyColumn(\n    state = listState\n) {\n\n    items(products) { product ->\n\n        ProductItem(product)\n\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> listState <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">rememberLazyListState<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6F42C1\">LazyColumn<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    state <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> listState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">items<\/span><span style=\"color: #24292E\">(products) { product <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">ProductItem<\/span><span style=\"color: #24292E\">(product)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u0645 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645 \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0647 \u0627\u0646\u062a\u0647\u0627\u06cc \u0644\u06cc\u0633\u062a \u0646\u0632\u062f\u06cc\u06a9 \u0634\u062f\u0647 \u0627\u0633\u062a \u06cc\u0627 \u0646\u0647.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>LaunchedEffect(listState) {\n\n    snapshotFlow {\n\n        listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index\n\n    }.collect { lastVisibleIndex ->\n\n        if (lastVisibleIndex != null &amp;&amp;\n            lastVisibleIndex >= products.size - 5\n        ) {\n\n            viewModel.loadNextPage()\n\n        }\n\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">LaunchedEffect<\/span><span style=\"color: #24292E\">(listState) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">snapshotFlow<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        listState.layoutInfo.visibleItemsInfo.<\/span><span style=\"color: #6F42C1\">lastOrNull<\/span><span style=\"color: #24292E\">()?.index<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }.<\/span><span style=\"color: #6F42C1\">collect<\/span><span style=\"color: #24292E\"> { lastVisibleIndex <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (lastVisibleIndex <\/span><span style=\"color: #D73A49\">!=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">&amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            lastVisibleIndex <\/span><span style=\"color: #D73A49\">&gt;=<\/span><span style=\"color: #24292E\"> products.size <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">5<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            viewModel.<\/span><span style=\"color: #6F42C1\">loadNextPage<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0645\u062b\u0627\u0644\u060c \u0648\u0642\u062a\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0628\u0647 \u067e\u0646\u062c \u0622\u06cc\u062a\u0645 \u0622\u062e\u0631 \u0646\u0632\u062f\u06cc\u06a9 \u0634\u0648\u062f\u060c \u0635\u0641\u062d\u0647 \u0628\u0639\u062f\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0627\u0632 \u0633\u0631\u0648\u0631 \u062f\u0631\u06cc\u0627\u0641\u062a \u062e\u0648\u0627\u0647\u062f \u0634\u062f. \u0628\u0647 \u0627\u06cc\u0646 \u062a\u0631\u062a\u06cc\u0628\u060c \u0642\u0628\u0644 \u0627\u0632 \u0627\u06cc\u0646\u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0647 \u0627\u0646\u062a\u0647\u0627\u06cc \u0644\u06cc\u0633\u062a \u0628\u0631\u0633\u062f\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062c\u062f\u06cc\u062f \u0622\u0645\u0627\u062f\u0647 \u0634\u062f\u0647\u200c\u0627\u0646\u062f \u0648 \u0627\u0633\u06a9\u0631\u0648\u0644 \u06a9\u0627\u0645\u0644\u0627\u064b \u0631\u0648\u0627\u0646 \u0628\u0627\u0642\u06cc \u0645\u06cc\u200c\u0645\u0627\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0645\u0631\u0627\u0642\u0628 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u062a\u06a9\u0631\u0627\u0631\u06cc \u0628\u0627\u0634\u06cc\u062f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0647\u0646\u06af\u0627\u0645 \u0627\u0633\u06a9\u0631\u0648\u0644\u060c \u0686\u0646\u062f\u06cc\u0646 \u0628\u0627\u0631 \u0645\u062a\u0648\u0627\u0644\u06cc \u0645\u062a\u062f <code>loadNextPage<\/code> \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0634\u0648\u062f. \u062f\u0631 \u0627\u06cc\u0646 \u062d\u0627\u0644\u062a \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0686\u0646\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u0634\u0627\u0628\u0647 \u0628\u0647 \u0633\u0631\u0648\u0631 \u0627\u0631\u0633\u0627\u0644 \u0634\u0648\u0646\u062f \u0648 \u0647\u0645 \u067e\u0647\u0646\u0627\u06cc \u0628\u0627\u0646\u062f \u0648 \u0647\u0645 \u0645\u0646\u0627\u0628\u0639 \u0633\u0631\u0648\u0631 \u0647\u062f\u0631 \u0628\u0631\u0648\u062f. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u062f\u0627\u062e\u0644 ViewModel \u06cc\u06a9 \u0645\u062a\u063a\u06cc\u0631 \u0628\u0631\u0627\u06cc \u0648\u0636\u0639\u06cc\u062a \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u06cc\u0645.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private var isLoading = false\n\nsuspend fun loadNextPage() {\n\n    if (isLoading) return\n\n    isLoading = true\n\n    try {\n\n        repository.loadNextPage()\n\n    } finally {\n\n        isLoading = false\n\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> isLoading <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">loadNextPage<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (isLoading) <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    isLoading <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        repository.<\/span><span style=\"color: #6F42C1\">loadNextPage<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    } <\/span><span style=\"color: #D73A49\">finally<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        isLoading <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0627\u06cc\u0646 \u062a\u0631\u062a\u06cc\u0628 \u062a\u0627 \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0642\u0628\u0644\u06cc \u062a\u0645\u0627\u0645 \u0646\u0634\u062f\u0647 \u0628\u0627\u0634\u062f\u060c \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062c\u062f\u06cc\u062f\u06cc \u0627\u0631\u0633\u0627\u0644 \u0646\u062e\u0648\u0627\u0647\u062f \u0634\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0646\u0645\u0627\u06cc\u0634 Loading \u062f\u0631 \u0627\u0646\u062a\u0647\u0627\u06cc \u0644\u06cc\u0633\u062a<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u062f\u0631\u06cc\u0627\u0641\u062a \u0635\u0641\u062d\u0647 \u0628\u0639\u062f \u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647 \u0637\u0648\u0644 \u0628\u06a9\u0634\u062f\u060c \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0627\u0637\u0644\u0627\u0639 \u062f\u0647\u06cc\u0645 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 \u062d\u0627\u0644 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062c\u062f\u06cc\u062f \u0627\u0633\u062a.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>LazyColumn {\n\n    items(products) { product ->\n\n        ProductItem(product)\n\n    }\n\n    if (isLoading) {\n\n        item {\n\n            CircularProgressIndicator()\n\n        }\n\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">LazyColumn<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">items<\/span><span style=\"color: #24292E\">(products) { product <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">ProductItem<\/span><span style=\"color: #24292E\">(product)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (isLoading) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">item<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">CircularProgressIndicator<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0628\u0627\u0639\u062b \u0645\u06cc\u200c\u0634\u0648\u062f \u06a9\u0627\u0631\u0628\u0631 \u062a\u0635\u0648\u0631 \u0646\u06a9\u0646\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u062a\u0648\u0642\u0641 \u0634\u062f\u0647 \u0627\u0633\u062a \u0648 \u062a\u062c\u0631\u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0628\u0647\u062a\u0631\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Paging 3 \u06cc\u0627 Lazy Loading\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0644\u06cc\u0633\u062a \u0646\u0633\u0628\u062a\u0627\u064b \u06a9\u0648\u0686\u06a9 \u0628\u0627\u0634\u062f\u060c \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc Lazy Loading \u0628\u0647 \u0647\u0645\u06cc\u0646 \u0634\u06a9\u0644 \u06a9\u0627\u0645\u0644\u0627\u064b \u06a9\u0627\u0641\u06cc \u0627\u0633\u062a. \u0627\u0645\u0627 \u0648\u0642\u062a\u06cc \u0628\u0627 \u0647\u0632\u0627\u0631\u0627\u0646 \u06cc\u0627 \u0645\u06cc\u0644\u06cc\u0648\u0646\u200c\u0647\u0627 \u0631\u06a9\u0648\u0631\u062f \u0633\u0631\u0648\u06a9\u0627\u0631 \u062f\u0627\u0631\u06cc\u0645\u060c \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0627\u0632 <strong>Paging 3<\/strong> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645. \u0627\u06cc\u0646 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u06a9\u0627\u0631\u0647\u0627\u06cc \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 Pagination\u060c \u0645\u062f\u06cc\u0631\u06cc\u062a \u062d\u0627\u0641\u0638\u0647\u060c Retry\u060c Refresh \u0648 \u0647\u0645\u0627\u0647\u0646\u06af\u06cc \u0628\u0627 Compose \u0631\u0627 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u200c\u062f\u0647\u062f \u0648 \u0628\u0631\u0627\u06cc \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af \u06af\u0632\u06cc\u0646\u0647 \u0627\u0633\u062a\u0627\u0646\u062f\u0627\u0631\u062f \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Lazy Loading \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u062a\u06a9\u0646\u06cc\u06a9\u200c\u0647\u0627\u06cc \u0628\u0647\u06cc\u0646\u0647\u200c\u0633\u0627\u0632\u06cc \u0639\u0645\u0644\u06a9\u0631\u062f \u062f\u0631 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646\u200c\u0647\u0627\u06cc \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u06cc \u0627\u0633\u062a. \u0628\u0647 \u062c\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0647\u0645\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0627 \u0627\u0632 \u0647\u0645\u0627\u0646 \u0627\u0628\u062a\u062f\u0627 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u06cc\u0645\u060c \u0641\u0642\u0637 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc\u06cc \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0645\u06cc\u200c\u0634\u0648\u0646\u062f \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631 \u0647\u0645\u0627\u0646 \u0644\u062d\u0638\u0647 \u0628\u0647 \u0622\u0646\u200c\u0647\u0627 \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u062f. \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0628\u0627\u0639\u062b \u06a9\u0627\u0647\u0634 \u0645\u0635\u0631\u0641 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a\u060c \u06a9\u0627\u0647\u0634 \u0645\u0635\u0631\u0641 \u062d\u0627\u0641\u0638\u0647\u060c \u0627\u0641\u0632\u0627\u06cc\u0634 \u0633\u0631\u0639\u062a \u0627\u062c\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0648 \u0631\u0648\u0627\u0646\u200c\u062a\u0631 \u0634\u062f\u0646 \u0627\u0633\u06a9\u0631\u0648\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f. \u062f\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u06a9\u0648\u0686\u06a9 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646 Lazy Loading \u0631\u0627 \u0628\u0627 <code>LazyColumn<\/code> \u0648 \u0686\u0646\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0635\u0641\u062d\u0647\u200c\u0628\u0646\u062f\u06cc \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u06a9\u0631\u062f\u060c \u0627\u0645\u0627 \u0628\u0631\u0627\u06cc \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af\u060c \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 <strong>Paging 3<\/strong> \u0628\u0647\u062a\u0631\u06cc\u0646 \u0648 \u0627\u0633\u062a\u0627\u0646\u062f\u0627\u0631\u062f\u062a\u0631\u06cc\u0646 \u0631\u0627\u0647\u06a9\u0627\u0631 \u0627\u0633\u062a.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u062f\u0631\u0633 \u067e\u0646\u062c\u0627\u0647\u200c\u0648\u0647\u0641\u062a\u0645<\/h3>\n\n\n\n<h1 class=\"wp-block-heading\">Performance<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0631\u0627 Performance \u0627\u0647\u0645\u06cc\u062a \u062f\u0627\u0631\u062f\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u062f\u0631\u0628\u0627\u0631\u0647 \u06a9\u06cc\u0641\u06cc\u062a \u06cc\u06a9 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0635\u062d\u0628\u062a \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645\u060c \u062e\u06cc\u0644\u06cc\u200c\u0647\u0627 \u0627\u0648\u0644 \u0627\u0632 \u0647\u0645\u0647 \u0628\u0647 \u0638\u0627\u0647\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u06cc\u0627 \u0627\u0645\u06a9\u0627\u0646\u0627\u062a \u0622\u0646 \u0641\u06a9\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f. \u0627\u0645\u0627 \u0648\u0627\u0642\u0639\u06cc\u062a \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0627\u06af\u0631 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u06a9\u0646\u062f \u0628\u0627\u0634\u062f\u060c \u062d\u062a\u06cc \u0632\u06cc\u0628\u0627\u062a\u0631\u06cc\u0646 \u0637\u0631\u0627\u062d\u06cc \u062f\u0646\u06cc\u0627 \u0647\u0645 \u0646\u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u062f \u062a\u062c\u0631\u0628\u0647 \u062e\u0648\u0628\u06cc \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0628\u0633\u0627\u0632\u062f. \u062a\u0635\u0648\u0631 \u06a9\u0646 \u062f\u0627\u062e\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0631\u0648\u06cc \u06cc\u06a9 \u0645\u062d\u0635\u0648\u0644 \u0644\u0645\u0633 \u0645\u06cc\u200c\u06a9\u0646\u06cc \u0648 \u062f\u0648 \u06cc\u0627 \u0633\u0647 \u062b\u0627\u0646\u06cc\u0647 \u0637\u0648\u0644 \u0645\u06cc\u200c\u06a9\u0634\u062f \u062a\u0627 \u0635\u0641\u062d\u0647 \u0628\u0639\u062f \u0628\u0627\u0632 \u0634\u0648\u062f. \u06cc\u0627 \u0647\u0646\u06af\u0627\u0645 \u0627\u0633\u06a9\u0631\u0648\u0644 \u06a9\u0631\u062f\u0646\u060c \u0644\u06cc\u0633\u062a \u0645\u062f\u0627\u0645 \u06af\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u062a\u0635\u0627\u0648\u06cc\u0631 \u0628\u0627 \u062a\u0623\u062e\u06cc\u0631 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u0646\u062f. \u062f\u0631 \u0686\u0646\u06cc\u0646 \u0634\u0631\u0627\u06cc\u0637\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0641\u06a9\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u0634\u06a9\u0644 \u062f\u0627\u0631\u062f\u060c \u062d\u062a\u06cc \u0627\u06af\u0631 \u062f\u0644\u06cc\u0644 \u0627\u0635\u0644\u06cc \u0641\u0642\u0637 \u0628\u0647\u06cc\u0646\u0647 \u0646\u0628\u0648\u062f\u0646 \u06a9\u062f\u0647\u0627 \u0628\u0627\u0634\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Performance \u06cc\u0639\u0646\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u062a\u0648\u0627\u0646\u062f \u0628\u0627 \u06a9\u0645\u062a\u0631\u06cc\u0646 \u0645\u0635\u0631\u0641 \u0645\u0646\u0627\u0628\u0639\u060c \u0633\u0631\u06cc\u0639\u200c\u062a\u0631\u06cc\u0646 \u0648 \u0631\u0648\u0627\u0646\u200c\u062a\u0631\u06cc\u0646 \u062a\u062c\u0631\u0628\u0647 \u0645\u0645\u06a9\u0646 \u0631\u0627 \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0642\u0631\u0627\u0631 \u062f\u0647\u062f. \u0627\u06cc\u0646 \u0645\u0648\u0636\u0648\u0639 \u0641\u0642\u0637 \u0628\u0647 \u0633\u0631\u0639\u062a \u067e\u0631\u062f\u0627\u0632\u0646\u062f\u0647 \u0645\u0631\u0628\u0648\u0637 \u0646\u0645\u06cc\u200c\u0634\u0648\u062f\u061b \u0645\u0635\u0631\u0641 \u062d\u0627\u0641\u0638\u0647\u060c \u062a\u0639\u062f\u0627\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647\u060c \u0646\u062d\u0648\u0647 \u0631\u0633\u0645 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0648 \u062d\u062a\u06cc \u062a\u0639\u062f\u0627\u062f Recomposition\u0647\u0627\u06cc Compose \u0647\u0645 \u0631\u0648\u06cc Performance \u062a\u0623\u062b\u06cc\u0631 \u0645\u06cc\u200c\u06af\u0630\u0627\u0631\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0647\u0645\u06cc\u0634\u0647 \u06af\u0644\u0648\u06af\u0627\u0647 \u0631\u0627 \u067e\u06cc\u062f\u0627 \u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0642\u0628\u0644 \u0627\u0632 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0646 \u0645\u0634\u06a9\u0644\u060c \u0634\u0631\u0648\u0639 \u0628\u0647 \u0628\u0647\u06cc\u0646\u0647\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u0645. \u0641\u0631\u0636 \u06a9\u0646 \u0635\u0641\u062d\u0647 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u06a9\u0646\u062f \u0628\u0627\u0632 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0634\u0627\u06cc\u062f \u0627\u0648\u0644\u06cc\u0646 \u062d\u062f\u0633 \u0627\u06cc\u0646 \u0628\u0627\u0634\u062f \u06a9\u0647 \u0645\u0634\u06a9\u0644 \u0627\u0632 Recycler \u06cc\u0627 LazyColumn \u0627\u0633\u062a\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u0628\u0639\u062f \u0627\u0632 \u0628\u0631\u0631\u0633\u06cc \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u200c\u0634\u0648\u06cc \u06f9\u06f0 \u062f\u0631\u0635\u062f \u0632\u0645\u0627\u0646 \u0635\u0631\u0641 \u062f\u0627\u0646\u0644\u0648\u062f \u062a\u0635\u0627\u0648\u06cc\u0631 \u0627\u0632 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0647\u0645\u06cc\u0634\u0647 \u0642\u0628\u0644 \u0627\u0632 \u0647\u0631 \u062a\u063a\u06cc\u06cc\u0631\u06cc\u060c \u06af\u0644\u0648\u06af\u0627\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u067e\u06cc\u062f\u0627 \u06a9\u0646. Android Studio \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc \u0628\u0633\u06cc\u0627\u0631 \u062e\u0648\u0628\u06cc \u0645\u062b\u0644 <strong>Profiler<\/strong> \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631\u0645\u0627\u0646 \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u062f\u0647\u062f \u062a\u0627 \u0628\u0628\u06cc\u0646\u06cc\u0645 \u0632\u0645\u0627\u0646 \u0627\u062c\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0642\u06cc\u0642\u0627\u064b \u06a9\u062c\u0627 \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0627\u06af\u0631 \u0628\u062f\u0648\u0646 \u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc \u0634\u0631\u0648\u0639 \u0628\u0647 \u0628\u0647\u06cc\u0646\u0647\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u0645\u060c \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0633\u0627\u0639\u062a\u200c\u0647\u0627 \u0631\u0648\u06cc \u0628\u062e\u0634\u06cc \u06a9\u0627\u0631 \u06a9\u0646\u06cc\u0645 \u06a9\u0647 \u0627\u0635\u0644\u0627\u064b \u0645\u0634\u06a9\u0644\u06cc \u0646\u062f\u0627\u0631\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0639\u0645\u0644\u06cc\u0627\u062a \u0633\u0646\u06af\u06cc\u0646 \u0631\u0627 \u0631\u0648\u06cc Main Thread \u0627\u062c\u0631\u0627 \u0646\u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0631\u0648\u06cc <strong>Main Thread<\/strong> \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0627\u06af\u0631 \u0627\u06cc\u0646 Thread \u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647 \u062f\u0631\u06af\u06cc\u0631 \u06cc\u06a9 \u06a9\u0627\u0631 \u0633\u0646\u06af\u06cc\u0646 \u0634\u0648\u062f\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u06cc\u06af\u0631 \u0646\u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u062f \u0628\u0647 \u0644\u0645\u0633 \u06a9\u0627\u0631\u0628\u0631 \u067e\u0627\u0633\u062e \u062f\u0647\u062f \u0648 \u062d\u062a\u06cc \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u067e\u06cc\u0627\u0645 <strong>Application Not Responding (ANR)<\/strong> \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u062f\u0627\u062e\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0647\u0646\u06af\u0627\u0645 \u0648\u0631\u0648\u062f \u0628\u0647 \u0635\u0641\u062d\u0647 \u0645\u062d\u0635\u0648\u0644\u0627\u062a\u060c \u0647\u0632\u0627\u0631 \u0631\u06a9\u0648\u0631\u062f \u0631\u0627 \u067e\u0631\u062f\u0627\u0632\u0634 \u06cc\u0627 \u06cc\u06a9 \u0641\u0627\u06cc\u0644 \u0628\u0632\u0631\u06af \u0631\u0627 \u0627\u0632 \u062d\u0627\u0641\u0638\u0647 \u0645\u06cc\u200c\u062e\u0648\u0627\u0646\u06cc\u0645. \u0627\u06af\u0631 \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0631\u0648\u06cc Main Thread \u0627\u0646\u062c\u0627\u0645 \u0634\u0648\u062f\u060c \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u06a9\u0627\u0645\u0644\u0627\u064b \u0645\u062a\u0648\u0642\u0641 \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u0627\u0647\u200c\u062d\u0644 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0639\u0645\u0644\u06cc\u0627\u062a \u0632\u0645\u0627\u0646\u200c\u0628\u0631 \u0631\u0627 \u062f\u0627\u062e\u0644 Coroutine \u0648 Dispatcher \u0645\u0646\u0627\u0633\u0628 \u0627\u062c\u0631\u0627 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>viewModelScope.launch {\n\n    val products = withContext(Dispatchers.IO) {\n\n        repository.loadProducts()\n\n    }\n\n    _uiState.value = products\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">viewModelScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">withContext<\/span><span style=\"color: #24292E\">(Dispatchers.IO) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        repository.<\/span><span style=\"color: #6F42C1\">loadProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    _uiState.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> products<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0627\u06cc\u0646 \u062a\u0631\u062a\u06cc\u0628\u060c \u0639\u0645\u0644\u06cc\u0627\u062a \u0634\u0628\u06a9\u0647 \u06cc\u0627 \u062e\u0648\u0627\u0646\u062f\u0646 \u0641\u0627\u06cc\u0644 \u0631\u0648\u06cc Thread \u062f\u06cc\u06af\u0631\u06cc \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0647\u0645\u0686\u0646\u0627\u0646 \u0631\u0648\u0627\u0646 \u0628\u0627\u0642\u06cc \u0645\u06cc\u200c\u0645\u0627\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0632 Recomposition\u0647\u0627\u06cc \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Jetpack Compose \u0647\u0631 \u0628\u0627\u0631 \u06a9\u0647 State \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f\u060c \u0628\u062e\u0634\u06cc \u0627\u0632 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u062f\u0648\u0628\u0627\u0631\u0647 \u0631\u0633\u0645 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0627\u06cc\u0646 \u0648\u06cc\u0698\u06af\u06cc \u0641\u0648\u0642\u200c\u0627\u0644\u0639\u0627\u062f\u0647 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u0627\u06af\u0631 State\u0647\u0627 \u0631\u0627 \u062f\u0631\u0633\u062a \u0645\u062f\u06cc\u0631\u06cc\u062a \u0646\u06a9\u0646\u06cc\u0645\u060c \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0628\u062e\u0634 \u0628\u0632\u0631\u06af\u06cc \u0627\u0632 \u0635\u0641\u062d\u0647 \u0628\u0627\u0631\u0647\u0627 \u0648 \u0628\u0627\u0631\u0647\u0627 \u0628\u062f\u0648\u0646 \u062f\u0644\u06cc\u0644 \u062f\u0648\u0628\u0627\u0631\u0647 \u0633\u0627\u062e\u062a\u0647 \u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0641\u0642\u0637 \u062a\u0639\u062f\u0627\u062f \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u062f\u0627\u062e\u0644 \u0633\u0628\u062f \u062e\u0631\u06cc\u062f \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f\u0647 \u0627\u0633\u062a. \u0627\u06af\u0631 \u06a9\u0644 \u0635\u0641\u062d\u0647 \u0628\u0647 \u0647\u0645\u0627\u0646 State \u0648\u0627\u0628\u0633\u062a\u0647 \u0628\u0627\u0634\u062f\u060c \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0635\u062f\u0647\u0627 Composable \u062f\u0648\u0628\u0627\u0631\u0647 \u0627\u062c\u0631\u0627 \u0634\u0648\u0646\u062f\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u0641\u0642\u0637 \u0622\u06cc\u06a9\u0648\u0646 \u0633\u0628\u062f \u062e\u0631\u06cc\u062f \u0646\u06cc\u0627\u0632 \u0628\u0647 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u062f\u0627\u0634\u062a\u0647 \u0627\u0633\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0647\u0645\u06cc\u0634\u0647 State\u0647\u0627 \u0631\u0627 \u062a\u0627 \u062d\u062f \u0645\u0645\u06a9\u0646 \u06a9\u0648\u0686\u06a9 \u0648 \u0645\u0633\u062a\u0642\u0644 \u0646\u06af\u0647 \u062f\u0627\u0631 \u0648 \u0627\u0632 \u0627\u06cc\u062c\u0627\u062f State\u0647\u0627\u06cc \u0628\u0632\u0631\u06af \u0648 \u0647\u0645\u0647\u200c\u06a9\u0627\u0631\u0647 \u062e\u0648\u062f\u062f\u0627\u0631\u06cc \u06a9\u0646.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0632 LazyColumn \u0628\u0647 \u062c\u0627\u06cc Column \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u062a\u0639\u062f\u0627\u062f \u0622\u06cc\u062a\u0645\u200c\u0647\u0627 \u0632\u06cc\u0627\u062f \u0627\u0633\u062a\u060c \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 <code>Column<\/code> \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u0646\u0627\u0633\u0628\u06cc \u0646\u06cc\u0633\u062a\u060c \u0686\u0648\u0646 \u062a\u0645\u0627\u0645 \u0622\u06cc\u062a\u0645\u200c\u0647\u0627 \u0631\u0627 \u06cc\u06a9\u200c\u062c\u0627 \u0645\u06cc\u200c\u0633\u0627\u0632\u062f\u061b \u062d\u062a\u06cc \u0622\u0646\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0647\u0646\u0648\u0632 \u0631\u0648\u06cc \u0635\u0641\u062d\u0647 \u062f\u06cc\u062f\u0647 \u0646\u0645\u06cc\u200c\u0634\u0648\u0646\u062f.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>LazyColumn {\n\n    items(products) { product ->\n\n        ProductItem(product)\n\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">LazyColumn<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">items<\/span><span style=\"color: #24292E\">(products) { product <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">ProductItem<\/span><span style=\"color: #24292E\">(product)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><code>LazyColumn<\/code> \u0641\u0642\u0637 \u0622\u06cc\u062a\u0645\u200c\u0647\u0627\u06cc\u06cc \u0631\u0627 \u0645\u06cc\u200c\u0633\u0627\u0632\u062f \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631 \u0647\u0645\u0627\u0646 \u0644\u062d\u0638\u0647 \u0645\u06cc\u200c\u0628\u06cc\u0646\u062f. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0647\u0645 \u062d\u0627\u0641\u0638\u0647 \u06a9\u0645\u062a\u0631\u06cc \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0647\u0645 \u0627\u0633\u06a9\u0631\u0648\u0644 \u0628\u0633\u06cc\u0627\u0631 \u0631\u0648\u0627\u0646\u200c\u062a\u0631 \u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647 \u0631\u0627 \u06a9\u0645\u062a\u0631 \u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06af\u0627\u0647\u06cc \u0645\u0634\u06a9\u0644 Performance \u0627\u0635\u0644\u0627\u064b \u0627\u0632 \u06a9\u062f\u0647\u0627\u06cc \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0646\u06cc\u0633\u062a. \u0641\u0631\u0636 \u06a9\u0646 \u0628\u0631\u0627\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0647\u0631 \u0645\u062d\u0635\u0648\u0644\u060c \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062c\u062f\u0627\u06af\u0627\u0646\u0647 \u0628\u0631\u0627\u06cc \u062a\u0635\u0648\u06cc\u0631\u060c \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a \u0648 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u06cc\u06af\u0631 \u0628\u0631\u0627\u06cc \u0645\u0648\u062c\u0648\u062f\u06cc \u06a9\u0627\u0644\u0627 \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u06cc\u0645. \u0627\u06af\u0631 \u0635\u0641\u062d\u0647 \u0628\u06cc\u0633\u062a \u0645\u062d\u0635\u0648\u0644 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f\u060c \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0634\u0635\u062a \u062f\u0631\u062e\u0648\u0627\u0633\u062a HTTP \u0627\u0631\u0633\u0627\u0644 \u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647\u062a\u0631 \u0627\u0633\u062a API\u0647\u0627 \u0637\u0648\u0631\u06cc \u0637\u0631\u0627\u062d\u06cc \u0634\u0648\u0646\u062f \u06a9\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0648\u0631\u062f\u0646\u06cc\u0627\u0632 \u0647\u0631 \u0635\u0641\u062d\u0647 \u0631\u0627 \u062a\u0627 \u062d\u062f \u0645\u0645\u06a9\u0646 \u062f\u0631 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0631\u06af\u0631\u062f\u0627\u0646\u0646\u062f. \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0647\u0645 \u0633\u0631\u0639\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0628\u06cc\u0634\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u0647\u0645 \u0641\u0634\u0627\u0631 \u0631\u0648\u06cc \u0633\u0631\u0648\u0631 \u0631\u0627 \u06a9\u0627\u0647\u0634 \u0645\u06cc\u200c\u062f\u0647\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0635\u0627\u0648\u06cc\u0631 \u0631\u0627 \u0628\u0627 \u0627\u0646\u062f\u0627\u0632\u0647 \u0645\u0646\u0627\u0633\u0628 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u06cc\u06a9 \u062a\u0635\u0648\u06cc\u0631 \u06f4\u06f0\u06f0\u06f0 \u062f\u0631 \u06f3\u06f0\u06f0\u06f0 \u067e\u06cc\u06a9\u0633\u0644\u06cc \u0631\u0627 \u0628\u0631\u0627\u06cc \u06cc\u06a9 \u0622\u06cc\u06a9\u0648\u0646 \u06a9\u0648\u0686\u06a9 \u062f\u0627\u0646\u0644\u0648\u062f \u06a9\u0646\u06cc\u0645. \u062f\u0631 \u0627\u06cc\u0646 \u062d\u0627\u0644\u062a \u0647\u0645 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0628\u06cc\u0634\u062a\u0631\u06cc \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0647\u0645 Decode \u06a9\u0631\u062f\u0646 \u062a\u0635\u0648\u06cc\u0631 \u0632\u0645\u0627\u0646 \u0628\u06cc\u0634\u062a\u0631\u06cc \u0645\u06cc\u200c\u0628\u0631\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 <strong>Coil<\/strong> \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0646\u062f \u062a\u0635\u0648\u06cc\u0631 \u0631\u0627 \u0645\u062a\u0646\u0627\u0633\u0628 \u0628\u0627 \u0627\u0646\u062f\u0627\u0632\u0647 View \u062f\u0631\u06cc\u0627\u0641\u062a \u0648 \u067e\u0631\u062f\u0627\u0632\u0634 \u06a9\u0646\u0646\u062f. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0647\u0645\u06cc\u0634\u0647 \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0627\u0632 \u0627\u06cc\u0646 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645 \u0648 \u062a\u0635\u0627\u0648\u06cc\u0631 \u0631\u0627 \u0628\u0627 \u0627\u0646\u062f\u0627\u0632\u0647 \u0648\u0627\u0642\u0639\u06cc \u0645\u0648\u0631\u062f\u0646\u06cc\u0627\u0632 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0647\u06cc\u0645.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0632 Cache \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u062f\u0631\u0633 \u0642\u0628\u0644 \u062f\u0631\u0628\u0627\u0631\u0647 <strong>Image Cache<\/strong> \u0635\u062d\u0628\u062a \u06a9\u0631\u062f\u06cc\u0645. Cache \u0641\u0642\u0637 \u0645\u062e\u0635\u0648\u0635 \u062a\u0635\u0627\u0648\u06cc\u0631 \u0646\u06cc\u0633\u062a. \u0647\u0631 \u062f\u0627\u062f\u0647\u200c\u0627\u06cc \u06a9\u0647 \u0645\u0631\u062a\u0628 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u06a9\u0645\u06cc \u062f\u0627\u0631\u062f\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u062f Cache \u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0644\u06cc\u0633\u062a \u062f\u0633\u062a\u0647\u200c\u0628\u0646\u062f\u06cc \u0645\u062d\u0635\u0648\u0644\u0627\u062a\u060c \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u06cc\u0627 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u067e\u0631\u0648\u0641\u0627\u06cc\u0644 \u06a9\u0627\u0631\u0628\u0631 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0644\u0627\u0632\u0645 \u0646\u06cc\u0633\u062a \u0647\u0631 \u0628\u0627\u0631 \u0627\u0632 \u0633\u0631\u0648\u0631 \u062f\u0631\u06cc\u0627\u0641\u062a \u0634\u0648\u0646\u062f. \u0627\u06af\u0631 \u0627\u06cc\u0646 \u062f\u0627\u062f\u0647\u200c\u0647\u0627 \u0631\u0627 Cache \u06a9\u0646\u06cc\u0645\u060c \u0647\u0645 \u0633\u0631\u0639\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u06cc\u0634\u062a\u0631 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0647\u0645 \u062a\u0639\u062f\u0627\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647 \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc \u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc \u0631\u0627 \u0641\u0631\u0627\u0645\u0648\u0634 \u0646\u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc \u0645\u062a\u0639\u062f\u062f\u06cc \u0628\u0631\u0627\u06cc \u0628\u0631\u0631\u0633\u06cc Performance \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u062f\u0647\u062f. CPU Profiler \u0645\u06cc\u0632\u0627\u0646 \u0645\u0635\u0631\u0641 \u067e\u0631\u062f\u0627\u0632\u0646\u062f\u0647 \u0631\u0627 \u0646\u0634\u0627\u0646 \u0645\u06cc\u200c\u062f\u0647\u062f\u060c Memory Profiler \u0648\u0636\u0639\u06cc\u062a \u062d\u0627\u0641\u0638\u0647 \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 Network Inspector \u062a\u0639\u062f\u0627\u062f \u0648 \u0632\u0645\u0627\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647 \u0631\u0627 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u200c\u062f\u0647\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647\u062a\u0631\u06cc\u0646 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633 \u06a9\u0633\u06cc \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0647\u0645\u06cc\u0634\u0647 \u062d\u062f\u0633 \u062f\u0631\u0633\u062a\u06cc \u0628\u0632\u0646\u062f\u061b \u0628\u0644\u06a9\u0647 \u06a9\u0633\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0642\u0628\u0644 \u0627\u0632 \u0647\u0631 \u062a\u0635\u0645\u06cc\u0645\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc \u06a9\u0646\u062f \u0648 \u0628\u0639\u062f \u0628\u0631 \u0627\u0633\u0627\u0633 \u062f\u0627\u062f\u0647 \u0648\u0627\u0642\u0639\u06cc \u0645\u0634\u06a9\u0644 \u0631\u0627 \u0628\u0631\u0637\u0631\u0641 \u06a9\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Performance \u0641\u0642\u0637 \u0628\u0647 \u0633\u0631\u06cc\u0639 \u0628\u0648\u062f\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u062e\u0644\u0627\u0635\u0647 \u0646\u0645\u06cc\u200c\u0634\u0648\u062f\u061b \u0628\u0644\u06a9\u0647 \u0645\u062c\u0645\u0648\u0639\u0647\u200c\u0627\u06cc \u0627\u0632 \u062a\u0635\u0645\u06cc\u0645\u200c\u0647\u0627\u06cc \u062f\u0631\u0633\u062a \u062f\u0631 \u0637\u0631\u0627\u062d\u06cc\u060c \u0645\u062f\u06cc\u0631\u06cc\u062a \u062d\u0627\u0641\u0638\u0647\u060c \u0627\u0631\u062a\u0628\u0627\u0637 \u0628\u0627 \u0634\u0628\u06a9\u0647 \u0648 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0627\u0633\u062a. \u0627\u06af\u0631 \u0639\u0645\u0644\u06cc\u0627\u062a \u0633\u0646\u06af\u06cc\u0646 \u0631\u0627 \u0627\u0632 Main Thread \u062e\u0627\u0631\u062c \u06a9\u0646\u06cc\u0645\u060c \u0627\u0632 Lazy Loading \u0648 Cache \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645\u060c \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u0634\u0628\u06a9\u0647 \u0631\u0627 \u062d\u0630\u0641 \u06a9\u0646\u06cc\u0645 \u0648 State\u0647\u0627\u06cc Compose \u0631\u0627 \u0628\u0647\u200c\u062f\u0631\u0633\u062a\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc\u0645\u060c \u062d\u062a\u06cc \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc\u200c\u0647\u0627\u06cc \u0636\u0639\u06cc\u0641 \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0627\u06cc \u0631\u0648\u0627\u0646 \u0648 \u0644\u0630\u062a\u200c\u0628\u062e\u0634 \u0633\u0627\u062e\u062a. \u062a\u0641\u0627\u0648\u062a \u06cc\u06a9 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0645\u0639\u0645\u0648\u0644\u06cc \u0628\u0627 \u06cc\u06a9 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u062f\u0631 \u0647\u0645\u06cc\u0646 \u062c\u0632\u0626\u06cc\u0627\u062a \u062f\u06cc\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u062f\u0631\u0633 \u067e\u0646\u062c\u0627\u0647\u200c\u0648\u0647\u0634\u062a\u0645<\/h3>\n\n\n\n<h1 class=\"wp-block-heading\">Battery Optimization<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0631\u0627 Battery Optimization \u0627\u0647\u0645\u06cc\u062a \u062f\u0627\u0631\u062f\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u0628\u06cc\u0646 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627\u06cc \u062a\u0627\u0632\u0647\u200c\u06a9\u0627\u0631 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0641\u06a9\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f \u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0632 \u0646\u0638\u0631 \u0638\u0627\u0647\u0631\u06cc \u062e\u0648\u0628 \u06a9\u0627\u0631 \u06a9\u0646\u062f\u060c \u062f\u06cc\u06af\u0631 \u0647\u0645\u0647 \u0686\u06cc\u0632 \u062a\u0645\u0627\u0645 \u0627\u0633\u062a. \u0627\u0645\u0627 \u0627\u0632 \u062f\u06cc\u062f \u06a9\u0627\u0631\u0628\u0631\u060c \u0627\u06af\u0631 \u06cc\u06a9 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0628\u0627\u0639\u062b \u0634\u0648\u062f \u0628\u0627\u062a\u0631\u06cc \u06af\u0648\u0634\u06cc \u0632\u0648\u062f\u062a\u0631 \u062e\u0627\u0644\u06cc \u0634\u0648\u062f\u060c \u062e\u06cc\u0644\u06cc \u0633\u0631\u06cc\u0639 \u062d\u0630\u0641 \u062e\u0648\u0627\u0647\u062f \u0634\u062f\u061b \u062d\u062a\u06cc \u0627\u06af\u0631 \u0627\u0645\u06a9\u0627\u0646\u0627\u062a \u0641\u0648\u0642\u200c\u0627\u0644\u0639\u0627\u062f\u0647\u200c\u0627\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u06a9\u0627\u0631\u0628\u0631 <strong>\u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646<\/strong> \u0631\u0627 \u0635\u0628\u062d \u0628\u0627\u0632 \u06a9\u0631\u062f\u0647\u060c \u0642\u06cc\u0645\u062a \u0686\u0646\u062f \u06a9\u0627\u0644\u0627 \u0631\u0627 \u062f\u06cc\u062f\u0647 \u0648 \u0628\u0639\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0628\u0633\u062a\u0647 \u0627\u0633\u062a. \u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0639\u062f \u0627\u0632 \u0628\u0633\u062a\u0647 \u0634\u062f\u0646 \u0647\u0645\u0686\u0646\u0627\u0646 \u0647\u0631 \u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647 \u06cc\u06a9 \u0628\u0627\u0631 \u0628\u0647 \u0633\u0631\u0648\u0631 \u0648\u0635\u0644 \u0634\u0648\u062f\u060c \u0645\u0648\u0642\u0639\u06cc\u062a \u0645\u06a9\u0627\u0646\u06cc \u0631\u0627 \u0628\u062e\u0648\u0627\u0646\u062f \u06cc\u0627 \u067e\u0631\u062f\u0627\u0632\u0634\u200c\u0647\u0627\u06cc \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u062f\u0647\u062f\u060c \u0628\u062f\u0648\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0645\u062a\u0648\u062c\u0647 \u0634\u0648\u062f\u060c \u0628\u0627\u062a\u0631\u06cc \u06af\u0648\u0634\u06cc \u062f\u0631 \u062d\u0627\u0644 \u0645\u0635\u0631\u0641 \u0634\u062f\u0646 \u0627\u0633\u062a. \u0634\u0627\u06cc\u062f \u062e\u0648\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0641\u0642\u0637 \u0686\u0646\u062f \u062f\u0642\u06cc\u0642\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0634\u062f\u0647 \u0628\u0627\u0634\u062f\u060c \u0627\u0645\u0627 \u0627\u062b\u0631\u0634 \u062a\u0627 \u0633\u0627\u0639\u062a\u200c\u0647\u0627 \u0628\u0627\u0642\u06cc \u0628\u0645\u0627\u0646\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644\u060c \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u0648\u06cc\u0698\u06af\u06cc\u200c\u0647\u0627\u06cc \u06cc\u06a9 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0648\u0642\u062a\u06cc \u0644\u0627\u0632\u0645 \u0646\u06cc\u0633\u062a \u06a9\u0627\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u062f\u0647\u062f\u060c \u0648\u0627\u0642\u0639\u0627\u064b \u0647\u06cc\u0686 \u06a9\u0627\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u0646\u062f\u0647\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0628\u0627\u062a\u0631\u06cc \u0628\u06cc\u0634\u062a\u0631 \u0627\u0632 \u067e\u0631\u062f\u0627\u0632\u0646\u062f\u0647 \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u0634\u0648\u062f \u06cc\u0627 \u0634\u0628\u06a9\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u06cc\u0634\u062a\u0631 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647\u200c\u0647\u0627 \u062a\u0635\u0648\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f \u0645\u0635\u0631\u0641 \u0628\u0627\u062a\u0631\u06cc \u0641\u0642\u0637 \u0628\u0647 \u067e\u0631\u062f\u0627\u0632\u0646\u062f\u0647 \u0645\u0631\u0628\u0648\u0637 \u0627\u0633\u062a\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u0645\u0627\u062c\u0631\u0627 \u067e\u06cc\u0686\u06cc\u062f\u0647\u200c\u062a\u0631 \u0627\u0632 \u0627\u06cc\u0646 \u0627\u0633\u062a. \u0631\u0648\u0634\u0646 \u0634\u062f\u0646 \u0622\u0646\u062a\u0646 \u0634\u0628\u06a9\u0647\u060c \u0641\u0639\u0627\u0644 \u0634\u062f\u0646 GPS\u060c \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u062f\u0627\u0648\u0645 \u0627\u0632 \u062f\u0648\u0631\u0628\u06cc\u0646\u060c \u0628\u0644\u0648\u062a\u0648\u062b\u060c Wi-Fi \u0648 \u062d\u062a\u06cc \u0631\u0648\u0634\u0646 \u06a9\u0631\u062f\u0646 \u0645\u06a9\u0631\u0631 CPU\u060c \u0647\u0645\u06af\u06cc \u0631\u0648\u06cc \u0645\u0635\u0631\u0641 \u0628\u0627\u062a\u0631\u06cc \u062a\u0623\u062b\u06cc\u0631 \u0645\u06cc\u200c\u06af\u0630\u0627\u0631\u0646\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0627\u06af\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0647\u0631 \u062f\u0647 \u062b\u0627\u0646\u06cc\u0647 \u06cc\u06a9 \u0628\u0627\u0631 \u0628\u0631\u0627\u06cc \u0628\u0631\u0631\u0633\u06cc \u0642\u06cc\u0645\u062a \u06a9\u0627\u0644\u0627\u0647\u0627 \u0628\u0647 \u0633\u0631\u0648\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0641\u0631\u0633\u062a\u062f\u060c \u0634\u0627\u06cc\u062f \u062d\u062c\u0645 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0645\u0635\u0631\u0641\u06cc \u0646\u0627\u0686\u06cc\u0632 \u0628\u0627\u0634\u062f\u060c \u0627\u0645\u0627 \u0647\u0645\u06cc\u0646 \u0628\u06cc\u062f\u0627\u0631 \u06a9\u0631\u062f\u0646 \u0645\u062f\u0627\u0648\u0645 \u0631\u0627\u062f\u06cc\u0648\u06cc \u0634\u0628\u06a9\u0647 \u0628\u0627\u0639\u062b \u0645\u0635\u0631\u0641 \u0642\u0627\u0628\u0644 \u062a\u0648\u062c\u0647 \u0628\u0627\u062a\u0631\u06cc \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644\u060c \u062a\u0639\u062f\u0627\u062f \u062f\u0641\u0639\u0627\u062a \u0627\u0646\u062c\u0627\u0645 \u06cc\u06a9 \u06a9\u0627\u0631 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u0632 \u062e\u0648\u062f \u0622\u0646 \u06a9\u0627\u0631 \u0645\u0647\u0645\u200c\u062a\u0631 \u0627\u0633\u062a.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0632 Polling \u0645\u062f\u0627\u0648\u0645 \u062e\u0648\u062f\u062f\u0627\u0631\u06cc \u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0645\u06cc\u200c\u062e\u0648\u0627\u0647\u06cc\u0645 \u0642\u06cc\u0645\u062a \u062f\u0644\u0627\u0631 \u06cc\u0627 \u0645\u0648\u062c\u0648\u062f\u06cc \u06cc\u06a9 \u06a9\u0627\u0644\u0627 \u0631\u0627 \u0628\u0647\u200c\u0631\u0648\u0632 \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645. \u0633\u0627\u062f\u0647\u200c\u062a\u0631\u06cc\u0646 \u0631\u0627\u0647 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0647\u0631 \u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062c\u062f\u06cc\u062f \u0628\u0647 \u0633\u0631\u0648\u0631 \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">\u0647\u0631 10 \u062b\u0627\u0646\u06cc\u0647<br>\u2502<br>\u25bc<br>\u0627\u0631\u0633\u0627\u0644 \u062f\u0631\u062e\u0648\u0627\u0633\u062a<br>\u2502<br>\u25bc<br>\u062f\u0631\u06cc\u0627\u0641\u062a \u067e\u0627\u0633\u062e<br>\u2502<br>\u25bc<br>\u062a\u06a9\u0631\u0627\u0631&#8230;<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0631\u0648\u0634 \u0634\u0627\u06cc\u062f \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0633\u0627\u062f\u0647\u200c\u0627\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f\u060c \u0627\u0645\u0627 \u0628\u0631\u0627\u06cc \u0628\u0627\u062a\u0631\u06cc \u0648 \u062d\u062a\u06cc \u0633\u0631\u0648\u0631 \u0627\u0635\u0644\u0627\u064b \u0645\u0646\u0627\u0633\u0628 \u0646\u06cc\u0633\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0628\u0627\u06cc\u062f \u0628\u0647\u200c\u0635\u0648\u0631\u062a \u0644\u062d\u0638\u0647\u200c\u0627\u06cc \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0646\u062f\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b <strong>WebSocket<\/strong> \u0627\u0646\u062a\u062e\u0627\u0628 \u0628\u0633\u06cc\u0627\u0631 \u0628\u0647\u062a\u0631\u06cc \u0627\u0633\u062a\u060c \u0686\u0648\u0646 \u06cc\u06a9 \u0627\u062a\u0635\u0627\u0644 \u0628\u0631\u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u062a\u0627 \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u0644\u0627\u0632\u0645 \u0628\u0627\u0634\u062f \u0647\u0645\u0627\u0646 \u0627\u062a\u0635\u0627\u0644 \u062d\u0641\u0638 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0627\u06af\u0631 \u0647\u0645 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0641\u0642\u0637 \u0647\u0631 \u0686\u0646\u062f \u0633\u0627\u0639\u062a \u06cc\u06a9 \u0628\u0627\u0631 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f\u060c \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0627\u0632 <strong>WorkManager<\/strong> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645 \u062a\u0627 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u062e\u0648\u062f\u0634 \u0628\u0647\u062a\u0631\u06cc\u0646 \u0632\u0645\u0627\u0646 \u0627\u062c\u0631\u0627\u06cc \u06a9\u0627\u0631 \u0631\u0627 \u0627\u0646\u062a\u062e\u0627\u0628 \u06a9\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u062c\u0627\u0632\u0647 \u0628\u062f\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0632\u0645\u0627\u0646\u200c\u0628\u0646\u062f\u06cc \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u062f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u062f\u0644\u0627\u06cc\u0644 \u0645\u0639\u0631\u0641\u06cc WorkManager \u0647\u0645\u06cc\u0646 \u0645\u0648\u0636\u0648\u0639 \u0628\u0648\u062f. \u0633\u06cc\u0633\u062a\u0645\u200c\u0639\u0627\u0645\u0644 \u0628\u0647\u062a\u0631 \u0627\u0632 \u0645\u0627 \u0645\u06cc\u200c\u062f\u0627\u0646\u062f \u0686\u0647 \u0632\u0645\u0627\u0646\u06cc \u06af\u0648\u0634\u06cc \u062f\u0631 \u062d\u0627\u0644 \u0634\u0627\u0631\u0698 \u0627\u0633\u062a\u060c \u0686\u0647 \u0632\u0645\u0627\u0646\u06cc \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0645\u0646\u0627\u0633\u0628 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f \u0648 \u0686\u0647 \u0632\u0645\u0627\u0646\u06cc \u0627\u062c\u0631\u0627\u06cc \u06cc\u06a9 \u06a9\u0627\u0631 \u06a9\u0645\u062a\u0631\u06cc\u0646 \u062a\u0623\u062b\u06cc\u0631 \u0631\u0627 \u0631\u0648\u06cc \u0628\u0627\u062a\u0631\u06cc \u0645\u06cc\u200c\u06af\u0630\u0627\u0631\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0642\u0631\u0627\u0631 \u0627\u0633\u062a \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0647\u0631 \u0634\u0634 \u0633\u0627\u0639\u062a \u06cc\u06a9 \u0628\u0627\u0631 \u0642\u06cc\u0645\u062a \u06a9\u0627\u0644\u0627\u0647\u0627 \u0631\u0627 \u0647\u0645\u06af\u0627\u0645\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u062f\u060c \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0631\u0627 \u0628\u0647 WorkManager \u0628\u0633\u067e\u0627\u0631\u06cc\u0645\u060c \u0646\u0647 \u0627\u06cc\u0646\u06a9\u0647 \u062e\u0648\u062f\u0645\u0627\u0646 \u06cc\u06a9 \u0633\u0631\u0648\u06cc\u0633 \u062f\u0627\u0626\u0645\u06cc \u0627\u062c\u0631\u0627 \u06a9\u0646\u06cc\u0645. \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0647\u0645 \u0645\u0635\u0631\u0641 \u0628\u0627\u062a\u0631\u06cc \u0631\u0627 \u06a9\u0645\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u0647\u0645 \u0628\u0627\u0639\u062b \u0645\u06cc\u200c\u0634\u0648\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627 \u0633\u06cc\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0633\u0627\u0632\u06af\u0627\u0631 \u0628\u0627\u0634\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0632 Wake Lock \u0641\u0642\u0637 \u062f\u0631 \u0645\u0648\u0627\u0642\u0639 \u0636\u0631\u0648\u0631\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06af\u0627\u0647\u06cc \u0644\u0627\u0632\u0645 \u0627\u0633\u062a \u0647\u0646\u06af\u0627\u0645 \u0627\u0646\u062c\u0627\u0645 \u06cc\u06a9 \u0639\u0645\u0644\u06cc\u0627\u062a \u0645\u0647\u0645\u060c \u0627\u062c\u0627\u0632\u0647 \u0646\u062f\u0647\u06cc\u0645 \u06af\u0648\u0634\u06cc \u0628\u0647 \u062d\u0627\u0644\u062a Sleep \u0628\u0631\u0648\u062f. \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0628\u0631\u0627\u06cc \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0645\u0641\u0647\u0648\u0645\u06cc \u0628\u0647 \u0646\u0627\u0645 <strong>Wake Lock<\/strong> \u062f\u0627\u0631\u062f. \u0627\u0645\u0627 Wake Lock \u06cc\u06a9\u06cc \u0627\u0632 \u067e\u0631\u0645\u0635\u0631\u0641\u200c\u062a\u0631\u06cc\u0646 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc \u0633\u06cc\u0633\u062a\u0645 \u0627\u0633\u062a. \u0627\u06af\u0631 \u0627\u0634\u062a\u0628\u0627\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0634\u0648\u062f\u060c \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u06af\u0648\u0634\u06cc \u0633\u0627\u0639\u062a\u200c\u0647\u0627 \u0628\u06cc\u062f\u0627\u0631 \u0628\u0645\u0627\u0646\u062f \u0648 \u0628\u0627\u062a\u0631\u06cc \u0628\u0627 \u0633\u0631\u0639\u062a \u0632\u06cc\u0627\u062f\u06cc \u062a\u062e\u0644\u06cc\u0647 \u0634\u0648\u062f. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0641\u0642\u0637 \u0632\u0645\u0627\u0646\u06cc \u0627\u0632 Wake Lock \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646 \u06a9\u0647 \u0648\u0627\u0642\u0639\u0627\u064b \u0647\u06cc\u0686 \u0631\u0627\u0647\u200c\u062d\u0644 \u062f\u06cc\u06af\u0631\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f \u0648 \u0647\u0645\u06cc\u0634\u0647 \u0628\u0639\u062f \u0627\u0632 \u067e\u0627\u06cc\u0627\u0646 \u06a9\u0627\u0631 \u0622\u0646 \u0631\u0627 \u0622\u0632\u0627\u062f \u06a9\u0646.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0632 Location \u0628\u06cc\u200c\u062f\u0644\u06cc\u0644 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648\u0627\u0642\u0639\u0627\u064b \u0628\u0647 \u0645\u0648\u0642\u0639\u06cc\u062a \u0645\u06a9\u0627\u0646\u06cc \u0646\u06cc\u0627\u0632 \u0646\u062f\u0627\u0631\u062f\u060c \u0647\u0631<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0628\u062e\u0634 \u0646\u0647\u0645 \u2014 \u0627\u0646\u062a\u0634\u0627\u0631<\/h1>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u062f\u0631\u0633 \u067e\u0646\u062c\u0627\u0647\u200c\u0648\u0646\u0647\u0645<\/h3>\n\n\n\n<h1 class=\"wp-block-heading\">Build Variant<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Build Variant \u0686\u06cc\u0633\u062a\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u0627\u06cc\u0646\u062c\u0627 \u0647\u0631 \u0628\u0627\u0631 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0627\u062c\u0631\u0627 \u06a9\u0631\u062f\u06cc\u0645\u060c \u0647\u0645\u06cc\u0634\u0647 \u06cc\u06a9 \u0646\u0633\u062e\u0647 \u0627\u0632 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0633\u0627\u062e\u062a\u0647 \u0634\u062f. \u0627\u0645\u0627 \u062a\u0648\u06cc \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u06cc\u0686\u200c\u0648\u0642\u062a \u0641\u0642\u0637 \u06cc\u06a9 \u0646\u0633\u062e\u0647 \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u0647. \u0641\u0631\u0636 \u06a9\u0646 \u0631\u0648\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u06cc. \u062e\u0648\u062f\u062a \u0648 \u0627\u0639\u0636\u0627\u06cc \u062a\u06cc\u0645 \u0647\u0631 \u0631\u0648\u0632 \u062f\u0631 \u062d\u0627\u0644 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0646 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f \u0647\u0633\u062a\u06cc\u0646\u060c \u0648\u0644\u06cc \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0647\u0632\u0627\u0631\u0627\u0646 \u06a9\u0627\u0631\u0628\u0631 \u0647\u0645 \u062f\u0627\u0631\u0646 \u0627\u0632 \u0646\u0633\u062e\u0647 \u0627\u0635\u0644\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646. \u0637\u0628\u06cc\u0639\u062a\u0627\u064b \u0646\u0645\u06cc\u200c\u062e\u0648\u0627\u06cc \u0646\u0633\u062e\u0647\u200c\u0627\u06cc \u06a9\u0647 \u0647\u0646\u0648\u0632 \u0646\u0635\u0641\u0647\u200c\u06a9\u0627\u0631\u0647 \u0627\u0633\u062a\u060c \u062f\u0633\u062a \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0648\u0627\u0642\u0639\u06cc \u0628\u0631\u0633\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646\u062c\u0627\u0633\u062a \u06a9\u0647 <strong>Build Variant<\/strong> \u0628\u0647 \u06a9\u0645\u06a9\u0645\u0648\u0646 \u0645\u06cc\u0627\u062f. Build Variant \u0628\u0647\u062a \u0627\u062c\u0627\u0632\u0647 \u0645\u06cc\u062f\u0647 \u0627\u0632 \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647\u060c \u0686\u0646\u062f \u0646\u0633\u062e\u0647 \u0645\u062e\u062a\u0644\u0641 \u0628\u0633\u0627\u0632\u06cc\u061b \u0645\u062b\u0644\u0627\u064b \u06cc\u06a9 \u0646\u0633\u062e\u0647 \u0628\u0631\u0627\u06cc \u062a\u0648\u0633\u0639\u0647\u060c \u06cc\u06a9 \u0646\u0633\u062e\u0647 \u0628\u0631\u0627\u06cc \u062a\u0633\u062a \u0648 \u06cc\u06a9 \u0646\u0633\u062e\u0647 \u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0646\u0647\u0627\u06cc\u06cc. \u0647\u0631 \u06a9\u062f\u0648\u0645 \u0627\u0632 \u0627\u06cc\u0646 \u0646\u0633\u062e\u0647\u200c\u0647\u0627 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a\u060c \u0622\u062f\u0631\u0633 \u0633\u0631\u0648\u0631\u060c \u0622\u06cc\u06a9\u0648\u0646\u060c \u0646\u0627\u0645 \u0628\u0631\u0646\u0627\u0645\u0647 \u06cc\u0627 \u062d\u062a\u06cc \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc \u0645\u062a\u0641\u0627\u0648\u062a\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646\u060c \u0628\u062f\u0648\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0645\u062c\u0628\u0648\u0631 \u0628\u0634\u06cc \u0686\u0646\u062f \u067e\u0631\u0648\u0698\u0647 \u062c\u062f\u0627 \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0631\u0627 \u0628\u0647 Build Variant \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u06cc\u0645\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u062f\u0627\u062e\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u062f\u0648 \u0633\u0631\u0648\u0631 \u062f\u0627\u0631\u06cc. \u06cc\u06a9\u06cc \u0633\u0631\u0648\u0631 \u0627\u0635\u0644\u06cc \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0648\u0627\u0642\u0639\u06cc \u0627\u0632\u0634 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646 \u0648 \u06cc\u06a9\u06cc \u0647\u0645 \u0633\u0631\u0648\u0631 \u0622\u0632\u0645\u0627\u06cc\u0634\u06cc \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627 \u0647\u0631 \u0631\u0648\u0632 \u0631\u0648\u0634 \u062a\u063a\u06cc\u06cc\u0631 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u200c\u06a9\u0646\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0627\u0634\u062a\u0628\u0627\u0647\u06cc \u0646\u0633\u062e\u0647 \u0622\u0632\u0645\u0627\u06cc\u0634\u06cc \u0628\u0647 \u0633\u0631\u0648\u0631 \u0627\u0635\u0644\u06cc \u0648\u0635\u0644 \u0628\u0634\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0648\u0627\u0642\u0639\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u062e\u0631\u0627\u0628 \u0628\u0634\u0647. \u0628\u0631\u0639\u06a9\u0633\u060c \u0627\u06af\u0631 \u0646\u0633\u062e\u0647 \u0645\u0646\u062a\u0634\u0631\u0634\u062f\u0647 \u0628\u0647 \u0633\u0631\u0648\u0631 \u062a\u0633\u062a \u0648\u0635\u0644 \u0628\u0627\u0634\u0647\u060c \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0646\u0627\u0642\u0635 \u06cc\u0627 \u0627\u0634\u062a\u0628\u0627\u0647 \u0645\u06cc\u200c\u0628\u06cc\u0646\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062e\u0627\u0637\u0631 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u062a\u06cc\u0645\u200c\u0647\u0627\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc\u060c \u0645\u062d\u06cc\u0637\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0631\u0648 \u0627\u0632 \u0647\u0645 \u062c\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0646 \u0648 Build Variant \u062f\u0642\u06cc\u0642\u0627\u064b \u0628\u0631\u0627\u06cc \u0647\u0645\u06cc\u0646 \u06a9\u0627\u0631 \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0631\u0627\u06cc\u062c\u200c\u062a\u0631\u06cc\u0646 Variant\u0647\u0627<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0639\u0645\u0648\u0644\u0627\u064b \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627 \u062d\u062f\u0627\u0642\u0644 \u0633\u0647 Variant \u062f\u0627\u0631\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Development<\/strong> \u0646\u0633\u062e\u0647\u200c\u0627\u06cc\u0647 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627 \u0647\u0631 \u0631\u0648\u0632 \u0628\u0627\u0647\u0627\u0634 \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646. \u062a\u0648\u06cc \u0627\u06cc\u0646 \u0646\u0633\u062e\u0647 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0644\u0627\u06af\u200c\u0647\u0627 \u0641\u0639\u0627\u0644\u0647\u060c \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc \u062f\u06cc\u0628\u0627\u06af \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0646 \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647 \u0633\u0631\u0648\u0631 \u062a\u0633\u062a \u0648\u0635\u0644 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Staging<\/strong> \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0645\u0648\u0646 \u0646\u0633\u062e\u0647 \u0646\u0647\u0627\u06cc\u06cc\u0647\u060c \u0627\u0645\u0627 \u0647\u0646\u0648\u0632 \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0645\u0646\u062a\u0634\u0631 \u0646\u0634\u062f\u0647. \u062a\u06cc\u0645 \u062a\u0633\u062a \u0642\u0628\u0644 \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631\u060c \u0647\u0645\u0647 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627 \u0631\u0648 \u0631\u0648\u06cc \u0627\u06cc\u0646 \u0646\u0633\u062e\u0647 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Release<\/strong> \u0647\u0645\u0648\u0646 \u0646\u0633\u062e\u0647\u200c\u0627\u06cc\u0647 \u06a9\u0647 \u062f\u0627\u062e\u0644 Google Play \u0645\u0646\u062a\u0634\u0631 \u0645\u06cc\u0634\u0647. \u0627\u06cc\u0646 \u0646\u0633\u062e\u0647 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0633\u0631\u06cc\u0639\u200c\u062a\u0631\u0647\u060c \u0644\u0627\u06af\u200c\u0647\u0627\u06cc \u0627\u0636\u0627\u0641\u06cc \u062d\u0630\u0641 \u0634\u062f\u0646\u060c \u06a9\u062f\u0647\u0627 Obfuscate \u0634\u062f\u0646 \u0648 \u0641\u0642\u0637 \u0628\u0647 \u0633\u0631\u0648\u0631 \u0627\u0635\u0644\u06cc \u0648\u0635\u0644 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Build Type \u0628\u0627 Product Flavor \u0641\u0631\u0642 \u062f\u0627\u0631\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u062c\u0627\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u062e\u06cc\u0644\u06cc\u200c\u0647\u0627 \u0627\u0648\u0644 \u06a9\u0627\u0631 \u0627\u0634\u062a\u0628\u0627\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646\u060c \u062a\u0641\u0627\u0648\u062a \u0628\u06cc\u0646 <strong>Build Type<\/strong> \u0648 <strong>Product Flavor<\/strong> \u0647\u0633\u062a. <strong>Build Type<\/strong> \u0645\u0634\u062e\u0635 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0686\u0637\u0648\u0631\u06cc \u0633\u0627\u062e\u062a\u0647 \u0628\u0634\u0647. \u0645\u062b\u0644\u0627\u064b Debug \u06cc\u0627 Release.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 <strong>Product Flavor<\/strong> \u0645\u0634\u062e\u0635 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0627\u0635\u0644\u0627\u064b \u06a9\u062f\u0648\u0645 \u0646\u0633\u062e\u0647 \u0627\u0632 \u0628\u0631\u0646\u0627\u0645\u0647 \u0633\u0627\u062e\u062a\u0647 \u0628\u0634\u0647. \u0645\u062b\u0644\u0627\u064b \u0646\u0633\u062e\u0647 \u0631\u0627\u06cc\u06af\u0627\u0646\u060c \u0646\u0633\u062e\u0647 \u067e\u0648\u0644\u06cc \u06cc\u0627 \u0646\u0633\u062e\u0647 \u0645\u062e\u0635\u0648\u0635 \u06cc\u06a9 \u06a9\u0634\u0648\u0631. \u0641\u0631\u0636 \u06a9\u0646 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0647\u0645 \u0646\u0633\u062e\u0647 \u0631\u0627\u06cc\u06af\u0627\u0646 \u062f\u0627\u0631\u0647 \u0648 \u0647\u0645 \u0646\u0633\u062e\u0647 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc. \u0627\u06cc\u0646 \u062a\u0641\u0627\u0648\u062a \u0628\u0627 Product Flavor \u0645\u0634\u062e\u0635 \u0645\u06cc\u0634\u0647\u060c \u0646\u0647 Build Type. \u062f\u0631 \u0639\u0645\u0644\u060c \u0627\u06cc\u0646 \u062f\u0648 \u0645\u0641\u0647\u0648\u0645 \u0628\u0627 \u0647\u0645 \u062a\u0631\u06a9\u06cc\u0628 \u0645\u06cc\u0634\u0646 \u0648 Variant\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0631\u0648 \u0645\u06cc\u200c\u0633\u0627\u0632\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>freeDebug\nfreeRelease\n\nproDebug\nproRelease\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0639\u0646\u06cc \u0686\u0647\u0627\u0631 \u0646\u0633\u062e\u0647 \u0645\u062e\u062a\u0644\u0641 \u0627\u0632 \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0639\u0631\u06cc\u0641 Build Type<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0627\u062e\u0644 \u0641\u0627\u06cc\u0644 Gradle \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 Build Type\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0631\u0648 \u062a\u0639\u0631\u06cc\u0641 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>android {\n\n    buildTypes {\n\n        debug {\n\n            applicationIdSuffix = \".debug\"\n\n            versionNameSuffix = \"-DEBUG\"\n\n        }\n\n        release {\n\n            isMinifyEnabled = true\n\n        }\n\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">android<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">buildTypes<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">debug<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            applicationIdSuffix <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;.debug&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            versionNameSuffix <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;-DEBUG&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">release<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            isMinifyEnabled <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646\u062c\u0627 \u0646\u0633\u062e\u0647 Debug \u0628\u0627 \u06cc\u06a9 \u0634\u0646\u0627\u0633\u0647 \u0645\u062a\u0641\u0627\u0648\u062a \u0646\u0635\u0628 \u0645\u06cc\u0634\u0647. \u06cc\u0639\u0646\u06cc \u062d\u062a\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0646\u0633\u062e\u0647 \u0627\u0635\u0644\u06cc \u0648 \u0646\u0633\u062e\u0647 Debug \u0631\u0648 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0631\u0648\u06cc \u06cc\u06a9 \u06af\u0648\u0634\u06cc \u0646\u0635\u0628 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0639\u0631\u06cc\u0641 Product Flavor<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0641\u0631\u0636 \u06a9\u0646 \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc \u0646\u0633\u062e\u0647 \u0631\u0627\u06cc\u06af\u0627\u0646 \u0648 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0627\u0632 \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647 \u0628\u0633\u0627\u0632\u06cc.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>android {\n\n    flavorDimensions += \"version\"\n\n    productFlavors {\n\n        create(\"free\") {\n\n            dimension = \"version\"\n\n        }\n\n        create(\"pro\") {\n\n            dimension = \"version\"\n\n        }\n\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">android<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    flavorDimensions <\/span><span style=\"color: #D73A49\">+=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;version&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">productFlavors<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;free&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            dimension <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;version&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;pro&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            dimension <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;version&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0627\u0633\u062a\u0648\u062f\u06cc\u0648 \u062e\u0648\u062f\u0634 Variant\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0631\u0648 \u0645\u06cc\u200c\u0633\u0627\u0632\u0647 \u0648 \u0647\u0631 \u0628\u0627\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0645\u0634\u062e\u0635 \u06a9\u0646\u06cc \u062f\u0642\u06cc\u0642\u0627\u064b \u06a9\u062f\u0648\u0645 \u0646\u0633\u062e\u0647 Build \u0628\u0634\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0645\u062a\u0641\u0627\u0648\u062a \u0628\u0631\u0627\u06cc \u0647\u0631 Variant<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u062c\u0630\u0627\u0628\u200c\u062a\u0631\u06cc\u0646 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc Build Variant \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0647\u0631 \u0646\u0633\u062e\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0645\u062e\u0635\u0648\u0635 \u062e\u0648\u062f\u0634 \u0631\u0648 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u062f\u0627\u062e\u0644 \u0646\u0633\u062e\u0647 Debug \u0622\u062f\u0631\u0633 API \u0627\u06cc\u0646 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;test.gheimatban.com\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0644\u06cc \u062f\u0627\u062e\u0644 \u0646\u0633\u062e\u0647 Release \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647 \u0627\u06cc\u0646 \u0622\u062f\u0631\u0633 \u0648\u0635\u0644 \u0628\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;api.gheimatban.com\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627 \u0645\u062b\u0644\u0627\u064b \u062f\u0627\u062e\u0644 \u0646\u0633\u062e\u0647 Debug \u0647\u0645\u0647 Log\u0647\u0627 \u0641\u0639\u0627\u0644 \u0628\u0627\u0634\u0646\u060c \u0627\u0645\u0627 \u062f\u0627\u062e\u0644 Release \u0647\u06cc\u0686 \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u06cc \u062f\u0627\u062e\u0644 Logcat \u0646\u0648\u0634\u062a\u0647 \u0646\u0634\u0647. \u062d\u062a\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0627\u0633\u0645 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0647\u0645 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u06cc \u062a\u0627 \u0645\u0648\u0642\u0639 \u0646\u0635\u0628 \u0631\u0627\u062d\u062a \u062a\u0634\u062e\u06cc\u0635 \u0628\u062f\u06cc \u06a9\u062f\u0648\u0645 \u0646\u0633\u062e\u0647 \u0631\u0648 \u0627\u062c\u0631\u0627 \u06a9\u0631\u062f\u06cc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GheimatBan\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GheimatBan Debug\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Variant \u0645\u0646\u0627\u0633\u0628 \u0631\u0648 \u0627\u0646\u062a\u062e\u0627\u0628 \u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0627\u0644\u0627\u06cc Android Studio \u067e\u0646\u062c\u0631\u0647\u200c\u0627\u06cc \u0628\u0647 \u0646\u0627\u0645 <strong>Build Variants<\/strong> \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647. \u0627\u0632 \u0647\u0645\u0648\u0646\u062c\u0627 \u0645\u0634\u062e\u0635 \u0645\u06cc\u200c\u06a9\u0646\u06cc \u06a9\u0647 \u067e\u0631\u0648\u0698\u0647 \u0628\u0627 \u06a9\u062f\u0648\u0645 Variant \u0627\u062c\u0631\u0627 \u06cc\u0627 Build \u0628\u0634\u0647. \u0627\u06af\u0631 \u0631\u0648\u06cc Debug \u0628\u0627\u0634\u06cc\u060c \u0646\u0633\u062e\u0647 \u062a\u0648\u0633\u0639\u0647 \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647. \u0627\u06af\u0631 Release \u0631\u0648 \u0627\u0646\u062a\u062e\u0627\u0628 \u06a9\u0646\u06cc\u060c \u0647\u0645\u0648\u0646 \u0646\u0633\u062e\u0647\u200c\u0627\u06cc \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647 \u06a9\u0647 \u0622\u0645\u0627\u062f\u0647 \u0627\u0646\u062a\u0634\u0627\u0631 \u0631\u0648\u06cc Google Play \u0647\u0633\u062a. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062e\u0627\u0637\u0631 \u0642\u0628\u0644 \u0627\u0632 \u06af\u0631\u0641\u062a\u0646 \u0641\u0627\u06cc\u0644 APK \u06cc\u0627 AAB \u0647\u0645\u06cc\u0634\u0647 \u06cc\u06a9 \u0628\u0627\u0631 \u0686\u06a9 \u06a9\u0646 \u06a9\u0647 \u0627\u0634\u062a\u0628\u0627\u0647\u06cc \u0631\u0648\u06cc Debug \u0646\u0628\u0627\u0634\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Build Variant \u06cc\u06a9\u06cc \u0627\u0632 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc\u06cc\u0647 \u06a9\u0647 \u0627\u0632 \u0647\u0645\u0648\u0646 \u0631\u0648\u0632\u0647\u0627\u06cc \u0627\u0648\u0644 \u067e\u0631\u0648\u0698\u0647 \u0627\u0631\u0632\u0634\u0634 \u0631\u0648 \u0646\u0634\u0648\u0646 \u0645\u06cc\u062f\u0647. \u0628\u0647 \u062c\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0628\u0631\u0627\u06cc \u0647\u0631 \u0646\u0633\u062e\u0647 \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647 \u062c\u062f\u0627 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u060c \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0647\u0645\u0647 \u0646\u0633\u062e\u0647\u200c\u0647\u0627 \u0631\u0648 \u062f\u0627\u062e\u0644 \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc. \u0646\u0633\u062e\u0647 \u062a\u0648\u0633\u0639\u0647 \u0628\u0647 \u0633\u0631\u0648\u0631 \u062a\u0633\u062a \u0648\u0635\u0644 \u0628\u0634\u0647\u060c \u0646\u0633\u062e\u0647 \u0646\u0647\u0627\u06cc\u06cc \u0628\u0647 \u0633\u0631\u0648\u0631 \u0627\u0635\u0644\u06cc\u060c \u0646\u0633\u062e\u0647 \u0631\u0627\u06cc\u06af\u0627\u0646 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647 \u0648 \u0646\u0633\u062e\u0647 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0627\u0645\u06a9\u0627\u0646\u0627\u062a \u06a9\u0627\u0645\u0644 \u0631\u0648 \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0630\u0627\u0631\u0647. \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0627\u0632 Build Variant \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646\u060c \u0686\u0648\u0646 \u0647\u0645 \u0645\u062f\u06cc\u0631\u06cc\u062a \u067e\u0631\u0648\u0698\u0647 \u0631\u0648 \u0633\u0627\u062f\u0647\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u0647\u0645 \u0627\u062d\u062a\u0645\u0627\u0644 \u062e\u0637\u0627 \u0647\u0646\u06af\u0627\u0645 \u0627\u0646\u062a\u0634\u0627\u0631 \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f \u0631\u0648 \u0628\u0647 \u0634\u06a9\u0644 \u0645\u062d\u0633\u0648\u0633\u06cc \u06a9\u0627\u0647\u0634 \u0645\u06cc\u062f\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u0645<\/h3>\n\n\n\n<h1 class=\"wp-block-heading\">Signing<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0635\u0644\u0627\u064b \u0686\u0631\u0627 \u0628\u0627\u06cc\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 Sign \u06a9\u0646\u06cc\u0645\u061f<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"768\" height=\"1024\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-04-1-768x1024.avif\" alt=\"\" class=\"wp-image-6158\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-04-1-768x1024.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-04-1-225x300.avif 225w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-04-1.avif 1086w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u06cc\u06a9 \u0634\u0631\u06a9\u062a \u062e\u0648\u062f\u0631\u0648\u0633\u0627\u0632\u06cc \u0645\u0627\u0634\u06cc\u0646 \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0642\u0628\u0644 \u0627\u0632 \u0627\u06cc\u0646\u06a9\u0647 \u0645\u0627\u0634\u06cc\u0646 \u0627\u0632 \u06a9\u0627\u0631\u062e\u0627\u0646\u0647 \u062e\u0627\u0631\u062c \u0628\u0634\u0647\u060c \u06cc\u06a9 \u0634\u0645\u0627\u0631\u0647 \u0634\u0627\u0633\u06cc \u0648 \u0645\u0647\u0631 \u06a9\u0627\u0631\u062e\u0627\u0646\u0647 \u0631\u0648\u06cc \u0627\u0648\u0646 \u062b\u0628\u062a \u0645\u06cc\u0634\u0647. \u0627\u0632 \u0627\u0648\u0646 \u0644\u062d\u0638\u0647 \u0628\u0647 \u0628\u0639\u062f\u060c \u0647\u0645\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u062a\u0634\u062e\u06cc\u0635 \u0628\u062f\u0646 \u0627\u06cc\u0646 \u0645\u0627\u0634\u06cc\u0646 \u0648\u0627\u0642\u0639\u0627\u064b \u062a\u0648\u0633\u0637 \u0647\u0645\u0648\u0646 \u0634\u0631\u06a9\u062a \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647 \u06cc\u0627 \u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u06cc\u0646 \u0627\u062a\u0641\u0627\u0642 \u062f\u0631 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0647\u0645 \u0645\u06cc\u0641\u062a\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0631 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646\u06cc \u06a9\u0647 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0646\u0635\u0628 \u0645\u06cc\u0634\u0647\u060c \u0628\u0627\u06cc\u062f \u06cc\u06a9 <strong>\u0627\u0645\u0636\u0627\u06cc \u062f\u06cc\u062c\u06cc\u062a\u0627\u0644 (Digital Signature)<\/strong> \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u0627\u06cc\u0646 \u0627\u0645\u0636\u0627 \u0645\u0634\u062e\u0635 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u0648\u0633\u0637 \u0686\u0647 \u06a9\u0633\u06cc \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647 \u0648 \u0622\u06cc\u0627 \u0627\u0632 \u0632\u0645\u0627\u0646 \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0646 \u062a\u0627 \u0627\u0644\u0627\u0646 \u06a9\u0633\u06cc \u0641\u0627\u06cc\u0644\u0634 \u0631\u0648 \u062f\u0633\u062a\u06a9\u0627\u0631\u06cc \u06a9\u0631\u062f\u0647 \u06cc\u0627 \u0646\u0647. \u0627\u06af\u0631 \u0641\u0627\u06cc\u0644 APK \u06cc\u0627 AAB \u0627\u0645\u0636\u0627 \u0646\u0634\u062f\u0647 \u0628\u0627\u0634\u0647\u060c \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0627\u0635\u0644\u0627\u064b \u0627\u062c\u0627\u0632\u0647 \u0646\u0635\u0628\u0634 \u0631\u0648 \u0646\u0645\u06cc\u062f\u0647. \u067e\u0633 Signing \u0641\u0642\u0637 \u06cc\u06a9 \u0645\u0631\u062d\u0644\u0647 \u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u06cc\u0633\u062a\u061b \u0628\u0644\u06a9\u0647 \u0628\u062e\u0634\u06cc \u0627\u0632 \u0633\u06cc\u0633\u062a\u0645 \u0627\u0645\u0646\u06cc\u062a\u06cc \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0645\u0636\u0627\u06cc \u062f\u06cc\u062c\u06cc\u062a\u0627\u0644 \u06cc\u0639\u0646\u06cc \u0686\u06cc\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u06cc\u0644\u06cc\u200c\u0647\u0627 \u0648\u0642\u062a\u06cc \u0627\u0633\u0645 \u0627\u0645\u0636\u0627\u06cc \u062f\u06cc\u062c\u06cc\u062a\u0627\u0644 \u0631\u0648 \u0645\u06cc\u200c\u0634\u0646\u0648\u0646\u060c \u0641\u06a9\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646 \u06cc\u0639\u0646\u06cc \u0627\u0633\u0645 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633 \u062f\u0627\u062e\u0644 \u0641\u0627\u06cc\u0644 \u0646\u0648\u0634\u062a\u0647 \u0645\u06cc\u0634\u0647. \u0627\u0645\u0627 \u0648\u0627\u0642\u0639\u06cc\u062a \u06a9\u0627\u0645\u0644\u0627\u064b \u0641\u0631\u0642 \u062f\u0627\u0631\u0647. \u0627\u0645\u0636\u0627\u06cc \u062f\u06cc\u062c\u06cc\u062a\u0627\u0644 \u0628\u0631 \u067e\u0627\u06cc\u0647 \u0631\u0645\u0632\u0646\u06af\u0627\u0631\u06cc \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647. \u062a\u0648 \u06cc\u06a9 <strong>Key<\/strong> \u062e\u0635\u0648\u0635\u06cc \u062f\u0627\u0631\u06cc \u06a9\u0647 \u0641\u0642\u0637 \u0628\u0627\u06cc\u062f \u062f\u0633\u062a \u062e\u0648\u062f\u062a \u0628\u0627\u0634\u0647. \u0648\u0642\u062a\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 Build \u0645\u06cc\u200c\u06a9\u0646\u06cc\u060c \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0627\u0648\u0646 Key \u06cc\u06a9 \u0627\u0645\u0636\u0627\u06cc \u0631\u0645\u0632\u0646\u06af\u0627\u0631\u06cc\u200c\u0634\u062f\u0647 \u0631\u0648\u06cc \u0641\u0627\u06cc\u0644 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0628\u0639\u062f \u0647\u0631 \u0628\u0627\u0631 \u06a9\u0647 \u06af\u0648\u0634\u06cc \u0628\u062e\u0648\u0627\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0646\u0635\u0628 \u06cc\u0627 \u0622\u067e\u062f\u06cc\u062a \u06a9\u0646\u0647\u060c \u0627\u06cc\u0646 \u0627\u0645\u0636\u0627 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u062d\u062a\u06cc \u06cc\u06a9 \u0628\u0627\u06cc\u062a \u0627\u0632 \u0641\u0627\u06cc\u0644 APK \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u0647\u060c \u0627\u0645\u0636\u0627 \u062f\u06cc\u06af\u0647 \u0645\u0639\u062a\u0628\u0631 \u0646\u06cc\u0633\u062a \u0648 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u0634\u0647 \u0641\u0627\u06cc\u0644 \u062f\u0633\u062a\u06a9\u0627\u0631\u06cc \u0634\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0639\u0646\u06cc Signing \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0634\u0646\u0627\u0633\u0627\u06cc\u06cc \u0633\u0627\u0632\u0646\u062f\u0647 \u0646\u06cc\u0633\u062a\u061b \u0628\u0644\u06a9\u0647 \u062a\u0636\u0645\u06cc\u0646 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0641\u0627\u06cc\u0644 \u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u0648\u0646 \u0686\u06cc\u0632\u06cc\u0647 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633 \u0645\u0646\u062a\u0634\u0631 \u06a9\u0631\u062f\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0631\u0627 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0627\u06cc\u0646\u200c\u0642\u062f\u0631 \u0631\u0648\u06cc Signing \u062d\u0633\u0627\u0633\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0646\u0633\u062e\u0647 \u06f1.\u06f0 \u0628\u0631\u0646\u0627\u0645\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0631\u0648 \u0645\u0646\u062a\u0634\u0631 \u06a9\u0631\u062f\u06cc \u0648 \u0647\u0632\u0627\u0631\u0627\u0646 \u0646\u0641\u0631 \u0646\u0635\u0628\u0634 \u06a9\u0631\u062f\u0646. \u0634\u0634 \u0645\u0627\u0647 \u0628\u0639\u062f \u0646\u0633\u062e\u0647 \u06f2.\u06f0 \u0622\u0645\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647. \u062d\u0627\u0644\u0627 \u062a\u0635\u0648\u0631 \u06a9\u0646 \u06cc\u06a9 \u0646\u0641\u0631 \u0641\u0627\u06cc\u0644 APK \u062e\u0648\u062f\u0634 \u0631\u0648 \u0628\u0627 \u0647\u0645\u0648\u0646 Package Name \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u0647 \u0648 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0647\u0645 \u0627\u0634\u062a\u0628\u0627\u0647\u06cc \u0627\u0648\u0646 \u0646\u0633\u062e\u0647 \u0631\u0648 \u0646\u0635\u0628 \u06a9\u0646\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0641\u0642\u0637 Package Name \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0631\u062f\u060c \u0647\u0631 \u06a9\u0633\u06cc \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0633\u062a \u062e\u0648\u062f\u0634 \u0631\u0627 \u062c\u0627\u06cc \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0627\u0635\u0644\u06cc \u062c\u0627 \u0628\u0632\u0646\u062f \u0648 \u0646\u0633\u062e\u0647 \u062c\u0639\u0644\u06cc \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u062f. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062e\u0627\u0637\u0631 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0639\u0644\u0627\u0648\u0647 \u0628\u0631 Package Name\u060c \u0627\u0645\u0636\u0627\u06cc \u062f\u06cc\u062c\u06cc\u062a\u0627\u0644 \u0631\u0627 \u0647\u0645 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u062f. \u0627\u06af\u0631 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0628\u0627 \u0647\u0645\u0627\u0646 \u06a9\u0644\u06cc\u062f\u06cc \u0627\u0645\u0636\u0627 \u0634\u062f\u0647 \u0628\u0627\u0634\u062f \u06a9\u0647 \u0646\u0633\u062e\u0647 \u0642\u0628\u0644\u06cc \u0628\u0627 \u0622\u0646 \u0627\u0645\u0636\u0627 \u0634\u062f\u0647 \u0628\u0648\u062f\u060c \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f \u0627\u06cc\u0646 \u0647\u0645\u0627\u0646 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0627\u0633\u062a \u0648 \u0627\u062c\u0627\u0632\u0647 Update \u0645\u06cc\u200c\u062f\u0647\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0627\u06af\u0631 \u0627\u0645\u0636\u0627 \u0641\u0631\u0642 \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u062f\u060c \u062d\u062a\u06cc \u0627\u06af\u0631 \u062a\u0645\u0627\u0645 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627 \u0648 Package Name \u06cc\u06a9\u0633\u0627\u0646 \u0628\u0627\u0634\u0646\u062f\u060c \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0622\u0646 \u0631\u0627 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u062a\u0641\u0627\u0648\u062a \u0645\u06cc\u200c\u062f\u0627\u0646\u062f \u0648 \u0627\u062c\u0627\u0632\u0647 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u0634\u062f\u0646 \u0646\u0633\u062e\u0647 \u0642\u0628\u0644\u06cc \u0631\u0627 \u0646\u0645\u06cc\u200c\u062f\u0647\u062f. \u0627\u06cc\u0646 \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u0644\u0627\u06cc\u0647\u200c\u0647\u0627\u06cc \u0627\u0645\u0646\u06cc\u062a\u06cc \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0627\u0633\u062a.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Debug Key \u0648 Release Key<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u0627\u0648\u0644\u06cc\u0646 \u067e\u0631\u0648\u0698\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u062a \u0631\u0648 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u060c \u0627\u062d\u062a\u0645\u0627\u0644\u0627\u064b \u0647\u06cc\u0686 Key\u0627\u06cc \u0646\u0633\u0627\u062e\u062a\u06cc. \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u062f\u0648\u0646 \u0645\u0634\u06a9\u0644 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0646\u0635\u0628 \u0645\u06cc\u0634\u0647. \u062f\u0644\u06cc\u0644\u0634 \u0627\u06cc\u0646\u0647 \u06a9\u0647 Android Studio \u0628\u0647\u200c\u0635\u0648\u0631\u062a \u062e\u0648\u062f\u06a9\u0627\u0631 \u06cc\u06a9 <strong>Debug Key<\/strong> \u0628\u0631\u0627\u06cc \u062a\u0648\u0633\u0639\u0647 \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06cc\u0646 \u06a9\u0644\u06cc\u062f \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0632\u0645\u0627\u0646 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u06cc\u0647 \u0648 \u0647\u06cc\u0686\u200c\u0648\u0642\u062a \u0646\u0628\u0627\u06cc\u062f \u0628\u0627\u0647\u0627\u0634 \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u0646\u062a\u0634\u0631 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0631\u0648 \u062f\u0627\u062e\u0644 Google Play \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u06cc\u060c \u0628\u0627\u06cc\u062f \u06cc\u06a9 <strong>Release Key<\/strong> \u0645\u062e\u0635\u0648\u0635 \u062e\u0648\u062f\u062a \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc. \u0627\u0632 \u0627\u0648\u0646 \u0644\u062d\u0638\u0647 \u0628\u0647 \u0628\u0639\u062f\u060c \u062a\u0645\u0627\u0645 \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u0622\u06cc\u0646\u062f\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627\u06cc\u062f \u0628\u0627 \u0647\u0645\u06cc\u0646 Key \u0627\u0645\u0636\u0627 \u0628\u0634\u0646.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Keystore \u0686\u06cc\u0633\u062a\u061f<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"896\" height=\"1024\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-05-1-896x1024.avif\" alt=\"\" class=\"wp-image-6159\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-05-1-896x1024.avif 896w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-05-1-262x300.avif 262w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-05-1-768x878.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-05-1.avif 1173w\" sizes=\"(max-width: 896px) 100vw, 896px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0633\u0624\u0627\u0644 \u0645\u0647\u0645 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0627\u06cc\u0646 Key \u06a9\u062c\u0627 \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0645\u06cc\u0634\u0647\u061f<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0641\u0627\u06cc\u0644 \u0645\u062e\u0635\u0648\u0635\u06cc \u0628\u0647 \u0646\u0627\u0645 <strong>Keystore<\/strong> \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Keystore \u0645\u062b\u0644 \u06cc\u06a9 \u06af\u0627\u0648\u0635\u0646\u062f\u0648\u0642\u0647 \u06a9\u0647 \u06a9\u0644\u06cc\u062f\u0647\u0627\u06cc \u0631\u0645\u0632\u0646\u06af\u0627\u0631\u06cc \u062f\u0627\u062e\u0644\u0634 \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0645\u06cc\u0634\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0627\u062e\u0644 \u0627\u06cc\u0646 \u0641\u0627\u06cc\u0644 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0647\u0645\u06cc \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647\u061b \u0645\u062b\u0644:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u06a9\u0644\u06cc\u062f \u062e\u0635\u0648\u0635\u06cc<\/li>\n\n\n\n<li>Certificate<\/li>\n\n\n\n<li>Alias<\/li>\n\n\n\n<li>\u0631\u0645\u0632 \u0639\u0628\u0648\u0631 Keystore<\/li>\n\n\n\n<li>\u0631\u0645\u0632 \u0639\u0628\u0648\u0631 \u062e\u0648\u062f Key<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0648\u0627\u0642\u0639 \u0648\u0642\u062a\u06cc \u0645\u06cc\u200c\u06af\u06cc \u00ab\u06a9\u0644\u06cc\u062f \u0628\u0631\u0646\u0627\u0645\u0647\u00bb\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0645\u0646\u0638\u0648\u0631\u062a \u0647\u0645\u0648\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u06cc\u0647 \u06a9\u0647 \u062f\u0627\u062e\u0644 \u0641\u0627\u06cc\u0644 Keystore \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u06af\u0631 Keystore \u0631\u0648 \u06af\u0645 \u06a9\u0646\u06cc\u0645 \u0686\u0647 \u0627\u062a\u0641\u0627\u0642\u06cc \u0645\u06cc\u0641\u062a\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06cc\u06a9\u06cc \u0627\u0632 \u0628\u0632\u0631\u06af\u200c\u062a\u0631\u06cc\u0646 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc\u06cc\u0647 \u06a9\u0647 \u0628\u0639\u0636\u06cc \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647\u200c\u0647\u0627 \u0645\u0631\u062a\u06a9\u0628 \u0645\u06cc\u0634\u0646. \u0641\u0631\u0636 \u06a9\u0646 \u0627\u0645\u0631\u0648\u0632 \u0646\u0633\u062e\u0647 \u06f1.\u06f0 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0631\u0648 \u0645\u0646\u062a\u0634\u0631 \u06a9\u0631\u062f\u06cc. \u06cc\u06a9 \u0633\u0627\u0644 \u0628\u0639\u062f \u0646\u0633\u062e\u0647 \u06f2.\u06f0 \u0622\u0645\u0627\u062f\u0647 \u0634\u062f\u0647\u060c \u0627\u0645\u0627 \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u0634\u06cc \u0641\u0627\u06cc\u0644 Keystore \u0631\u0648 \u067e\u0627\u06a9 \u06a9\u0631\u062f\u06cc \u0648 \u0647\u06cc\u0686 \u0646\u0633\u062e\u0647 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u0647\u0645 \u0646\u062f\u0627\u0631\u06cc. \u062d\u0627\u0644\u0627 \u0686\u06cc \u0645\u06cc\u0634\u0647\u061f<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u06cc\u06af\u0647 \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0631\u0648 \u0628\u0627 \u0647\u0645\u0648\u0646 \u0627\u0645\u0636\u0627 \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u06cc. \u06cc\u0639\u0646\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0641\u0639\u0644\u06cc \u062f\u06cc\u06af\u0647 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0631\u0648 \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 Update \u062f\u0631\u06cc\u0627\u0641\u062a \u0646\u0645\u06cc\u200c\u06a9\u0646\u0646. \u062f\u0631 \u06af\u0630\u0634\u062a\u0647 \u0627\u06cc\u0646 \u0627\u062a\u0641\u0627\u0642 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0641\u0627\u062c\u0639\u0647 \u0628\u0648\u062f \u0648 \u0628\u0639\u0636\u06cc \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647\u200c\u0647\u0627 \u0645\u062c\u0628\u0648\u0631 \u0645\u06cc\u200c\u0634\u062f\u0646 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u06a9\u0627\u0645\u0644\u0627\u064b \u062c\u062f\u06cc\u062f \u0628\u0627 Package Name \u062c\u062f\u06cc\u062f \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0631\u0648\u0632\u0647 Google Play \u0642\u0627\u0628\u0644\u06cc\u062a\u06cc \u0628\u0647 \u0646\u0627\u0645 <strong>Play App Signing<\/strong> \u0627\u0631\u0627\u0626\u0647 \u06a9\u0631\u062f\u0647 \u06a9\u0647 \u0628\u062e\u0634 \u0632\u06cc\u0627\u062f\u06cc \u0627\u0632 \u0627\u06cc\u0646 \u0631\u06cc\u0633\u06a9 \u0631\u0648 \u06a9\u0645 \u06a9\u0631\u062f\u0647\u060c \u0627\u0645\u0627 \u0647\u0645\u0686\u0646\u0627\u0646 \u0627\u0632 \u062f\u0633\u062a \u062f\u0627\u062f\u0646 Keystore \u06cc\u0627 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0631\u0628\u0648\u0637 \u0628\u0647\u0634 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062f\u0631\u062f\u0633\u0631\u0647\u0627\u06cc \u062c\u062f\u06cc \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0647. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062e\u0627\u0637\u0631\u060c \u0627\u0632 \u0647\u0645\u0648\u0646 \u0631\u0648\u0632 \u0627\u0648\u0644 \u0628\u0627\u06cc\u062f \u0686\u0646\u062f \u0646\u0633\u062e\u0647 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646 \u0627\u0645\u0646 \u0627\u0632 Keystore \u062a\u0647\u06cc\u0647 \u06a9\u0646\u06cc \u0648 \u062f\u0631 \u0645\u062d\u0644\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Android Studio \u0686\u0637\u0648\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 Sign \u0645\u06cc\u200c\u06a9\u0646\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u0622\u0645\u0627\u062f\u0647 \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0627\u0634\u06cc\u060c \u0627\u0632 \u0645\u0646\u0648\u06cc Build \u06af\u0632\u06cc\u0646\u0647 \u0633\u0627\u062e\u062a \u0646\u0633\u062e\u0647 Release \u0631\u0648 \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u06cc\u200c\u06a9\u0646\u06cc. \u062f\u0631 \u0645\u0631\u0627\u062d\u0644 \u0628\u0639\u062f\u06cc\u060c Android Studio \u0627\u0632\u062a \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0632\u06cc\u0631 \u0631\u0648 \u0645\u06cc\u200c\u062e\u0648\u0627\u062f:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u0641\u0627\u06cc\u0644 Keystore<\/li>\n\n\n\n<li>\u0631\u0645\u0632 Keystore<\/li>\n\n\n\n<li>Alias<\/li>\n\n\n\n<li>\u0631\u0645\u0632 Alias<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 \u0648\u0627\u0631\u062f \u06a9\u0631\u062f\u0646 \u0627\u06cc\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627 \u0647\u0645\u0627\u0646 \u06a9\u0644\u06cc\u062f \u0627\u0645\u0636\u0627 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0641\u0627\u06cc\u0644 \u0646\u0647\u0627\u06cc\u06cc APK \u06cc\u0627 AAB \u0633\u0627\u062e\u062a\u0647 \u062e\u0648\u0627\u0647\u062f \u0634\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0627\u0634\u062a\u0628\u0627\u0647 \u0628\u0627\u0634\u0646\u062f\u060c Build \u0627\u0646\u062c\u0627\u0645 \u0646\u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0645\u0636\u0627\u06cc \u062e\u0648\u062f\u06a9\u0627\u0631 \u062f\u0631 Gradle<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0646\u0645\u06cc\u200c\u062e\u0648\u0627\u0646 \u0647\u0631 \u0628\u0627\u0631 \u0645\u0648\u0642\u0639 Build \u06a9\u0631\u062f\u0646\u060c \u0631\u0645\u0632\u0647\u0627 \u0631\u0648 \u062f\u0633\u062a\u06cc \u0648\u0627\u0631\u062f \u06a9\u0646\u0646. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062e\u0627\u0637\u0631 \u0627\u0637\u0644\u0627\u0639\u0627\u062a Signing \u062f\u0627\u062e\u0644 Gradle \u062a\u0639\u0631\u06cc\u0641 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0645\u0648\u0646\u0647 \u0633\u0627\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>android {\n\n    signingConfigs {\n\n        create(\"release\") {\n\n            storeFile = file(\"release.jks\")\n\n            storePassword = \"******\"\n\n            keyAlias = \"gheimatban\"\n\n            keyPassword = \"******\"\n\n        }\n\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">android<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">signingConfigs<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;release&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            storeFile <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">file<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;release.jks&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            storePassword <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;******&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            keyAlias <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;gheimatban&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            keyPassword <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;******&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f Build Type \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 Release \u0627\u0632 \u0647\u0645\u06cc\u0646 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>buildTypes {\n\n    release {\n\n        signingConfig = signingConfigs.getByName(\"release\")\n\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">buildTypes<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">release<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        signingConfig <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> signingConfigs.<\/span><span style=\"color: #6F42C1\">getByName<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;release&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0644\u0628\u062a\u0647 \u062f\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0647\u06cc\u0686\u200c\u0648\u0642\u062a \u0631\u0645\u0632\u0647\u0627 \u062f\u0627\u062e\u0644 \u06a9\u062f \u0646\u0648\u0634\u062a\u0647 \u0646\u0645\u06cc\u200c\u0634\u0646. \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u0632 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc \u0645\u062d\u0644\u06cc\u060c Environment Variable\u0647\u0627 \u06cc\u0627 \u0633\u06cc\u0633\u062a\u0645 CI\/CD \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646 \u062a\u0627 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u0648\u0627\u0631\u062f \u0645\u062e\u0632\u0646 Git \u0646\u0634\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0622\u06cc\u0627 \u0645\u06cc\u0634\u0647 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0627 \u06a9\u0644\u06cc\u062f \u062c\u062f\u06cc\u062f \u0645\u0646\u062a\u0634\u0631 \u06a9\u0631\u062f\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0646\u0648\u0632 \u0645\u0646\u062a\u0634\u0631 \u0646\u0634\u062f\u0647\u060c \u0628\u0644\u0647. \u0647\u0631 \u0632\u0645\u0627\u0646 \u0628\u062e\u0648\u0627\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc Keystore \u0631\u0648 \u0639\u0648\u0636 \u06a9\u0646\u06cc. \u0627\u0645\u0627 \u0628\u0639\u062f \u0627\u0632 \u0627\u06cc\u0646\u06a9\u0647 \u0646\u0633\u062e\u0647 \u0627\u0648\u0644 \u0645\u0646\u062a\u0634\u0631 \u0634\u062f \u0648 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0627\u0648\u0646 \u0631\u0648 \u0646\u0635\u0628 \u06a9\u0631\u062f\u0646\u060c \u062f\u0627\u0633\u062a\u0627\u0646 \u06a9\u0627\u0645\u0644\u0627\u064b \u0641\u0631\u0642 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u0632 \u0627\u0648\u0646 \u0644\u062d\u0638\u0647 \u0628\u0647 \u0628\u0639\u062f\u060c \u062a\u0645\u0627\u0645 \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u0628\u0639\u062f\u06cc \u0628\u0627\u06cc\u062f \u0628\u0627 \u0647\u0645\u0627\u0646 \u06a9\u0644\u06cc\u062f \u0627\u0645\u0636\u0627 \u0628\u0634\u0646\u061b \u0648\u06af\u0631\u0646\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0627\u0648\u0646\u200c\u0647\u0627 \u0631\u0648 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0647\u0645\u0648\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0645\u06cc\u200c\u0634\u0646\u0627\u0633\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062e\u0627\u0637\u0631\u060c Keystore \u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0631\u0632\u0634\u0645\u0646\u062f\u062a\u0631\u06cc\u0646 \u062f\u0627\u0631\u0627\u06cc\u06cc\u200c\u0647\u0627\u06cc \u0647\u0631 \u067e\u0631\u0648\u0698\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u0647. \u0627\u06af\u0631 \u0633\u0648\u0631\u0633 \u067e\u0631\u0648\u0698\u0647 \u0631\u0648 \u0627\u0632 \u062f\u0633\u062a \u0628\u062f\u06cc\u060c \u0634\u0627\u06cc\u062f \u0628\u0627 \u062f\u0627\u0634\u062a\u0646 \u0646\u0633\u062e\u0647 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646 \u0628\u062a\u0648\u0646\u06cc \u062f\u0648\u0628\u0627\u0631\u0647 \u0628\u0633\u0627\u0632\u06cc\u0634\u061b \u0627\u0645\u0627 \u0627\u06af\u0631 Keystore \u0631\u0648 \u0627\u0632 \u062f\u0633\u062a \u0628\u062f\u06cc\u060c \u0645\u0645\u06a9\u0646\u0647 \u0627\u0645\u06a9\u0627\u0646 \u0627\u0646\u062a\u0634\u0627\u0631 \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u0628\u0639\u062f\u06cc \u0628\u0631\u0627\u06cc \u0647\u0645\u0627\u0646 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0631\u0648 \u0627\u0632 \u062f\u0633\u062a \u0628\u062f\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Play App Signing \u062f\u0642\u06cc\u0642\u0627\u064b \u0686\u0647 \u0645\u0634\u06a9\u0644\u06cc \u0631\u0648 \u062d\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06af\u0648\u06af\u0644 \u0686\u0646\u062f \u0633\u0627\u0644\u06cc\u0647 \u0642\u0627\u0628\u0644\u06cc\u062a\u06cc \u0628\u0647 \u0646\u0627\u0645 <strong>Play App Signing<\/strong> \u0631\u0648 \u0645\u0639\u0631\u0641\u06cc \u06a9\u0631\u062f\u0647 \u062a\u0627 \u0645\u0633\u0626\u0648\u0644\u06cc\u062a \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u06a9\u0644\u06cc\u062f \u0627\u0635\u0644\u06cc \u062a\u0627 \u062d\u062f \u0632\u06cc\u0627\u062f\u06cc \u0627\u0632 \u062f\u0648\u0634 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0628\u0631\u062f\u0627\u0634\u062a\u0647 \u0628\u0634\u0647. \u062f\u0631 \u0627\u06cc\u0646 \u0631\u0648\u0634\u060c \u0627\u0648\u0644\u06cc\u0646 \u0628\u0627\u0631 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0645\u0646\u062a\u0634\u0631 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u060c \u06a9\u0644\u06cc\u062f \u0627\u0635\u0644\u06cc \u0627\u0645\u0636\u0627 \u0646\u0632\u062f \u06af\u0648\u06af\u0644 \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0645\u06cc\u0634\u0647. \u0628\u0639\u062f \u0627\u0632 \u0627\u0648\u0646\u060c \u062a\u0648 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f \u0631\u0648 \u0628\u0627 \u06cc\u06a9 <strong>Upload Key<\/strong> \u0627\u0645\u0636\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc \u0648 \u06af\u0648\u06af\u0644 \u0642\u0628\u0644 \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631\u060c \u0641\u0627\u06cc\u0644 \u0631\u0648 \u0628\u0627 \u06a9\u0644\u06cc\u062f \u0627\u0635\u0644\u06cc \u062f\u0648\u0628\u0627\u0631\u0647 \u0627\u0645\u0636\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0632\u06cc\u062a\u0634 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0627\u06af\u0631 Upload Key \u0631\u0648 \u06af\u0645 \u06a9\u0646\u06cc\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u0645\u06a9\u0627\u0646 \u0628\u0627\u0632\u06cc\u0627\u0628\u06cc \u06cc\u0627 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u06a9\u0631\u062f\u0646\u0634 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647\u061b \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u062f\u0631 \u0631\u0648\u0634 \u0642\u062f\u06cc\u0645\u06cc\u060c \u06af\u0645 \u0634\u062f\u0646 \u06a9\u0644\u06cc\u062f \u0627\u0635\u0644\u06cc \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0628\u0647 \u0645\u0639\u0646\u06cc \u067e\u0627\u06cc\u0627\u0646 \u0627\u0645\u06a9\u0627\u0646 \u0627\u0646\u062a\u0634\u0627\u0631 \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f \u0628\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0644\u0628\u062a\u0647 \u0627\u06cc\u0646 \u0628\u0647 \u0645\u0639\u0646\u06cc \u0628\u06cc\u200c\u0627\u0647\u0645\u06cc\u062a \u0634\u062f\u0646 \u0627\u0645\u0646\u06cc\u062a \u06a9\u0644\u06cc\u062f\u0647\u0627 \u0646\u06cc\u0633\u062a. \u0647\u0645\u0686\u0646\u0627\u0646 \u0628\u0627\u06cc\u062f \u0647\u0645 Keystore \u0648 \u0647\u0645 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0631\u0628\u0648\u0637 \u0628\u0647\u0634 \u0631\u0648 \u0628\u0627 \u062f\u0642\u062a \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u06a9\u0646\u06cc\u060c \u0686\u0648\u0646 \u0627\u0645\u0646\u06cc\u062a \u062d\u0633\u0627\u0628 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0648 \u0641\u0631\u0622\u06cc\u0646\u062f \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647 \u0627\u0648\u0646\u200c\u0647\u0627 \u0648\u0627\u0628\u0633\u062a\u0647 \u0627\u0633\u062a.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Signing \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u0628\u062e\u0634\u200c\u0647\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u0647 \u0648 \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0646\u0635\u0628 \u0634\u062f\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u06cc\u0633\u062a. \u0627\u0645\u0636\u0627\u06cc \u062f\u06cc\u062c\u06cc\u062a\u0627\u0644 \u0647\u0648\u06cc\u062a \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0631\u0648 \u0645\u0634\u062e\u0635 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u062c\u0644\u0648\u06cc \u062f\u0633\u062a\u06a9\u0627\u0631\u06cc \u0641\u0627\u06cc\u0644 \u0631\u0648 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647 \u0648 \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0645\u0637\u0645\u0626\u0646 \u0628\u0627\u0634\u0647 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0648\u0627\u0642\u0639\u0627\u064b \u0627\u062f\u0627\u0645\u0647 \u0647\u0645\u0648\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0642\u0628\u0644\u06cc\u0647. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644\u060c \u0641\u0627\u06cc\u0644 Keystore \u0648 \u06a9\u0644\u06cc\u062f\u0647\u0627\u06cc \u062f\u0627\u062e\u0644 \u0627\u0648\u0646 \u0627\u0632 \u0628\u0627\u0627\u0631\u0632\u0634\u200c\u062a\u0631\u06cc\u0646 \u062f\u0627\u0631\u0627\u06cc\u06cc\u200c\u0647\u0627\u06cc \u0647\u0631 \u067e\u0631\u0648\u0698\u0647 \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0646 \u0648 \u0628\u0627\u06cc\u062f \u0645\u062b\u0644 \u0631\u0645\u0632 \u062d\u0633\u0627\u0628 \u0628\u0627\u0646\u06a9\u06cc \u0627\u0632\u0634\u0648\u0646 \u0645\u062d\u0627\u0641\u0638\u062a \u06a9\u0631\u062f. \u0648\u0642\u062a\u06cc \u0645\u0641\u0647\u0648\u0645 Signing \u0631\u0648 \u062e\u0648\u0628 \u0628\u0641\u0647\u0645\u06cc\u060c \u062e\u06cc\u0644\u06cc \u0631\u0627\u062d\u062a\u200c\u062a\u0631 \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u0634\u06cc \u0686\u0631\u0627 \u06af\u0648\u06af\u0644 \u0631\u0648\u06cc \u0627\u0645\u0646\u06cc\u062a \u0641\u0631\u0622\u06cc\u0646\u062f \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u06cc\u0646\u200c\u0642\u062f\u0631 \u062d\u0633\u0627\u0633\u0647 \u0648 \u0686\u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u062f\u0631\u0633\u062a \u06a9\u0644\u06cc\u062f\u0647\u0627 \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0633\u0626\u0648\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc \u0645\u0647\u0645 \u0647\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u200c\u0648\u06cc\u06a9\u0645<\/h3>\n\n\n\n<h1 class=\"wp-block-heading\">ProGuard<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0635\u0644\u0627\u064b ProGuard \u0686\u0647 \u0645\u0634\u06a9\u0644\u06cc \u0631\u0648 \u062d\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u0631\u0648\u06cc \u067e\u0631\u0648\u0698\u0647\u200c\u0627\u06cc \u0645\u062b\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0686\u0646\u062f \u0645\u0627\u0647 \u06cc\u0627 \u0686\u0646\u062f \u0633\u0627\u0644 \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u060c \u06a9\u0645\u200c\u06a9\u0645 \u062d\u062c\u0645 \u06a9\u062f\u0647\u0627 \u0632\u06cc\u0627\u062f \u0645\u06cc\u0634\u0647. \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u0634\u0646\u060c \u06a9\u0644\u0627\u0633\u200c\u0647\u0627\u06cc \u0632\u06cc\u0627\u062f\u06cc \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0646 \u0648 \u0628\u062e\u0634\u06cc \u0627\u0632 \u06a9\u062f\u0647\u0627 \u0647\u0645 \u0628\u0647 \u0645\u0631\u0648\u0631 \u0628\u0644\u0627\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u0634\u0646. \u062f\u0631 \u0646\u0647\u0627\u06cc\u062a\u060c \u0648\u0642\u062a\u06cc \u0646\u0633\u062e\u0647 Release \u0631\u0648 Build \u0645\u06cc\u200c\u06a9\u0646\u06cc\u060c \u0645\u0645\u06a9\u0646\u0647 \u0641\u0627\u06cc\u0644 APK \u06cc\u0627 AAB \u062e\u06cc\u0644\u06cc \u0628\u0632\u0631\u06af\u200c\u062a\u0631 \u0627\u0632 \u0686\u06cc\u0632\u06cc \u0628\u0627\u0634\u0647 \u06a9\u0647 \u0648\u0627\u0642\u0639\u0627\u064b \u0644\u0627\u0632\u0645\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u062d\u062c\u0645 \u0628\u0631\u0646\u0627\u0645\u0647 \u0641\u0642\u0637 \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0634\u06a9\u0644\u0627\u062a\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u06cc\u06a9 \u0646\u0641\u0631 \u0641\u0627\u06cc\u0644 APK \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0627\u0632 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u06a9\u0646\u0647. \u0627\u06af\u0631 \u0647\u06cc\u0686 \u0645\u062d\u0627\u0641\u0638\u062a\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0641\u0627\u06cc\u0644 \u0631\u0648 Decompile \u06a9\u0646\u0647 \u0648 \u0628\u062e\u0634 \u0632\u06cc\u0627\u062f\u06cc \u0627\u0632 \u0633\u0627\u062e\u062a\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0628\u06cc\u0646\u0647\u061b \u0627\u0633\u0645 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627\u060c \u0645\u062a\u062f\u0647\u0627\u060c \u0645\u062f\u0644\u200c\u0647\u0627\u06cc \u062f\u0627\u062f\u0647 \u0648 \u062d\u062a\u06cc \u0645\u0646\u0637\u0642 \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u0627 \u062d\u062f \u0632\u06cc\u0627\u062f\u06cc \u0642\u0627\u0628\u0644 \u062a\u0634\u062e\u06cc\u0635 \u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f. \u0634\u0627\u06cc\u062f \u0646\u062a\u0648\u0646\u0647 \u062f\u0642\u06cc\u0642\u0627\u064b \u0633\u0648\u0631\u0633 \u0627\u0635\u0644\u06cc Kotlin \u0631\u0648 \u0628\u0647 \u062f\u0633\u062a \u0628\u06cc\u0627\u0631\u0647\u060c \u0627\u0645\u0627 \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u06cc \u06a9\u0647 \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0645\u06cc\u200c\u06a9\u0646\u0647 \u06af\u0627\u0647\u06cc \u0628\u0631\u0627\u06cc \u0641\u0647\u0645\u06cc\u062f\u0646 \u0633\u0627\u062e\u062a\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u06a9\u0627\u0645\u0644\u0627\u064b \u06a9\u0627\u0641\u06cc\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646\u062c\u0627\u0633\u062a \u06a9\u0647 <strong>ProGuard<\/strong> \u0648\u0627\u0631\u062f \u0645\u0627\u062c\u0631\u0627 \u0645\u06cc\u0634\u0647. \u0627\u0644\u0628\u062a\u0647 \u0627\u06af\u0631 \u0628\u062e\u0648\u0627\u06cc \u062f\u0642\u06cc\u0642\u200c\u062a\u0631 \u0628\u06af\u06cc\u0645\u060c \u0627\u0632 \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f Android Gradle Plugin \u0627\u0628\u0632\u0627\u0631 \u0627\u0635\u0644\u06cc <strong>R8<\/strong> \u0647\u0633\u062a\u060c \u0646\u0647 ProGuard. \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u0686\u0648\u0646 \u0633\u0627\u0644\u200c\u0647\u0627\u0633\u062a \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627 \u0628\u0647 \u0627\u06cc\u0646 \u0641\u0631\u0627\u06cc\u0646\u062f \u0645\u06cc\u06af\u0646 \u00ab\u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0646 ProGuard\u00bb\u060c \u0647\u0646\u0648\u0632 \u0647\u0645 \u0627\u06cc\u0646 \u0627\u0633\u0645 \u0628\u06cc\u0646 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647\u200c\u0647\u0627\u06cc \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0631\u0627\u06cc\u062c\u0647. \u062f\u0631 \u0648\u0627\u0642\u0639\u060c \u0627\u0645\u0631\u0648\u0632 R8 \u06a9\u0627\u0631\u0647\u0627\u06cc\u06cc \u0631\u0648 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0647 \u06a9\u0647 \u0642\u0628\u0644\u0627\u064b ProGuard \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u200c\u062f\u0627\u062f \u0648 \u062d\u062a\u06cc \u0627\u0645\u06a9\u0627\u0646\u0627\u062a \u0628\u06cc\u0634\u062a\u0631\u06cc \u0647\u0645 \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u06af\u0631 ProGuard \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0634\u062a \u0686\u0647 \u0627\u062a\u0641\u0627\u0642\u06cc \u0645\u06cc\u200c\u0627\u0641\u062a\u0627\u062f\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u062f\u0627\u062e\u0644 \u067e\u0631\u0648\u0698\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627\u06cc\u06cc \u0628\u0627 \u0627\u0633\u0645\u200c\u0647\u0627\u06cc \u0632\u06cc\u0631 \u062f\u0627\u0631\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>ProductRepository\n\nUserManager\n\nPaymentService\n\nDiscountCalculator\n\nApiSecurityManager\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">ProductRepository<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">UserManager<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">PaymentService<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">DiscountCalculator<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">ApiSecurityManager<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u062a\u06cc \u0627\u06af\u0631 \u0647\u06cc\u0686 \u062e\u0637\u06cc \u0627\u0632 \u06a9\u062f \u0631\u0648 \u0647\u0645 \u0646\u062e\u0648\u0646\u06cc\u060c \u0641\u0642\u0637 \u0627\u0632 \u0631\u0648\u06cc \u0627\u0633\u0645 \u0627\u06cc\u0646 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u0645\u06cc\u0634\u0647 \u062d\u062f\u0633 \u0632\u062f \u0647\u0631 \u0628\u062e\u0634 \u0627\u0632 \u0628\u0631\u0646\u0627\u0645\u0647 \u0686\u0647 \u06a9\u0627\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0647. \u062d\u0627\u0644\u0627 \u062a\u0635\u0648\u0631 \u06a9\u0646 \u0635\u062f\u0647\u0627 \u06a9\u0644\u0627\u0633 \u0628\u0627 \u0647\u0645\u06cc\u0646 \u0633\u0628\u06a9 \u062f\u0627\u062e\u0644 \u067e\u0631\u0648\u0698\u0647 \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646. \u06a9\u0633\u06cc \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0645\u0647\u0646\u062f\u0633\u06cc \u0645\u0639\u06a9\u0648\u0633 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u062e\u06cc\u0644\u06cc \u0631\u0627\u062d\u062a \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0645\u0639\u0645\u0627\u0631\u06cc \u06a9\u0644\u06cc \u067e\u0631\u0648\u0698\u0647 \u0631\u0648 \u062f\u0631\u06a9 \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0648\u0642\u062a\u06cc R8 \u06cc\u0627 \u0647\u0645\u0627\u0646 \u0686\u06cc\u0632\u06cc \u06a9\u0647 \u0647\u0645\u0647 \u0628\u0647 \u0627\u0633\u0645 ProGuard \u0645\u06cc\u200c\u0634\u0646\u0627\u0633\u0646 \u0641\u0639\u0627\u0644 \u0628\u0627\u0634\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 \u0647\u0645\u06cc\u0646 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u0628\u0647 \u0686\u06cc\u0632\u06cc \u0634\u0628\u06cc\u0647 \u0627\u06cc\u0646 \u062a\u0628\u062f\u06cc\u0644 \u0628\u0634\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>a\n\nb\n\nc\n\nd\n\ne\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u0645\u062a\u062f\u0647\u0627 \u0647\u0645 \u0627\u0633\u0645\u200c\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 \u0627\u06cc\u0646 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u0646:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>a()\n\nb()\n\nc()\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">a<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6F42C1\">b<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6F42C1\">c<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u062d\u062a\u06cc \u0627\u06af\u0631 \u06a9\u0633\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 Decompile \u06a9\u0646\u0647\u060c \u0641\u0647\u0645\u06cc\u062f\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0647\u0631 \u06a9\u0644\u0627\u0633 \u0686\u0647 \u06a9\u0627\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0647\u060c \u0686\u0646\u062f\u06cc\u0646 \u0628\u0631\u0627\u0628\u0631 \u0633\u062e\u062a\u200c\u062a\u0631 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">ProGuard \u062f\u0642\u06cc\u0642\u0627\u064b \u0686\u0647 \u06a9\u0627\u0631\u0647\u0627\u06cc\u06cc \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u06cc\u0634\u062a\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627 \u0641\u06a9\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646 ProGuard \u0641\u0642\u0637 \u0627\u0633\u0645 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u0631\u0648 \u0639\u0648\u0636 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u0627\u06cc\u0646 \u0641\u0642\u0637 \u06cc\u06a9\u06cc \u0627\u0632 \u0648\u0638\u0627\u06cc\u0641\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0648\u0644\u06cc\u0646 \u06a9\u0627\u0631\u06cc \u06a9\u0647 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0647 <strong>Code Shrinking<\/strong> \u0647\u0633\u062a. \u06cc\u0639\u0646\u06cc \u06a9\u062f\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0647\u06cc\u0686\u200c\u0648\u0642\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u0645\u06cc\u200c\u0634\u0646 \u0631\u0648 \u062d\u0630\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0641\u0631\u0636 \u06a9\u0646 \u0633\u0647 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0628\u0647 \u067e\u0631\u0648\u0698\u0647 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u06cc\u060c \u0627\u0645\u0627 \u0641\u0642\u0637 \u0627\u0632 \u062f\u0647 \u062f\u0631\u0635\u062f \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc \u0627\u0648\u0646\u200c\u0647\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc. R8 \u0628\u062e\u0634 \u0632\u06cc\u0627\u062f\u06cc \u0627\u0632 \u06a9\u062f\u0647\u0627\u06cc \u0628\u0644\u0627\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0631\u0648 \u062d\u0630\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u062a\u0627 \u062d\u062c\u0645 \u0628\u0631\u0646\u0627\u0645\u0647 \u06a9\u0645\u062a\u0631 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0648\u0645\u06cc\u0646 \u06a9\u0627\u0631 <strong>Resource Shrinking<\/strong> \u0647\u0633\u062a. \u06af\u0627\u0647\u06cc \u062f\u0627\u062e\u0644 \u067e\u0631\u0648\u0698\u0647 \u0639\u06a9\u0633\u200c\u0647\u0627\u060c \u0622\u06cc\u06a9\u0648\u0646\u200c\u0647\u0627 \u06cc\u0627 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc\u06cc \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0646 \u06a9\u0647 \u062f\u06cc\u06af\u0647 \u0647\u06cc\u0686 \u0628\u062e\u0634\u06cc \u0627\u0632 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0632\u0634\u0648\u0646 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06cc\u0646 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627 \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u062d\u0630\u0641 \u0628\u0634\u0646 \u0648 \u062d\u062c\u0645 \u0646\u0647\u0627\u06cc\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u06a9\u0645\u062a\u0631 \u06a9\u0646\u0646. \u0633\u0648\u0645\u06cc\u0646 \u06a9\u0627\u0631 <strong>Optimization<\/strong> \u0647\u0633\u062a. \u0628\u0639\u0636\u06cc \u0627\u0632 \u06a9\u062f\u0647\u0627 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u0633\u0627\u062f\u0647\u200c\u062a\u0631 \u06cc\u0627 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u0627\u062c\u0631\u0627 \u0628\u0634\u0646. R8 \u062f\u0631 \u0628\u0639\u0636\u06cc \u0634\u0631\u0627\u06cc\u0637 \u0627\u06cc\u0646 \u0628\u0647\u06cc\u0646\u0647\u200c\u0633\u0627\u0632\u06cc\u200c\u0647\u0627 \u0631\u0648 \u0647\u0645 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u062f\u0631 \u0646\u0647\u0627\u06cc\u062a \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u0628\u062e\u0634\u06cc \u06a9\u0647 \u0628\u06cc\u0634\u062a\u0631 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647\u200c\u0647\u0627 \u0628\u0627\u0647\u0627\u0634 \u0622\u0634\u0646\u0627 \u0647\u0633\u062a\u0646\u060c <strong>Obfuscation<\/strong> \u06cc\u0627 \u0645\u0628\u0647\u0645\u200c\u0633\u0627\u0632\u06cc \u06a9\u062f\u0647\u061b \u06cc\u0639\u0646\u06cc \u062a\u063a\u06cc\u06cc\u0631 \u0627\u0633\u0645 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627\u060c \u0645\u062a\u062f\u0647\u0627 \u0648 \u0641\u06cc\u0644\u062f\u0647\u0627 \u062a\u0627 \u0645\u0647\u0646\u062f\u0633\u06cc \u0645\u0639\u06a9\u0648\u0633 \u0628\u0631\u0646\u0627\u0645\u0647 \u0633\u062e\u062a\u200c\u062a\u0631 \u0628\u0634\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0622\u06cc\u0627 ProGuard \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u063a\u06cc\u0631\u0642\u0627\u0628\u0644 \u0647\u06a9 \u0645\u06cc\u200c\u06a9\u0646\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0647. \u0627\u06cc\u0646 \u06cc\u06a9\u06cc \u0627\u0632 \u0631\u0627\u06cc\u062c\u200c\u062a\u0631\u06cc\u0646 \u0633\u0648\u0621\u062a\u0641\u0627\u0647\u0645\u200c\u0647\u0627\u0633\u062a. \u0628\u0639\u0636\u06cc\u200c\u0647\u0627 \u0641\u06a9\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646 \u0627\u06af\u0631 ProGuard \u0631\u0648 \u0641\u0639\u0627\u0644 \u06a9\u0646\u0646\u060c \u062f\u06cc\u06af\u0647 \u0647\u06cc\u0686\u200c\u06a9\u0633 \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0634\u0648\u0646 \u0631\u0648 \u0645\u0647\u0646\u062f\u0633\u06cc \u0645\u0639\u06a9\u0648\u0633 \u06a9\u0646\u0647. \u0648\u0627\u0642\u0639\u06cc\u062a \u0627\u06cc\u0646\u0647 \u06a9\u0647 ProGuard \u0641\u0642\u0637 \u06a9\u0627\u0631 \u0645\u0647\u0627\u062c\u0645 \u0631\u0648 \u0633\u062e\u062a\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0646\u0647 \u063a\u06cc\u0631\u0645\u0645\u06a9\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc \u0648\u0627\u0631\u062f \u06cc\u06a9 \u0633\u0627\u062e\u062a\u0645\u0627\u0646 \u0628\u0634\u06cc. \u0627\u06af\u0631 \u062f\u0631\u0650 \u0633\u0627\u062e\u062a\u0645\u0627\u0646 \u0642\u0641\u0644 \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0647\u0631 \u06a9\u0633\u06cc \u0628\u0647 \u0631\u0627\u062d\u062a\u06cc \u0648\u0627\u0631\u062f \u0645\u06cc\u0634\u0647. \u0627\u0645\u0627 \u0627\u06af\u0631 \u0686\u0646\u062f \u0642\u0641\u0644\u060c \u062f\u0648\u0631\u0628\u06cc\u0646 \u0648 \u0633\u06cc\u0633\u062a\u0645 \u0627\u0645\u0646\u06cc\u062a\u06cc \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0648\u0631\u0648\u062f \u062e\u06cc\u0644\u06cc \u0633\u062e\u062a\u200c\u062a\u0631 \u0645\u06cc\u0634\u0647. \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u0647\u0646\u0648\u0632 \u0647\u0645 \u0627\u0632 \u0646\u0638\u0631 \u062a\u0626\u0648\u0631\u06cc \u0645\u0645\u06a9\u0646\u0647 \u06cc\u06a9 \u0645\u0647\u0627\u062c\u0645 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0648\u0627\u0631\u062f \u0628\u0634\u0647. ProGuard \u0647\u0645 \u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u06cc\u0646 \u0646\u0642\u0634 \u0631\u0648 \u062f\u0627\u0631\u0647. \u0647\u062f\u0641\u0634 \u0627\u06cc\u0646 \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0627\u0645\u0646\u06cc\u062a \u0645\u0637\u0644\u0642 \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0647\u061b \u0647\u062f\u0641\u0634 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0632\u0645\u0627\u0646\u060c \u0647\u0632\u06cc\u0646\u0647 \u0648 \u0633\u062e\u062a\u06cc \u0645\u0647\u0646\u062f\u0633\u06cc \u0645\u0639\u06a9\u0648\u0633 \u0631\u0648 \u062a\u0627 \u062c\u0627\u06cc \u0645\u0645\u06a9\u0646 \u0628\u0627\u0644\u0627 \u0628\u0628\u0631\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0646 ProGuard<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0646\u0633\u062e\u0647 Release \u0645\u0639\u0645\u0648\u0644\u0627\u064b R8 \u0628\u0647 \u0647\u0645\u06cc\u0646 \u0634\u06a9\u0644 \u0641\u0639\u0627\u0644 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>buildTypes {\n\n    release {\n\n        isMinifyEnabled = true\n\n        isShrinkResources = true\n\n        proguardFiles(\n\n            getDefaultProguardFile(\n                \"proguard-android-optimize.txt\"\n            ),\n            \"proguard-rules.pro\"\n        )\n\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">buildTypes<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">release<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        isMinifyEnabled <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        isShrinkResources <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">proguardFiles<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">getDefaultProguardFile<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;proguard-android-optimize.txt&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;proguard-rules.pro&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0631 \u06a9\u062f\u0648\u0645 \u0627\u0632 \u0627\u06cc\u0646 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u06cc\u06a9 \u0648\u0638\u06cc\u0641\u0647 \u062f\u0627\u0631\u0646. <code>isMinifyEnabled<\/code> \u0628\u0627\u0639\u062b \u0641\u0639\u0627\u0644 \u0634\u062f\u0646 \u0641\u0631\u0627\u06cc\u0646\u062f \u06a9\u0648\u0686\u06a9\u200c\u0633\u0627\u0632\u06cc\u060c \u0628\u0647\u06cc\u0646\u0647\u200c\u0633\u0627\u0632\u06cc \u0648 Obfuscation \u0645\u06cc\u0634\u0647. <code>isShrinkResources<\/code> \u0647\u0645 \u0645\u0646\u0627\u0628\u0639 \u0628\u0644\u0627\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u062b\u0644 \u062a\u0635\u0627\u0648\u06cc\u0631 \u0648 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc \u0627\u0636\u0627\u0641\u06cc \u0631\u0648 \u062d\u0630\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0641\u0627\u06cc\u0644 <code>proguard-rules.pro<\/code> \u0647\u0645 \u062c\u0627\u06cc\u06cc\u0647 \u06a9\u0647 \u0642\u0648\u0627\u0646\u06cc\u0646 \u0645\u062e\u0635\u0648\u0635 \u067e\u0631\u0648\u0698\u0647 \u062e\u0648\u062f\u062a \u0631\u0648 \u062f\u0627\u062e\u0644\u0634 \u0645\u06cc\u200c\u0646\u0648\u06cc\u0633\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0631\u0627 \u0628\u0639\u0636\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627 \u0628\u0639\u062f \u0627\u0632 \u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0646 ProGuard \u062e\u0631\u0627\u0628 \u0645\u06cc\u0634\u0646\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0627\u062a\u0641\u0627\u0642 \u0628\u06cc\u0634\u062a\u0631 \u0627\u0632 \u0686\u06cc\u0632\u06cc \u06a9\u0647 \u0641\u06a9\u0631 \u0645\u06cc\u200c\u06a9\u0646\u06cc \u0631\u0627\u06cc\u062c\u0647. \u0641\u0631\u0636 \u06a9\u0646 \u06cc\u06a9 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0628\u0627 Reflection \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u06cc\u0639\u0646\u06cc \u0627\u0633\u0645 \u06a9\u0644\u0627\u0633 \u06cc\u0627 \u0645\u062a\u062f\u0647\u0627 \u0631\u0648 \u062f\u0631 \u0632\u0645\u0627\u0646 \u0627\u062c\u0631\u0627 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06af\u0631 R8 \u0627\u0633\u0645 \u0627\u0648\u0646 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u0647\u060c \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u062f\u06cc\u06af\u0647 \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u067e\u06cc\u062f\u0627\u0634\u0648\u0646 \u06a9\u0646\u0647 \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 Crash \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627 \u0645\u062b\u0644\u0627\u064b \u0628\u0639\u0636\u06cc \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627 \u0627\u0632 Annotation\u0647\u0627 \u06cc\u0627 Serialization \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646. \u0627\u06af\u0631 \u0642\u0648\u0627\u0646\u06cc\u0646 \u0645\u0646\u0627\u0633\u0628 \u0628\u0631\u0627\u0634\u0648\u0646 \u0646\u0648\u0634\u062a\u0647 \u0646\u0634\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 \u0628\u062e\u0634\u06cc \u0627\u0632 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u062d\u0630\u0641 \u0628\u0634\u0646 \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u06cc\u06af\u0647 \u062f\u0631\u0633\u062a \u06a9\u0627\u0631 \u0646\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644\u060c \u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0646 ProGuard \u0641\u0642\u0637 \u0632\u062f\u0646 \u06cc\u06a9 \u06af\u0632\u06cc\u0646\u0647 \u0646\u06cc\u0633\u062a. \u0628\u0639\u062f \u0627\u0632 \u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0646\u0634 \u0628\u0627\u06cc\u062f \u0646\u0633\u062e\u0647 Release \u0631\u0648 \u06a9\u0627\u0645\u0644 \u062a\u0633\u062a \u06a9\u0646\u06cc\u060c \u0686\u0648\u0646 \u0645\u0645\u06a9\u0646\u0647 \u0645\u0634\u06a9\u0644\u06cc \u0628\u0647 \u0648\u062c\u0648\u062f \u0628\u06cc\u0627\u062f \u06a9\u0647 \u062f\u0631 \u0646\u0633\u062e\u0647 Debug \u0627\u0635\u0644\u0627\u064b \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0634\u062a.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0641\u0627\u06cc\u0644 proguard-rules.pro \u0686\u06cc\u0633\u062a\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0641\u0627\u06cc\u0644 \u062f\u0631 \u0648\u0627\u0642\u0639 \u062f\u0641\u062a\u0631\u0686\u0647 \u062f\u0633\u062a\u0648\u0631\u0647\u0627\u06cc \u062a\u0648 \u0628\u0631\u0627\u06cc R8 \u0647\u0633\u062a. \u0627\u06cc\u0646\u062c\u0627 \u0645\u0634\u062e\u0635 \u0645\u06cc\u200c\u06a9\u0646\u06cc \u0686\u0647 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627\u06cc\u06cc \u062d\u0630\u0641 \u0646\u0634\u0646\u060c \u0686\u0647 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627\u06cc\u06cc \u062a\u063a\u06cc\u06cc\u0631 \u0646\u0627\u0645 \u0646\u062f\u0646 \u0648 \u0686\u0647 \u0628\u062e\u0634\u200c\u0647\u0627\u06cc\u06cc \u062f\u0633\u062a\u200c\u0646\u062e\u0648\u0631\u062f\u0647 \u0628\u0627\u0642\u06cc \u0628\u0645\u0648\u0646\u0646. \u0645\u062b\u0644\u0627\u064b \u0627\u06af\u0631 \u0628\u062e\u0648\u0627\u06cc \u06cc\u06a9 \u06a9\u0644\u0627\u0633 \u062e\u0627\u0635 \u0647\u06cc\u0686\u200c\u0648\u0642\u062a Obfuscate \u0646\u0634\u0647\u060c \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0642\u0627\u0646\u0648\u0646\u06cc \u0634\u0628\u06cc\u0647 \u0627\u06cc\u0646 \u0628\u0646\u0648\u06cc\u0633\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>-keep class com.gheimatban.network.ApiService {\n    *;\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">keep <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">com<\/span><span style=\"color: #24292E\">.gheimatban.network.<\/span><span style=\"color: #6F42C1\">ApiService<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0639\u0646\u06cc \u0627\u06cc\u0646 \u06a9\u0644\u0627\u0633 \u0648 \u062a\u0645\u0627\u0645 \u0627\u0639\u0636\u0627\u06cc \u062f\u0627\u062e\u0644\u0634 \u0628\u0627\u06cc\u062f \u0628\u062f\u0648\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u0627\u0642\u06cc \u0628\u0645\u0648\u0646\u0646. \u062f\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc\u060c \u0628\u0647 \u0645\u0631\u0648\u0631 \u0632\u0645\u0627\u0646 \u0645\u0645\u06a9\u0646\u0647 \u062f\u0647\u200c\u0647\u0627 \u06cc\u0627 \u062d\u062a\u06cc \u0635\u062f\u0647\u0627 \u0642\u0627\u0646\u0648\u0646 \u062f\u0627\u062e\u0644 \u0627\u06cc\u0646 \u0641\u0627\u06cc\u0644 \u0646\u0648\u0634\u062a\u0647 \u0628\u0634\u0647\u061b \u0645\u062e\u0635\u0648\u0635\u0627\u064b \u0648\u0642\u062a\u06cc \u0627\u0632 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0622\u06cc\u0627 \u0647\u0645\u06cc\u0634\u0647 \u0628\u0627\u06cc\u062f ProGuard \u0631\u0648 \u0641\u0639\u0627\u0644 \u06a9\u0646\u06cc\u0645\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0646\u0633\u062e\u0647 Debug \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0646\u0647. \u062f\u0644\u06cc\u0644\u0634 \u0633\u0627\u062f\u0647 \u0627\u0633\u062a. \u0648\u0642\u062a\u06cc \u062f\u0631 \u062d\u0627\u0644 \u062a\u0648\u0633\u0639\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0633\u062a\u06cc\u060c \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc \u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc \u062e\u0637\u0627 \u0648\u0627\u0636\u062d \u0628\u0627\u0634\u0646\u060c \u0627\u0633\u0645 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u062a\u063a\u06cc\u06cc\u0631 \u0646\u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u0647 \u0648 \u062f\u06cc\u0628\u0627\u06af \u06a9\u0631\u062f\u0646 \u0631\u0627\u062d\u062a \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647. \u0627\u0645\u0627 \u0628\u0631\u0627\u06cc \u0646\u0633\u062e\u0647 Release \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0645\u06cc\u0634\u0647 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u0634\u0647 R8 \u0641\u0639\u0627\u0644 \u0628\u0627\u0634\u0647\u061b \u0686\u0648\u0646 \u0647\u0645 \u062d\u062c\u0645 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u06a9\u0645\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0647\u0645 \u0627\u062c\u0631\u0627\u06cc \u0628\u0639\u0636\u06cc \u0628\u062e\u0634\u200c\u0647\u0627 \u0631\u0648 \u0628\u0647\u06cc\u0646\u0647\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u0647\u0645 \u0645\u0647\u0646\u062f\u0633\u06cc \u0645\u0639\u06a9\u0648\u0633 \u0631\u0648 \u0633\u062e\u062a\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062e\u0627\u0637\u0631\u060c \u0627\u06af\u0631 \u0641\u0627\u06cc\u0644 Gradle \u0627\u06a9\u062b\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0631\u0648 \u0628\u0628\u06cc\u0646\u06cc\u060c \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u0634\u06cc \u06a9\u0647 <code>isMinifyEnabled<\/code> \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc Release \u0641\u0639\u0627\u0644 \u0634\u062f\u0647 \u0648 \u0646\u0633\u062e\u0647 Debug \u0628\u062f\u0648\u0646 \u0627\u06cc\u0646 \u0645\u0631\u062d\u0644\u0647 Build \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u06cc\u0644\u06cc\u200c\u0647\u0627 ProGuard \u0631\u0648 \u0641\u0642\u0637 \u06cc\u06a9 \u0627\u0628\u0632\u0627\u0631 \u0627\u0645\u0646\u06cc\u062a\u06cc \u0645\u06cc\u200c\u0628\u06cc\u0646\u0646\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u0646\u0642\u0634\u0634 \u062e\u06cc\u0644\u06cc \u06af\u0633\u062a\u0631\u062f\u0647\u200c\u062a\u0631 \u0627\u0632 \u0627\u06cc\u0646\u0647. \u0627\u0645\u0631\u0648\u0632\u0647 \u0627\u06cc\u0646 \u0648\u0638\u0627\u06cc\u0641 \u062a\u0648\u0633\u0637 <strong>R8<\/strong> \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u0634\u0647\u061b \u0627\u0628\u0632\u0627\u0631\u06cc \u06a9\u0647 \u0647\u0645 \u06a9\u062f\u0647\u0627 \u0648 \u0645\u0646\u0627\u0628\u0639 \u0628\u0644\u0627\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0631\u0648 \u062d\u0630\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0647\u0645 \u062d\u062c\u0645 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u06a9\u0627\u0647\u0634 \u0645\u06cc\u062f\u0647\u060c \u0647\u0645 \u0628\u0639\u0636\u06cc \u0628\u0647\u06cc\u0646\u0647\u200c\u0633\u0627\u0632\u06cc\u200c\u0647\u0627 \u0631\u0648 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0647 \u0648 \u0647\u0645 \u0628\u0627 \u0645\u0628\u0647\u0645 \u06a9\u0631\u062f\u0646 \u0646\u0627\u0645 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u0648 \u0645\u062a\u062f\u0647\u0627\u060c \u0645\u0647\u0646\u062f\u0633\u06cc \u0645\u0639\u06a9\u0648\u0633 \u0631\u0648 \u0633\u062e\u062a\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u0644\u0628\u062a\u0647 \u0646\u0628\u0627\u06cc\u062f \u0627\u0646\u062a\u0638\u0627\u0631 \u062f\u0627\u0634\u062a \u06a9\u0647 \u0627\u06cc\u0646 \u0627\u0628\u0632\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u063a\u06cc\u0631\u0642\u0627\u0628\u0644 \u0647\u06a9 \u06a9\u0646\u0647. \u0647\u062f\u0641 \u0627\u0635\u0644\u06cc\u0634 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0648 \u062a\u062d\u0644\u06cc\u0644 \u06a9\u062f \u0628\u0631\u0627\u06cc \u0627\u0641\u0631\u0627\u062f \u063a\u06cc\u0631\u0645\u062c\u0627\u0632 \u0632\u0645\u0627\u0646\u200c\u0628\u0631\u062a\u0631 \u0648 \u067e\u0631\u0647\u0632\u06cc\u0646\u0647\u200c\u062a\u0631 \u0628\u0634\u0647\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u062e\u0648\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645\u0686\u0646\u0627\u0646 \u0628\u0627 \u0633\u0631\u0639\u062a \u0648 \u062d\u062c\u0645 \u0628\u0647\u062a\u0631\u06cc \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0627\u062c\u0631\u0627 \u0628\u0634\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u200c\u0648\u062f\u0648\u0645<\/h3>\n\n\n\n<h1 class=\"wp-block-heading\">\u0627\u0646\u062a\u0634\u0627\u0631 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u062f\u0631 \u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631 \u0648 \u06af\u0648\u06af\u0644\u200c\u067e\u0644\u06cc<\/h1>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-06-1-1024x768.avif\" alt=\"\" class=\"wp-image-6161\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-06-1-1024x768.avif 1024w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-06-1-300x225.avif 300w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-06-1-768x576.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-06-1.avif 1448w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u0627\u06cc\u0646\u062c\u0627 \u0628\u0631\u0646\u0627\u0645\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0631\u0648 \u0633\u0627\u062e\u062a\u06cc\u0645\u060c \u0646\u0633\u062e\u0647 Release \u0631\u0648 \u0627\u0632 \u0646\u0633\u062e\u0647 Debug \u062c\u062f\u0627 \u06a9\u0631\u062f\u06cc\u0645\u060c \u0627\u0645\u0636\u0627\u06cc \u062f\u06cc\u062c\u06cc\u062a\u0627\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0634\u0646\u0627\u062e\u062a\u06cc\u0645 \u0648 \u0628\u0627 R8 \u06cc\u0627 \u0647\u0645\u0648\u0646 ProGuard \u06a9\u0627\u0631\u06cc \u06a9\u0631\u062f\u06cc\u0645 \u06a9\u0647 \u06a9\u062f\u0647\u0627\u06cc \u0627\u0636\u0627\u0641\u06cc \u062d\u0630\u0641 \u0628\u0634\u0646 \u0648 \u0645\u0647\u0646\u062f\u0633\u06cc \u0645\u0639\u06a9\u0648\u0633 \u0628\u0631\u0646\u0627\u0645\u0647 \u0633\u062e\u062a\u200c\u062a\u0631 \u0628\u0634\u0647. \u062d\u0627\u0644\u0627 \u0628\u0627\u06cc\u062f \u062e\u0631\u0648\u062c\u06cc \u0646\u0647\u0627\u06cc\u06cc \u0631\u0648 \u0627\u0632 \u0645\u062d\u06cc\u0637 \u062a\u0648\u0633\u0639\u0647 \u0628\u06cc\u0631\u0648\u0646 \u0628\u06cc\u0627\u0631\u06cc\u0645 \u0648 \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0648\u0627\u0642\u0639\u06cc \u0642\u0631\u0627\u0631 \u0628\u062f\u06cc\u0645. \u0627\u06cc\u0646 \u0645\u0631\u062d\u0644\u0647 \u0641\u0642\u0637 \u0622\u067e\u0644\u0648\u062f \u06a9\u0631\u062f\u0646 \u06cc\u06a9 \u0641\u0627\u06cc\u0644 \u062f\u0627\u062e\u0644 \u0633\u0627\u06cc\u062a \u0646\u06cc\u0633\u062a. \u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0645\u0648\u0641\u0642 \u0628\u0627\u06cc\u062f \u0646\u0633\u062e\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u062f\u0631\u0633\u062a \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u0645\u060c \u062e\u0631\u0648\u062c\u06cc \u0645\u0646\u0627\u0633\u0628 \u0647\u0631 \u0645\u0627\u0631\u06a9\u062a \u0631\u0648 \u0628\u0633\u0627\u0632\u06cc\u0645\u060c \u0645\u0637\u0645\u0626\u0646 \u0628\u0634\u06cc\u0645 \u0641\u0627\u06cc\u0644 \u0628\u0627 \u06a9\u0644\u06cc\u062f \u0635\u062d\u06cc\u062d \u0627\u0645\u0636\u0627 \u0634\u062f\u0647\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0631\u0648\u06cc \u0646\u0633\u062e\u0647 Release \u0622\u0632\u0645\u0627\u06cc\u0634 \u06a9\u0646\u06cc\u0645\u060c \u0635\u0641\u062d\u0647 \u0645\u0639\u0631\u0641\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u06a9\u0627\u0645\u0644 \u06a9\u0646\u06cc\u0645 \u0648 \u0628\u0639\u062f \u0647\u0645 \u0646\u0633\u062e\u0647 \u0631\u0648 \u0627\u0628\u062a\u062f\u0627 \u062f\u0631 \u0645\u0633\u06cc\u0631 \u0622\u0632\u0645\u0627\u06cc\u0634\u06cc \u0648 \u0633\u067e\u0633 \u062f\u0631 \u0645\u0633\u06cc\u0631 \u0639\u0645\u0648\u0645\u06cc \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u062f\u0631\u0633 \u0641\u0631\u0636 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0646\u0633\u062e\u0647 \u0627\u0648\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0622\u0645\u0627\u062f\u0647 \u0634\u062f\u0647 \u0648 \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc\u0645 \u0627\u0648\u0646 \u0631\u0648 \u0647\u0645 \u062f\u0631 \u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631 \u0648 \u0647\u0645 \u062f\u0631 Google Play \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u06cc\u0645. \u0628\u062e\u0634 \u0632\u06cc\u0627\u062f\u06cc \u0627\u0632 \u0622\u0645\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0641\u0646\u06cc \u0628\u0631\u0627\u06cc \u0647\u0631 \u062f\u0648 \u0645\u0627\u0631\u06a9\u062a \u0645\u0634\u062a\u0631\u06a9\u0647\u060c \u0627\u0645\u0627 \u0646\u0648\u0639 \u0641\u0627\u06cc\u0644\u060c \u0634\u06cc\u0648\u0647 \u0627\u0645\u0636\u0627 \u0648 \u0628\u0639\u0636\u06cc \u0645\u0631\u0627\u062d\u0644 \u067e\u0646\u0644 \u0627\u0646\u062a\u0634\u0627\u0631 \u062a\u0641\u0627\u0648\u062a \u062f\u0627\u0631\u0646. Google Play \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f \u0627\u0632 Android App Bundle \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u062e\u0648\u062f \u06af\u0648\u06af\u0644 \u0627\u0632 \u062f\u0627\u062e\u0644 \u0641\u0627\u06cc\u0644 AAB\u060c \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc APK \u0645\u0646\u0627\u0633\u0628 \u0647\u0631 \u062f\u0633\u062a\u06af\u0627\u0647 \u0631\u0648 \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. \u062f\u0631 \u0645\u0627\u0631\u06a9\u062a\u200c\u0647\u0627\u06cc \u062f\u06cc\u06af\u0647 \u0645\u0645\u06a9\u0646\u0647 APK \u06cc\u0627 AAB \u067e\u0630\u06cc\u0631\u0641\u062a\u0647 \u0628\u0634\u0647\u060c \u0627\u0645\u0627 \u0628\u0627\u06cc\u062f \u0642\u0628\u0644 \u0627\u0632 \u0647\u0631 \u0627\u0646\u062a\u0634\u0627\u0631\u060c \u0641\u0631\u0645\u062a\u200c\u0647\u0627\u06cc \u067e\u0630\u06cc\u0631\u0641\u062a\u0647\u200c\u0634\u062f\u0647 \u0648 \u0642\u0648\u0627\u0646\u06cc\u0646 \u0631\u0648\u0632 \u0647\u0645\u0648\u0646 \u0645\u0627\u0631\u06a9\u062a \u0631\u0648 \u062f\u0627\u062e\u0644 \u067e\u0646\u0644 \u0631\u0633\u0645\u06cc \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u061b \u0686\u0648\u0646 \u062c\u0632\u0626\u06cc\u0627\u062a \u067e\u0646\u0644\u200c\u0647\u0627 \u0648 \u0633\u06cc\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0645\u0645\u06a9\u0646\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0642\u0628\u0644 \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631\u060c \u0646\u0633\u062e\u0647 Release \u0648\u0627\u0642\u0639\u06cc \u0631\u0648 \u0622\u0645\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0648\u0644\u06cc\u0646 \u0627\u0634\u062a\u0628\u0627\u0647 \u062e\u0637\u0631\u0646\u0627\u06a9 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u062f\u0631 \u062d\u0627\u0644\u062a Debug \u062a\u0633\u062a \u06a9\u0646\u06cc\u0645 \u0648 \u062a\u0635\u0648\u0631 \u06a9\u0646\u06cc\u0645 \u0646\u0633\u062e\u0647 Release \u0647\u0645 \u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u0648\u0646 \u0631\u0641\u062a\u0627\u0631 \u0631\u0648 \u062e\u0648\u0627\u0647\u062f \u062f\u0627\u0634\u062a. \u0646\u0633\u062e\u0647 Release \u0645\u0645\u06a9\u0646\u0647 \u0627\u0632 \u0622\u062f\u0631\u0633 \u0633\u0631\u0648\u0631 \u0645\u062a\u0641\u0627\u0648\u062a\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0647\u060c \u0644\u0627\u06af\u200c\u0647\u0627\u0634 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u0628\u0627\u0634\u0646\u060c R8 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u0631\u0648 \u062d\u0630\u0641 \u06cc\u0627 Obfuscate \u06a9\u0646\u0647\u060c \u0627\u0645\u0636\u0627\u06cc \u0645\u062a\u0641\u0627\u0648\u062a\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647 \u0648 \u062d\u062a\u06cc \u0628\u0639\u0636\u06cc \u0633\u0631\u0648\u06cc\u0633\u200c\u0647\u0627 \u0645\u062b\u0644 \u0648\u0631\u0648\u062f \u06af\u0648\u06af\u0644\u060c \u0646\u0642\u0634\u0647\u060c Firebase \u06cc\u0627 API\u0647\u0627\u06cc \u062f\u0627\u0631\u0627\u06cc \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0627\u0645\u0636\u0627 \u062f\u0631 \u0627\u0648\u0646 \u06a9\u0627\u0631 \u0646\u06a9\u0646\u0646. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0686\u06cc\u0632\u06cc \u06a9\u0647 \u0628\u0627\u06cc\u062f \u0622\u0632\u0645\u0627\u06cc\u0634 \u0628\u0634\u0647\u060c \u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u0648\u0646 \u0641\u0627\u06cc\u0644 \u0627\u0645\u0636\u0627\u0634\u062f\u0647\u200c\u0627\u06cc\u0647 \u06a9\u0647 \u0642\u0631\u0627\u0631\u0647 \u062f\u0631 \u0645\u0627\u0631\u06a9\u062a \u0645\u0646\u062a\u0634\u0631 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0641\u0627\u06cc\u0644 <code>build.gradle.kts<\/code> \u0645\u0627\u0698\u0648\u0644 <code>app<\/code> \u0628\u0627\u06cc\u062f \u0645\u0634\u062e\u0635\u0627\u062a \u0646\u0633\u062e\u0647\u060c \u0634\u0646\u0627\u0633\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a Release \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645. \u0646\u0645\u0648\u0646\u0647 \u0632\u06cc\u0631 \u06cc\u06a9 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc \u0645\u0639\u0642\u0648\u0644 \u0628\u0631\u0627\u06cc \u0646\u0633\u062e\u0647 \u0627\u0648\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0647\u0633\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>android {\n    namespace = \"com.gheimatban.app\"\n    compileSdk = 36\n\n    defaultConfig {\n        applicationId = \"com.gheimatban.app\"\n\n        minSdk = 24\n        targetSdk = 36\n\n        versionCode = 1\n        versionName = \"1.0.0\"\n    }\n\n    buildTypes {\n        debug {\n            applicationIdSuffix = \".debug\"\n            versionNameSuffix = \"-debug\"\n\n            isDebuggable = true\n            isMinifyEnabled = false\n            isShrinkResources = false\n        }\n\n        release {\n            isDebuggable = false\n            isMinifyEnabled = true\n            isShrinkResources = true\n\n            proguardFiles(\n                getDefaultProguardFile(\n                    \"proguard-android-optimize.txt\"\n                ),\n                \"proguard-rules.pro\"\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">android<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    namespace <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;com.gheimatban.app&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    compileSdk <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">36<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">defaultConfig<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        applicationId <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;com.gheimatban.app&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        minSdk <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">24<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        targetSdk <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">36<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        versionCode <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        versionName <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;1.0.0&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">buildTypes<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">debug<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            applicationIdSuffix <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;.debug&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            versionNameSuffix <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;-debug&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            isDebuggable <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            isMinifyEnabled <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            isShrinkResources <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">release<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            isDebuggable <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            isMinifyEnabled <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            isShrinkResources <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">proguardFiles<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">getDefaultProguardFile<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;proguard-android-optimize.txt&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;proguard-rules.pro&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0642\u062f\u0627\u0631 <code>applicationId<\/code> \u0647\u0648\u06cc\u062a \u0641\u0646\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0648 \u0645\u0627\u0631\u06a9\u062a\u200c\u0647\u0627\u0633\u062a. \u06a9\u0627\u0631\u0628\u0631 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u06cc\u0646 \u0645\u0642\u062f\u0627\u0631 \u0631\u0648 \u0646\u0645\u06cc\u200c\u0628\u06cc\u0646\u0647\u060c \u0627\u0645\u0627 Google Play \u0648 \u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0627 \u0647\u0645\u06cc\u0646 \u0634\u0646\u0627\u0633\u0647 \u0645\u06cc\u200c\u0634\u0646\u0627\u0633\u0646. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 <code>com.gheimatban.app<\/code> \u0628\u0627 <code>com.gheimatban.android<\/code> \u062f\u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u06a9\u0627\u0645\u0644\u0627\u064b \u0645\u062a\u0641\u0627\u0648\u062a \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0646. \u0628\u0639\u062f \u0627\u0632 \u0627\u06cc\u0646\u06a9\u0647 \u0627\u0648\u0644\u06cc\u0646 \u0646\u0633\u062e\u0647 \u0631\u0648 \u062f\u0631 \u06cc\u06a9 \u0645\u0627\u0631\u06a9\u062a \u062b\u0628\u062a \u06a9\u0631\u062f\u06cc\u060c \u0646\u0628\u0627\u06cc\u062f \u0634\u0646\u0627\u0633\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u06cc\u061b \u0686\u0648\u0646 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u062f\u06cc\u06af\u0647 \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0646\u0633\u062e\u0647 \u0642\u0628\u0644\u06cc \u0634\u0646\u0627\u062e\u062a\u0647 \u0646\u0645\u06cc\u0634\u0647 \u0648 \u0639\u0645\u0644\u0627\u064b \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u0627\u0632\u0647 \u0628\u0647 \u0648\u062c\u0648\u062f \u0645\u06cc\u0627\u062f. Google Play \u0647\u0645 Package Name \u0631\u0648 \u06cc\u06a9 \u0634\u0646\u0627\u0633\u0647 \u06cc\u06a9\u062a\u0627 \u0648 \u062f\u0627\u0626\u0645\u06cc \u0645\u06cc\u200c\u062f\u0648\u0646\u0647 \u0648 \u0628\u0639\u062f \u0627\u0632 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0641\u0627\u06cc\u0644\u060c \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0627\u0648\u0646 \u0631\u0648 \u0628\u0631\u0627\u06cc \u0647\u0645\u0648\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0639\u0648\u0636 \u06a9\u0646\u06cc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u062c\u0648\u062f <code>applicationIdSuffix = \".debug\"<\/code> \u0647\u0645 \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u0646\u0633\u062e\u0647 Debug \u0628\u0627 \u0634\u0646\u0627\u0633\u0647 \u0632\u06cc\u0631 \u0646\u0635\u0628 \u0628\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>com.gheimatban.app.debug\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0646\u0633\u062e\u0647 Release \u0628\u0627 \u0634\u0646\u0627\u0633\u0647 \u0627\u0635\u0644\u06cc \u0646\u0635\u0628 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>com.gheimatban.app\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0628\u0633\u06cc\u0627\u0631 \u0645\u0641\u06cc\u062f\u0647\u060c \u0686\u0648\u0646 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0646\u0633\u062e\u0647 \u062a\u0648\u0633\u0639\u0647 \u0648 \u0646\u0633\u062e\u0647 \u0648\u0627\u0642\u0639\u06cc GheimatBan \u0631\u0648 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0631\u0648\u06cc \u06cc\u06a9 \u06af\u0648\u0634\u06cc \u0646\u0635\u0628 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc. \u0627\u06af\u0631 \u0686\u0646\u06cc\u0646 \u067e\u0633\u0648\u0646\u062f\u06cc \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u060c \u0646\u0635\u0628 \u0646\u0633\u062e\u0647 Debug \u0645\u0645\u06a9\u0646\u0647 \u0646\u0633\u062e\u0647 \u0648\u0627\u0642\u0639\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u06a9\u0646\u0647 \u06cc\u0627 \u0628\u0647 \u062f\u0644\u06cc\u0644 \u062a\u0641\u0627\u0648\u062a \u0627\u0645\u0636\u0627 \u0628\u0627 \u062e\u0637\u0627\u06cc \u0646\u0635\u0628 \u0631\u0648\u0628\u0647\u200c\u0631\u0648 \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0641\u0627\u0648\u062a versionCode \u0648 versionName<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627\u06cc\u062f \u062f\u0648 \u0645\u0642\u062f\u0627\u0631 \u0646\u0633\u062e\u0647 \u0631\u0648 \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>defaultConfig {\n    versionCode = 1\n    versionName = \"1.0.0\"\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">defaultConfig<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    versionCode <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    versionName <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;1.0.0&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><code>versionName<\/code> \u0647\u0645\u0648\u0646 \u0634\u0645\u0627\u0631\u0647\u200c\u0627\u06cc\u0647 \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0645\u06cc\u200c\u0628\u06cc\u0646\u0647. \u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 <code>1.0.0<\/code>\u060c <code>1.1.0<\/code> \u06cc\u0627 <code>2.0.0<\/code> \u0628\u0627\u0634\u0647. \u0627\u06cc\u0646 \u0645\u0642\u062f\u0627\u0631 \u0628\u06cc\u0634\u062a\u0631 \u0628\u0631\u0627\u06cc \u0627\u0631\u062a\u0628\u0627\u0637 \u0628\u0627 \u06a9\u0627\u0631\u0628\u0631 \u0648 \u062a\u06cc\u0645 \u062a\u0648\u0633\u0639\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647. \u0627\u0645\u0627 <code>versionCode<\/code> \u06cc\u06a9 \u0639\u062f\u062f \u0635\u062d\u06cc\u062d \u062f\u0627\u062e\u0644\u06cc\u0647 \u06a9\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0648 \u0645\u0627\u0631\u06a9\u062a\u200c\u0647\u0627 \u0628\u0627 \u0627\u0648\u0646 \u062a\u0634\u062e\u06cc\u0635 \u0645\u06cc\u062f\u0646 \u06a9\u062f\u0648\u0645 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f\u062a\u0631\u0647. \u0647\u0631 \u0641\u0627\u06cc\u0644 \u062c\u062f\u06cc\u062f\u06cc \u06a9\u0647 \u0645\u0646\u062a\u0634\u0631 \u0645\u06cc\u200c\u06a9\u0646\u06cc \u0628\u0627\u06cc\u062f <code>versionCode<\/code> \u0628\u0632\u0631\u06af\u200c\u062a\u0631\u06cc \u0627\u0632 \u062a\u0645\u0627\u0645 \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u0642\u0628\u0644\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062f\u0648\u0628\u0627\u0631\u0647 \u0627\u0632 \u06cc\u06a9 <code>versionCode<\/code> \u0642\u0628\u0644\u06cc \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 Google Play \u0641\u0627\u06cc\u0644 \u062c\u062f\u06cc\u062f \u0631\u0648 \u0646\u067e\u0630\u06cc\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0646\u0633\u062e\u0647 \u0627\u0648\u0644 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0627\u06cc\u0646 \u062a\u0646\u0638\u06cc\u0645 \u0631\u0648 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>versionCode = 1\nversionName = \"1.0.0\"\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">versionCode <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">versionName <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;1.0.0&quot;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u06cc\u06a9 \u0628\u0627\u06af \u06a9\u0648\u0686\u06a9 \u0631\u0648 \u0628\u0631\u0637\u0631\u0641 \u06a9\u0631\u062f\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>versionCode = 2\nversionName = \"1.0.1\"\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">versionCode <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">versionName <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;1.0.1&quot;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u06cc\u06a9 \u0642\u0627\u0628\u0644\u06cc\u062a \u062a\u0627\u0632\u0647 \u0645\u062b\u0644 \u0647\u0634\u062f\u0627\u0631 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>versionCode = 3\nversionName = \"1.1.0\"\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">versionCode <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">3<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">versionName <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;1.1.0&quot;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u0627\u06af\u0631 \u0645\u0639\u0645\u0627\u0631\u06cc \u06cc\u0627 \u062a\u062c\u0631\u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647\u200c\u0635\u0648\u0631\u062a \u0627\u0633\u0627\u0633\u06cc \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>versionCode = 10\nversionName = \"2.0.0\"\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">versionCode <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">10<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">versionName <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2.0.0&quot;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0644\u0627\u0632\u0645 \u0646\u06cc\u0633\u062a <code>versionCode<\/code> \u0634\u0628\u06cc\u0647 <code>versionName<\/code> \u0628\u0627\u0634\u0647. \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0646\u0633\u062e\u0647 <code>3.7.2<\/code> \u0631\u0648 \u0628\u0627 <code>versionCode = 48<\/code> \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u06cc. \u0646\u06a9\u062a\u0647 \u0627\u0635\u0644\u06cc \u0627\u06cc\u0646\u0647 \u06a9\u0647 <code>versionCode<\/code> \u0647\u0645\u06cc\u0634\u0647 \u0627\u0641\u0632\u0627\u06cc\u0634 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u0647. \u0628\u0631\u0627\u06cc \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u062a\u06cc\u0645\u06cc \u0628\u0647\u062a\u0631\u0647 \u0627\u0641\u0632\u0627\u06cc\u0634 \u0627\u06cc\u0646 \u0639\u062f\u062f \u0628\u062e\u0634\u06cc \u0627\u0632 \u0641\u0631\u0627\u06cc\u0646\u062f \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0627\u0634\u0647 \u062a\u0627 \u06a9\u0633\u06cc \u0641\u0631\u0627\u0645\u0648\u0634\u0634 \u0646\u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u0627\u0645\u0636\u0627 \u0631\u0648 \u062f\u0627\u062e\u0644 Git \u0642\u0631\u0627\u0631 \u0646\u0645\u06cc\u200c\u062f\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u062f\u0631\u0633 Signing \u06a9\u0644\u06cc\u062f \u0627\u0646\u062a\u0634\u0627\u0631 \u0631\u0648 \u0633\u0627\u062e\u062a\u06cc\u0645. \u062d\u0627\u0644\u0627 \u0628\u0627\u06cc\u062f \u0645\u0637\u0645\u0626\u0646 \u0628\u0634\u06cc\u0645 \u0627\u0637\u0644\u0627\u0639\u0627\u062a Keystore \u062f\u0627\u062e\u0644 \u0641\u0627\u06cc\u0644 Gradle \u0648 \u0645\u062e\u0632\u0646 Git \u0645\u0646\u062a\u0634\u0631 \u0646\u0634\u062f\u0647. \u06cc\u06a9 \u0631\u0627\u0647 \u0645\u0639\u0645\u0648\u0644 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0648 \u062f\u0627\u062e\u0644 \u0641\u0627\u06cc\u0644 \u0645\u062d\u0644\u06cc \u062c\u062f\u0627\u06af\u0627\u0646\u0647 \u0642\u0631\u0627\u0631 \u0628\u062f\u06cc\u0645. \u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644\u060c \u062f\u0631 \u0631\u06cc\u0634\u0647 \u067e\u0631\u0648\u0698\u0647 \u0641\u0627\u06cc\u0644\u06cc \u0628\u0627 \u0646\u0627\u0645 <code>keystore.properties<\/code> \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>storeFile=..\/keys\/gheimatban-release.jks\nstorePassword=YOUR_STORE_PASSWORD\nkeyAlias=gheimatban\nkeyPassword=YOUR_KEY_PASSWORD\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">storeFile<\/span><span style=\"color: #D73A49\">=..\/<\/span><span style=\"color: #24292E\">keys<\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #24292E\">gheimatban<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">release.jks<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">storePassword<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\">YOUR_STORE_PASSWORD<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">keyAlias<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\">gheimatban<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">keyPassword<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\">YOUR_KEY_PASSWORD<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0641\u0627\u06cc\u0644 \u0631\u0648 \u062f\u0627\u062e\u0644 <code>.gitignore<\/code> \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u062f\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>keystore.properties\n*.jks\n*.keystore\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">keystore.properties<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\">.jks<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\">.keystore<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u067e\u0633 \u062f\u0631 <code>build.gradle.kts<\/code> \u0645\u0627\u0698\u0648\u0644 <code>app<\/code> \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0648 \u0645\u06cc\u200c\u062e\u0648\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>import java.util.Properties\n\nval keystoreProperties = Properties()\nval keystorePropertiesFile = rootProject.file(\"keystore.properties\")\n\nif (keystorePropertiesFile.exists()) {\n    keystoreProperties.load(\n        keystorePropertiesFile.inputStream()\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">import<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">java.util.Properties<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> keystoreProperties <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Properties<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> keystorePropertiesFile <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> rootProject.<\/span><span style=\"color: #6F42C1\">file<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;keystore.properties&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (keystorePropertiesFile.<\/span><span style=\"color: #6F42C1\">exists<\/span><span style=\"color: #24292E\">()) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    keystoreProperties.<\/span><span style=\"color: #6F42C1\">load<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        keystorePropertiesFile.<\/span><span style=\"color: #6F42C1\">inputStream<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 Signing Config \u0631\u0648 \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>android {\n    signingConfigs {\n        create(\"release\") {\n            storeFile = file(\n                keystoreProperties&#91;\"storeFile\"&#93; as String\n            )\n\n            storePassword =\n                keystoreProperties&#91;\"storePassword\"&#93; as String\n\n            keyAlias =\n                keystoreProperties&#91;\"keyAlias\"&#93; as String\n\n            keyPassword =\n                keystoreProperties&#91;\"keyPassword\"&#93; as String\n        }\n    }\n\n    buildTypes {\n        release {\n            signingConfig = signingConfigs.getByName(\"release\")\n\n            isDebuggable = false\n            isMinifyEnabled = true\n            isShrinkResources = true\n\n            proguardFiles(\n                getDefaultProguardFile(\n                    \"proguard-android-optimize.txt\"\n                ),\n                \"proguard-rules.pro\"\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">android<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">signingConfigs<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;release&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            storeFile <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">file<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                keystoreProperties&#91;<\/span><span style=\"color: #032F62\">&quot;storeFile&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">as<\/span><span style=\"color: #24292E\"> String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            storePassword <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                keystoreProperties&#91;<\/span><span style=\"color: #032F62\">&quot;storePassword&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">as<\/span><span style=\"color: #24292E\"> String<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            keyAlias <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                keystoreProperties&#91;<\/span><span style=\"color: #032F62\">&quot;keyAlias&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">as<\/span><span style=\"color: #24292E\"> String<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            keyPassword <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                keystoreProperties&#91;<\/span><span style=\"color: #032F62\">&quot;keyPassword&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">as<\/span><span style=\"color: #24292E\"> String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">buildTypes<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">release<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            signingConfig <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> signingConfigs.<\/span><span style=\"color: #6F42C1\">getByName<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;release&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            isDebuggable <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            isMinifyEnabled <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            isShrinkResources <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">proguardFiles<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">getDefaultProguardFile<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;proguard-android-optimize.txt&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;proguard-rules.pro&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u062d\u0627\u0644\u062a \u0647\u0631 \u0628\u0627\u0631 \u06a9\u0647 \u0646\u0633\u062e\u0647 Release \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647\u060c Gradle \u0627\u0648\u0646 \u0631\u0648 \u0628\u0627 \u06a9\u0644\u06cc\u062f \u0627\u0635\u0644\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0627\u0645\u0636\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0641\u0627\u06cc\u0644 Keystore \u0648 \u0631\u0645\u0632\u0647\u0627 \u0628\u0627\u06cc\u062f \u0686\u0646\u062f \u0646\u0633\u062e\u0647 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646 \u0627\u0645\u0646 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646. \u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0647\u200c\u0635\u0648\u0631\u062a APK \u062f\u0631 \u06cc\u06a9 \u0645\u0627\u0631\u06a9\u062a \u0645\u0646\u062a\u0634\u0631 \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u06cc \u0648 \u06a9\u0644\u06cc\u062f \u0627\u0645\u0636\u0627\u06cc \u0627\u0635\u0644\u06cc \u0631\u0648 \u0627\u0632 \u062f\u0633\u062a \u0628\u062f\u06cc\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u062f\u06cc\u06af\u0647 \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0633\u0627\u0632\u06af\u0627\u0631 \u0628\u0627 \u0646\u0633\u062e\u0647 \u0646\u0635\u0628\u200c\u0634\u062f\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u062a\u0648\u0644\u06cc\u062f \u06a9\u0646\u06cc. \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0641\u0642\u0637 \u0632\u0645\u0627\u0646\u06cc \u0641\u0627\u06cc\u0644 \u062c\u062f\u06cc\u062f \u0631\u0648 \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 \u0622\u067e\u062f\u06cc\u062a \u0645\u06cc\u200c\u067e\u0630\u06cc\u0631\u0647 \u06a9\u0647 \u0634\u0646\u0627\u0633\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u06cc\u06a9\u0633\u0627\u0646\u060c <code>versionCode<\/code> \u0628\u0632\u0631\u06af\u200c\u062a\u0631 \u0648 \u0627\u0645\u0636\u0627\u06cc \u0645\u0648\u0631\u062f \u0627\u0639\u062a\u0645\u0627\u062f \u0633\u0627\u0632\u06af\u0627\u0631 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Google Play \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f \u0627\u0632 Play App Signing \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u062f\u0631 \u0627\u06cc\u0646 \u0633\u0627\u062e\u062a\u0627\u0631\u060c \u0641\u0627\u06cc\u0644 AAB \u0631\u0648 \u0628\u0627 <strong>Upload Key<\/strong> \u0627\u0645\u0636\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc \u0648 \u0628\u0631\u0627\u06cc \u06af\u0648\u06af\u0644 \u0645\u06cc\u200c\u0641\u0631\u0633\u062a\u06cc\u061b \u0633\u067e\u0633 Google Play \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc \u0646\u0647\u0627\u06cc\u06cc \u062a\u062d\u0648\u06cc\u0644\u06cc \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0631\u0648 \u0628\u0627 <strong>App Signing Key<\/strong> \u0627\u0645\u0636\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 Upload Key \u0648 App Signing Key \u062f\u0648 \u0646\u0642\u0634 \u0645\u062a\u0641\u0627\u0648\u062a \u062f\u0627\u0631\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0633\u0627\u062e\u062a \u0641\u0627\u06cc\u0644 AAB \u0628\u0631\u0627\u06cc Google Play<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0627\u06cc\u0644 AAB \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0645\u062b\u0644 APK \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0646\u0635\u0628 \u0646\u0645\u06cc\u0634\u0647. \u0627\u06cc\u0646 \u0641\u0627\u06cc\u0644 \u0645\u062c\u0645\u0648\u0639\u0647\u200c\u0627\u06cc \u0627\u0632 \u06a9\u062f\u0647\u0627 \u0648 \u0645\u0646\u0627\u0628\u0639 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0633\u062a \u06a9\u0647 Google Play \u0628\u0631 \u0627\u0633\u0627\u0633 \u0645\u062f\u0644 \u062f\u0633\u062a\u06af\u0627\u0647\u060c \u0645\u0639\u0645\u0627\u0631\u06cc \u067e\u0631\u062f\u0627\u0632\u0646\u062f\u0647\u060c \u0632\u0628\u0627\u0646 \u0648 \u062a\u0631\u0627\u06a9\u0645 \u0635\u0641\u062d\u0647\u060c APK\u0647\u0627\u06cc \u0645\u0646\u0627\u0633\u0628 \u0631\u0648 \u0627\u0632 \u062f\u0627\u062e\u0644 \u0627\u0648\u0646 \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f Google Play\u060c \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0627 Android App Bundle \u0627\u0644\u0632\u0627\u0645 \u0627\u0635\u0644\u06cc\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0633\u0627\u062e\u062a \u0641\u0627\u06cc\u0644 \u0627\u0632 \u062f\u0627\u062e\u0644 Android Studio \u0628\u0647 \u0645\u0633\u06cc\u0631 \u0632\u06cc\u0631 \u0645\u06cc\u200c\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Build\n\u2192 Generate Signed Bundle \/ APK\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Build<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\u2192 Generate Signed Bundle <\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #24292E\"> APK<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u067e\u0633 \u06af\u0632\u06cc\u0646\u0647 \u0632\u06cc\u0631 \u0631\u0648 \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Android App Bundle\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0645\u0631\u062d\u0644\u0647 \u0628\u0639\u062f\u060c \u0641\u0627\u06cc\u0644 Keystore\u060c \u0631\u0645\u0632\u060c Alias \u0648 \u0631\u0645\u0632 \u06a9\u0644\u06cc\u062f \u0631\u0648 \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. Build Variant \u0631\u0648 \u0631\u0648\u06cc <code>release<\/code> \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u062f\u06cc\u0645 \u0648 \u0633\u0627\u062e\u062a \u0641\u0627\u06cc\u0644 \u0631\u0648 \u0634\u0631\u0648\u0639 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. \u0628\u0639\u062f \u0627\u0632 \u067e\u0627\u06cc\u0627\u0646 \u0641\u0631\u0627\u06cc\u0646\u062f\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0641\u0627\u06cc\u0644 \u062f\u0631 \u0645\u0633\u06cc\u0631\u06cc \u0645\u0634\u0627\u0628\u0647 \u0627\u06cc\u0646 \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app\/build\/outputs\/bundle\/release\/app-release.aab\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Android Studio \u0628\u0631\u0627\u06cc \u0633\u0627\u062e\u062a \u062e\u0631\u0648\u062c\u06cc \u0627\u0645\u0636\u0627\u0634\u062f\u0647\u060c Wizard \u0645\u062e\u0635\u0648\u0635 <code>Generate Signed Bundle \/ APK<\/code> \u0631\u0648 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc\u062f\u0647 \u0648 \u062e\u0631\u0648\u062c\u06cc Bundle \u0631\u0648 \u062f\u0627\u062e\u0644 \u067e\u0648\u0634\u0647 <code>build\/outputs\/bundle\/<\/code> \u0642\u0631\u0627\u0631 \u0645\u06cc\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u06cc\u0646 \u06a9\u0627\u0631 \u0631\u0648 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0627\u0632 Terminal \u0647\u0645 \u0627\u0646\u062c\u0627\u0645 \u0628\u062f\u06cc\u0645. \u062f\u0631 \u0648\u06cc\u0646\u062f\u0648\u0632:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gradlew.bat bundleRelease\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 macOS \u06cc\u0627 Linux:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/gradlew bundleRelease\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 \u0645\u0648\u0641\u0642\u06cc\u062a Build\u060c \u0641\u0627\u06cc\u0644 \u0631\u0648 \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0633\u06cc\u0631 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app\/build\/outputs\/bundle\/release\/app-release.aab\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0686\u0646\u062f Flavor \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645\u060c \u0646\u0627\u0645 Task \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0645\u062b\u0644\u0627\u064b \u0627\u06af\u0631 Flavor \u0646\u0647\u0627\u06cc\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 <code>production<\/code> \u0628\u0627\u0634\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 Task \u0627\u06cc\u0646 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/gradlew bundleProductionRelease\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u0641\u0627\u06cc\u0644 \u062e\u0631\u0648\u062c\u06cc \u062f\u0631 \u0645\u0633\u06cc\u0631\u06cc \u0645\u0634\u0627\u0628\u0647 \u0627\u06cc\u0646 \u0633\u0627\u062e\u062a\u0647 \u0628\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app\/build\/outputs\/bundle\/productionRelease\/\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u0633\u0627\u062e\u062a \u0641\u0627\u06cc\u0644 APK \u0628\u0631\u0627\u06cc \u062a\u0633\u062a \u0648 \u0645\u0627\u0631\u06a9\u062a\u200c\u0647\u0627\u06cc \u062f\u06cc\u06af\u0631<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"879\" height=\"1024\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-07-1-879x1024.avif\" alt=\"\" class=\"wp-image-6162\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-07-1-879x1024.avif 879w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-07-1-258x300.avif 258w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-07-1-768x894.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-07-1.avif 1162w\" sizes=\"(max-width: 879px) 100vw, 879px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0631\u0648\u06cc \u0648\u0628\u200c\u0633\u0627\u06cc\u062a\u060c \u0627\u0631\u0633\u0627\u0644 \u0641\u0627\u06cc\u0644 \u0628\u0647 \u062a\u0633\u062a\u0631\u0647\u0627 \u06cc\u0627 \u0645\u0627\u0631\u06a9\u062a\u06cc \u06a9\u0647 APK \u0645\u06cc\u200c\u067e\u0630\u06cc\u0631\u0647\u060c \u0628\u0627\u06cc\u062f APK \u0627\u0645\u0636\u0627\u0634\u062f\u0647 Release \u0628\u0633\u0627\u0632\u06cc\u0645. \u0627\u0632 \u062f\u0627\u062e\u0644 Android Studio \u062f\u0648\u0628\u0627\u0631\u0647 \u0648\u0627\u0631\u062f \u0627\u06cc\u0646 \u0645\u0633\u06cc\u0631 \u0645\u06cc\u200c\u0634\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Build\n\u2192 Generate Signed Bundle \/ APK\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Build<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\u2192 Generate Signed Bundle <\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #24292E\"> APK<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0628\u0627\u0631 \u06af\u0632\u06cc\u0646\u0647 \u0632\u06cc\u0631 \u0631\u0648 \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>APK\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 \u0627\u0646\u062a\u062e\u0627\u0628 Keystore \u0648 Variant \u0646\u0633\u062e\u0647 Release\u060c \u0641\u0627\u06cc\u0644 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0633\u06cc\u0631 \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app\/build\/outputs\/apk\/release\/app-release.apk\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0632 \u062e\u0637 \u0641\u0631\u0645\u0627\u0646 \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/gradlew assembleRelease\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0648\u06cc\u0646\u062f\u0648\u0632:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gradlew.bat assembleRelease\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0642\u062a \u06a9\u0646 \u062f\u06a9\u0645\u0647 Run \u062f\u0631 Android Studio \u062e\u0631\u0648\u062c\u06cc \u0645\u0646\u0627\u0633\u0628 \u0627\u0646\u062a\u0634\u0627\u0631 \u0639\u0645\u0648\u0645\u06cc \u062a\u0648\u0644\u06cc\u062f \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647. \u062e\u0631\u0648\u062c\u06cc Run \u0645\u0645\u06a9\u0646\u0647 \u062f\u0627\u0631\u0627\u06cc <code>testOnly<\/code> \u0628\u0627\u0634\u0647 \u0648 \u0641\u0642\u0637 \u0627\u0632 \u0637\u0631\u06cc\u0642 ADB \u0646\u0635\u0628 \u0628\u0634\u0647. \u0628\u0631\u0627\u06cc \u0641\u0627\u06cc\u0644 \u0642\u0627\u0628\u0644 \u062a\u0648\u0632\u06cc\u0639 \u0628\u0627\u06cc\u062f \u0627\u0632 Build APK \u06cc\u0627 Generate Signed Bundle \/ APK \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0642\u0628\u0644 \u0627\u0632 \u0622\u067e\u0644\u0648\u062f\u060c \u0641\u0627\u06cc\u0644 Release \u0631\u0648 \u0648\u0627\u0642\u0639\u0627\u064b \u0646\u0635\u0628 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0627\u06cc\u0644 AAB \u0631\u0648 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0645\u062b\u0644 APK \u0628\u0627\u0632 \u06a9\u0646\u06cc\u0645\u060c \u0627\u0645\u0627 APK Release \u0631\u0648 \u0628\u0627\u06cc\u062f \u0642\u0628\u0644 \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631 \u0631\u0648\u06cc \u06cc\u06a9 \u06af\u0648\u0634\u06cc \u062a\u0645\u06cc\u0632 \u0646\u0635\u0628 \u06a9\u0646\u06cc\u0645. \u0628\u0647\u062a\u0631\u0647 \u0627\u0628\u062a\u062f\u0627 \u0646\u0633\u062e\u0647 Debug \u0631\u0648 \u062d\u0630\u0641 \u06a9\u0646\u06cc\u0645 \u062a\u0627 \u0645\u0637\u0645\u0626\u0646 \u0628\u0634\u06cc\u0645 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0628\u0627\u0642\u06cc\u200c\u0645\u0627\u0646\u062f\u0647\u060c \u0648\u0631\u0648\u062f \u0642\u0628\u0644\u06cc \u06cc\u0627 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u062a\u0648\u0633\u0639\u0647 \u0628\u0627\u0639\u062b \u0645\u062e\u0641\u06cc \u0634\u062f\u0646 \u0628\u0627\u06af\u200c\u0647\u0627 \u0646\u0634\u062f\u0647. \u0633\u067e\u0633 APK \u0631\u0648 \u0628\u0627 ADB \u0646\u0635\u0628 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>adb install app\/build\/outputs\/apk\/release\/app-release.apk\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0646\u0633\u062e\u0647 \u0642\u0628\u0644\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0628\u0627 \u0647\u0645\u0648\u0646 \u0627\u0645\u0636\u0627 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0646\u0635\u0628 \u0634\u062f\u0647 \u0648 \u0641\u0642\u0637 \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc\u0645 \u0622\u067e\u062f\u06cc\u062a\u0634 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>adb install -r app\/build\/outputs\/apk\/release\/app-release.apk\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0628\u0627 \u062e\u0637\u0627\u06cc\u06cc \u0634\u0628\u06cc\u0647 <code>INSTALL_FAILED_UPDATE_INCOMPATIBLE<\/code> \u0631\u0648\u0628\u0647\u200c\u0631\u0648 \u0634\u062f\u06cc\u0645\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0646\u0633\u062e\u0647 \u0646\u0635\u0628\u200c\u0634\u062f\u0647 \u0628\u0627 \u06a9\u0644\u06cc\u062f \u0645\u062a\u0641\u0627\u0648\u062a\u06cc \u0627\u0645\u0636\u0627 \u0634\u062f\u0647. \u0645\u062b\u0644\u0627\u064b \u0646\u0633\u062e\u0647 Debug \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0646\u0635\u0628\u0647\u060c \u0627\u0645\u0627 \u062d\u0627\u0644\u0627 APK Release \u0631\u0648 \u0628\u0627 \u0647\u0645\u0648\u0646 <code>applicationId<\/code> \u0646\u0635\u0628 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. \u062f\u0631 \u0627\u06cc\u0646 \u062d\u0627\u0644\u062a \u06cc\u0627 \u0628\u0627\u06cc\u062f \u0646\u0633\u062e\u0647 \u0642\u0628\u0644\u06cc \u062d\u0630\u0641 \u0628\u0634\u0647 \u06cc\u0627 \u0628\u0631\u0627\u06cc Debug \u0627\u0632 <code>applicationIdSuffix<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0633\u062e\u0647 Release \u0631\u0648 \u0641\u0642\u0637 \u0628\u0627\u0632 \u0646\u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0648 \u0628\u06af\u06cc\u0645 \u00ab\u0627\u062c\u0631\u0627 \u0634\u062f\u060c \u067e\u0633 \u0633\u0627\u0644\u0645\u0647\u00bb. \u0628\u0627\u06cc\u062f \u0645\u0633\u06cc\u0631\u0647\u0627\u06cc \u0627\u0635\u0644\u06cc \u0631\u0648 \u06a9\u0627\u0645\u0644 \u0622\u0632\u0645\u0627\u06cc\u0634 \u06a9\u0646\u06cc\u0645: \u062b\u0628\u062a\u200c\u0646\u0627\u0645\u060c \u0648\u0631\u0648\u062f\u060c \u062e\u0631\u0648\u062c\u060c \u0627\u0641\u0632\u0648\u062f\u0646 \u0645\u062d\u0635\u0648\u0644\u060c \u062f\u0631\u06cc\u0627\u0641\u062a \u0642\u06cc\u0645\u062a\u060c \u0627\u0639\u0644\u0627\u0646 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a\u060c \u0628\u0627\u0632 \u06a9\u0631\u062f\u0646 Deep Link\u060c \u062d\u0627\u0644\u062a \u0628\u062f\u0648\u0646 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a\u060c \u0645\u0646\u0642\u0636\u06cc \u0634\u062f\u0646 Token\u060c \u0622\u067e\u0644\u0648\u062f \u0639\u06a9\u0633\u060c \u0627\u062c\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0639\u062f \u0627\u0632 \u0628\u0633\u062a\u0647 \u0634\u062f\u0646 \u06a9\u0627\u0645\u0644\u060c \u062f\u0631\u06cc\u0627\u0641\u062a \u0627\u0639\u0644\u0627\u0646 \u062f\u0631 Foreground \u0648 Background \u0648 \u0631\u0641\u062a\u0646 \u0627\u0632 \u0627\u0639\u0644\u0627\u0646 \u0628\u0647 \u0635\u0641\u062d\u0647 \u062f\u0631\u0633\u062a. \u0627\u06af\u0631 R8 \u0641\u0639\u0627\u0644\u0647\u060c \u0628\u0627\u06cc\u062f \u0628\u062e\u0634\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0628\u0627 Reflection\u060c Serialization \u06cc\u0627 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc \u062e\u0627\u0635 \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646 \u0647\u0645 \u0628\u0631\u0631\u0633\u06cc \u0628\u0634\u0646\u061b \u0686\u0648\u0646 \u0627\u062d\u062a\u0645\u0627\u0644 \u062f\u0627\u0631\u0647 \u0646\u0633\u062e\u0647 Debug \u0633\u0627\u0644\u0645 \u0628\u0627\u0634\u0647 \u0627\u0645\u0627 Release Crash \u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u06a9\u0646\u062a\u0631\u0644 \u0644\u0627\u06af\u200c\u0647\u0627 \u0648 \u0622\u062f\u0631\u0633 \u0633\u0631\u0648\u0631 \u062f\u0631 \u0646\u0633\u062e\u0647 \u0646\u0647\u0627\u06cc\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0628\u0627\u06cc\u062f \u0646\u0633\u062e\u0647 \u0646\u0647\u0627\u06cc\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0628\u0647 \u0633\u0631\u0648\u0631 \u062a\u0633\u062a \u06cc\u0627 Localhost \u0645\u062a\u0635\u0644 \u0628\u0627\u0634\u0647. \u06cc\u06a9\u06cc \u0627\u0632 \u0628\u0647\u062a\u0631\u06cc\u0646 \u0631\u0627\u0647\u200c\u0647\u0627 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0622\u062f\u0631\u0633 API \u0631\u0648 \u0628\u0631 \u0627\u0633\u0627\u0633 Build Type \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>android {\n    buildTypes {\n        debug {\n            buildConfigField(\n                \"String\",\n                \"BASE_URL\",\n                \"\\\"https:\/\/staging-api.gheimatban.com\/\\\"\"\n            )\n        }\n\n        release {\n            buildConfigField(\n                \"String\",\n                \"BASE_URL\",\n                \"\\\"https:\/\/api.gheimatban.com\/\\\"\"\n            )\n        }\n    }\n\n    buildFeatures {\n        buildConfig = true\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">android<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">buildTypes<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">debug<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">buildConfigField<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;String&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;BASE_URL&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;<\/span><span style=\"color: #005CC5\">\\&quot;<\/span><span style=\"color: #032F62\">https:\/\/staging-api.gheimatban.com\/<\/span><span style=\"color: #005CC5\">\\&quot;<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">release<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">buildConfigField<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;String&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;BASE_URL&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;<\/span><span style=\"color: #005CC5\">\\&quot;<\/span><span style=\"color: #032F62\">https:\/\/api.gheimatban.com\/<\/span><span style=\"color: #005CC5\">\\&quot;<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">buildFeatures<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        buildConfig <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u062f\u0631 Retrofit \u0627\u0632 \u0647\u0645\u06cc\u0646 \u0645\u0642\u062f\u0627\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val retrofit = Retrofit.Builder()\n    .baseUrl(BuildConfig.BASE_URL)\n    .addConverterFactory(\n        GsonConverterFactory.create()\n    )\n    .build()\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> retrofit <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> Retrofit.<\/span><span style=\"color: #6F42C1\">Builder<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    .<\/span><span style=\"color: #6F42C1\">baseUrl<\/span><span style=\"color: #24292E\">(BuildConfig.BASE_URL)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    .<\/span><span style=\"color: #6F42C1\">addConverterFactory<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        GsonConverterFactory.<\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0644\u0627\u06af\u200c\u0647\u0627 \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u06cc\u06a9 Wrapper \u0633\u0627\u062f\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>object AppLogger {\n\n    fun d(tag: String, message: String) {\n        if (BuildConfig.DEBUG) {\n            Log.d(tag, message)\n        }\n    }\n\n    fun e(\n        tag: String,\n        message: String,\n        throwable: Throwable? = null\n    ) {\n        if (BuildConfig.DEBUG) {\n            Log.e(tag, message, throwable)\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AppLogger<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">, message: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (BuildConfig.DEBUG) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(tag, message)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        message: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        throwable: <\/span><span style=\"color: #6F42C1\">Throwable<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (BuildConfig.DEBUG) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Log.<\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(tag, message, throwable)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0644\u0628\u062a\u0647 \u062e\u0637\u0627\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc \u0646\u0633\u062e\u0647 Release \u0631\u0648 \u0646\u0628\u0627\u06cc\u062f \u06a9\u0627\u0645\u0644\u0627\u064b \u0646\u0627\u062f\u06cc\u062f\u0647 \u0628\u06af\u06cc\u0631\u06cc\u0645. \u0628\u0647\u200c\u062c\u0627\u06cc \u0686\u0627\u067e Token\u060c \u0634\u0645\u0627\u0631\u0647 \u062a\u0644\u0641\u0646 \u06cc\u0627 \u067e\u0627\u0633\u062e \u06a9\u0627\u0645\u0644 \u0633\u0631\u0648\u0631 \u062f\u0631 Logcat\u060c \u0628\u0647\u062a\u0631\u0647 Crash\u0647\u0627 \u0648 \u062e\u0637\u0627\u0647\u0627\u06cc \u06a9\u0646\u062a\u0631\u0644\u200c\u0634\u062f\u0647 \u0631\u0648 \u0628\u0627 \u0627\u0628\u0632\u0627\u0631\u06cc \u0645\u062b\u0644 Firebase Crashlytics \u062b\u0628\u062a \u06a9\u0646\u06cc\u0645. \u0645\u0648\u0636\u0648\u0639 Crash Reporting \u0631\u0648 \u062f\u0631 \u062f\u0631\u0633 \u062c\u062f\u0627\u06af\u0627\u0646\u0647 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0628\u0631\u0631\u0633\u06cc \u0634\u0646\u0627\u0633\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u0645\u062c\u0648\u0632\u0647\u0627 \u0648 Manifest \u0646\u0647\u0627\u06cc\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0642\u0628\u0644 \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0627\u06cc\u062f Manifest \u0627\u062f\u063a\u0627\u0645\u200c\u0634\u062f\u0647 \u0631\u0648 \u0647\u0645 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645. \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 Permission\u0647\u0627\u060c Service\u0647\u0627\u060c Receiver\u0647\u0627 \u0648 Provider\u0647\u0627\u06cc \u062e\u0648\u062f\u0634\u0648\u0646 \u0631\u0648 \u0628\u0647 Manifest \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u0646. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0641\u0642\u0637 \u0646\u06af\u0627\u0647 \u06a9\u0631\u062f\u0646 \u0628\u0647 \u0641\u0627\u06cc\u0644 <code>AndroidManifest.xml<\/code> \u067e\u0631\u0648\u0698\u0647 \u06a9\u0627\u0641\u06cc \u0646\u06cc\u0633\u062a. \u062f\u0631 Android Studio \u0641\u0627\u06cc\u0644 Manifest \u0631\u0648 \u0628\u0627\u0632 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0648 \u062a\u0628 <strong>Merged Manifest<\/strong> \u0631\u0648 \u0645\u06cc\u200c\u0628\u06cc\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0645\u0645\u06a9\u0646\u0647 \u0627\u06cc\u0646 \u0645\u062c\u0648\u0632\u0647\u0627 \u0644\u0627\u0632\u0645 \u0628\u0627\u0634\u0646:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;uses-permission\n    android:name=\"android.permission.INTERNET\" \/>\n\n&lt;uses-permission\n    android:name=\"android.permission.ACCESS_NETWORK_STATE\" \/>\n\n&lt;uses-permission\n    android:name=\"android.permission.POST_NOTIFICATIONS\" \/>\n\n&lt;uses-permission\n    android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\" \/>\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">uses<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">permission<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    android:<\/span><span style=\"color: #6F42C1\">name<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #032F62\">&quot;android.permission.INTERNET&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">\/&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">uses<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">permission<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    android:<\/span><span style=\"color: #6F42C1\">name<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #032F62\">&quot;android.permission.ACCESS_NETWORK_STATE&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">\/&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">uses<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">permission<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    android:<\/span><span style=\"color: #6F42C1\">name<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #032F62\">&quot;android.permission.POST_NOTIFICATIONS&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">\/&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">uses<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">permission<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    android:<\/span><span style=\"color: #6F42C1\">name<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #032F62\">&quot;android.permission.RECEIVE_BOOT_COMPLETED&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">\/&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0627\u06af\u0631 Permission \u062d\u0633\u0627\u0633\u06cc \u0645\u06cc\u200c\u0628\u06cc\u0646\u06cc \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648\u0627\u0642\u0639\u0627\u064b \u0628\u0647\u0634 \u0646\u06cc\u0627\u0632 \u0646\u062f\u0627\u0631\u0647\u060c \u0646\u0628\u0627\u06cc\u062f \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0631\u0627\u062d\u062a\u06cc \u0646\u06af\u0647\u0634 \u062f\u0627\u0631\u06cc. \u0645\u0627\u0631\u06a9\u062a\u200c\u0647\u0627 \u0645\u0645\u06a9\u0646\u0647 \u062f\u0631\u0628\u0627\u0631\u0647 \u062f\u0633\u062a\u0631\u0633\u06cc\u200c\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 \u0645\u0648\u0642\u0639\u06cc\u062a \u0645\u06a9\u0627\u0646\u06cc\u060c SMS\u060c \u062a\u0645\u0627\u0633\u200c\u0647\u0627\u060c \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u060c \u062f\u0648\u0631\u0628\u06cc\u0646\u060c \u0645\u06cc\u06a9\u0631\u0648\u0641\u0648\u0646 \u06cc\u0627 \u0646\u0635\u0628 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u0646\u0627\u0634\u0646\u0627\u0633 \u062a\u0648\u0636\u06cc\u062d \u0648 \u0645\u0633\u062a\u0646\u062f\u0627\u062a \u0628\u06cc\u0634\u062a\u0631\u06cc \u0628\u062e\u0648\u0627\u0646. \u0639\u0644\u0627\u0648\u0647 \u0628\u0631 \u0627\u0648\u0646\u060c \u062c\u0645\u0639\u200c\u0622\u0648\u0631\u06cc \u062f\u0627\u062f\u0647 \u0628\u0627\u06cc\u062f \u0628\u0627 \u0639\u0645\u0644\u06a9\u0631\u062f \u0648\u0627\u0642\u0639\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u0635\u0641\u062d\u0647 Privacy Policy \u0648 \u0641\u0631\u0645\u200c\u0647\u0627\u06cc Data Safety \u0647\u0645\u0627\u0647\u0646\u06af \u0628\u0627\u0634\u0647. Google Play \u0645\u0633\u0626\u0648\u0644\u06cc\u062a \u0627\u0639\u0644\u0627\u0645 \u062f\u0631\u0633\u062a \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u062c\u0645\u0639\u200c\u0622\u0648\u0631\u06cc\u200c\u0634\u062f\u0647 \u062a\u0648\u0633\u0637 \u062e\u0648\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0648 SDK\u0647\u0627\u06cc \u062c\u0627\u0646\u0628\u06cc \u0631\u0648 \u0628\u0631 \u0639\u0647\u062f\u0647 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0642\u0631\u0627\u0631 \u0645\u06cc\u062f\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0633\u0627\u062e\u062a \u062d\u0633\u0627\u0628 \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 Google Play Console<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 \u0633\u0627\u062e\u062a \u062d\u0633\u0627\u0628 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647\u060c \u0648\u0627\u0631\u062f Play Console \u0645\u06cc\u200c\u0634\u06cc\u0645 \u0648 \u06af\u0632\u06cc\u0646\u0647 <strong>Create app<\/strong> \u0631\u0648 \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0631\u062d\u0644\u0647 \u0632\u0628\u0627\u0646 \u0627\u0635\u0644\u06cc\u060c \u0646\u0627\u0645 \u0646\u0645\u0627\u06cc\u0634\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u0646\u0648\u0639 App \u06cc\u0627 Game\u060c \u0631\u0627\u06cc\u06af\u0627\u0646 \u06cc\u0627 \u067e\u0648\u0644\u06cc \u0628\u0648\u062f\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648 \u0627\u06cc\u0645\u06cc\u0644 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u0631\u0648 \u062a\u0639\u06cc\u06cc\u0646 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. \u0647\u0645\u0686\u0646\u06cc\u0646 \u0628\u0627\u06cc\u062f \u0642\u0648\u0627\u0646\u06cc\u0646 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u06af\u0627\u0646\u060c \u0645\u0642\u0631\u0631\u0627\u062a \u0635\u0627\u062f\u0631\u0627\u062a \u0648 \u0634\u0631\u0627\u06cc\u0637 Play App Signing \u0631\u0648 \u062a\u0623\u06cc\u06cc\u062f \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u067e\u0631\u0648\u0698\u0647 \u0645\u0627 \u0646\u0627\u0645 \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0627\u06cc\u0646 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Package Name \u0627\u0632 \u062f\u0627\u062e\u0644 \u0641\u0627\u06cc\u0644 AAB \u062e\u0648\u0646\u062f\u0647 \u0645\u06cc\u0634\u0647 \u0648 \u0628\u0639\u062f \u0627\u0632 \u0627\u0648\u0644\u06cc\u0646 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0628\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u062a\u0635\u0644 \u062e\u0648\u0627\u0647\u062f \u0634\u062f:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>com.gheimatban.app\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0627\u0645 \u0646\u0645\u0627\u06cc\u0634\u06cc \u0628\u0639\u062f\u0627\u064b \u0642\u0627\u0628\u0644 \u0648\u06cc\u0631\u0627\u06cc\u0634\u0647\u060c \u0627\u0645\u0627 Package Name \u0631\u0648 \u0646\u0628\u0627\u06cc\u062f \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u0648\u0642\u062a \u062f\u0631 \u0646\u0638\u0631 \u0628\u06af\u06cc\u0631\u06cc. \u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644 \u0627\u06af\u0631 \u0641\u0627\u06cc\u0644 \u0622\u0632\u0645\u0627\u06cc\u0634\u06cc \u0631\u0648 \u0628\u0627 \u0634\u0646\u0627\u0633\u0647 \u0632\u06cc\u0631 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u06a9\u0646\u06cc:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>com.example.gheimatban\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f\u0627\u064b \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0647\u0645\u0648\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u062b\u0628\u062a\u200c\u0634\u062f\u0647 \u0631\u0648 \u0628\u0647 \u0627\u06cc\u0646 \u0634\u0646\u0627\u0633\u0647 \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0646\u06cc:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>com.gheimatban.app\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062c\u0628\u0648\u0631 \u0645\u06cc\u0634\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u0627\u0632\u0647\u200c\u0627\u06cc \u062f\u0631 \u067e\u0646\u0644 \u0628\u0633\u0627\u0632\u06cc.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0635\u0641\u062d\u0647 \u0645\u0639\u0631\u0641\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 Google Play<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0642\u0628\u0644 \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631 \u0639\u0645\u0648\u0645\u06cc \u0628\u0627\u06cc\u062f Store Listing \u0631\u0648 \u06a9\u0627\u0645\u0644 \u06a9\u0646\u06cc\u0645. \u0635\u0641\u062d\u0647 \u0645\u0639\u0631\u0641\u06cc \u0641\u0642\u0637 \u06cc\u06a9 \u0641\u0631\u0645 \u0627\u062f\u0627\u0631\u06cc \u0646\u06cc\u0633\u062a\u061b \u0648\u06cc\u062a\u0631\u06cc\u0646 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0647. \u06a9\u0627\u0631\u0628\u0631 \u0642\u0628\u0644 \u0627\u0632 \u0646\u0635\u0628\u060c \u0646\u0627\u0645\u060c \u0622\u06cc\u06a9\u0648\u0646\u060c \u062a\u0648\u0636\u06cc\u062d\u0627\u062a\u060c \u062a\u0635\u0627\u0648\u06cc\u0631\u060c \u0627\u0645\u062a\u06cc\u0627\u0632 \u0648 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0631\u06cc\u0645 \u062e\u0635\u0648\u0635\u06cc \u0631\u0648 \u0645\u06cc\u200c\u0628\u06cc\u0646\u0647 \u0648 \u0628\u0631 \u0627\u0633\u0627\u0633 \u0627\u0648\u0646\u200c\u0647\u0627 \u062a\u0635\u0645\u06cc\u0645 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0648\u0636\u06cc\u062d \u06a9\u0648\u062a\u0627\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0686\u06cc\u0632\u06cc \u0634\u0628\u06cc\u0647 \u0627\u06cc\u0646 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u0642\u06cc\u0645\u062a \u06a9\u0627\u0644\u0627\u0647\u0627 \u0631\u0648 \u062f\u0646\u0628\u0627\u0644 \u06a9\u0646 \u0648 \u0627\u0632 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a\u200c\u0647\u0627 \u0628\u0627\u062e\u0628\u0631 \u0634\u0648.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0648\u0636\u06cc\u062d \u06a9\u0627\u0645\u0644 \u0628\u0627\u06cc\u062f \u0628\u0647\u200c\u062c\u0627\u06cc \u0634\u0639\u0627\u0631\u0647\u0627\u06cc \u0645\u0628\u0647\u0645\u060c \u0645\u0633\u0626\u0644\u0647 \u0648 \u0627\u0645\u06a9\u0627\u0646\u0627\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0631\u0648\u0634\u0646 \u062a\u0648\u0636\u06cc\u062d \u0628\u062f\u0647:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0628\u0647 \u0634\u0645\u0627 \u06a9\u0645\u06a9 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0645\u0648\u0631\u062f\u0646\u0638\u0631\u062a\u0627\u0646 \u0631\u0627\n\u062f\u0646\u0628\u0627\u0644 \u06a9\u0646\u06cc\u062f \u0648 \u0647\u0646\u06af\u0627\u0645 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a\u060c \u0627\u0639\u0644\u0627\u0646 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u06cc\u062f.\n\n\u0628\u0627 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f:\n\n\u2022 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0645\u0648\u0631\u062f\u0639\u0644\u0627\u0642\u0647\u200c\u062a\u0627\u0646 \u0631\u0627 \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0646\u06cc\u062f.\n\u2022 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0642\u06cc\u0645\u062a \u0631\u0627 \u0645\u0634\u0627\u0647\u062f\u0647 \u06a9\u0646\u06cc\u062f.\n\u2022 \u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a \u0647\u062f\u0641 \u062a\u0639\u06cc\u06cc\u0646 \u06a9\u0646\u06cc\u062f.\n\u2022 \u0647\u0646\u06af\u0627\u0645 \u0631\u0633\u06cc\u062f\u0646 \u0645\u062d\u0635\u0648\u0644 \u0628\u0647 \u0642\u06cc\u0645\u062a \u062f\u0644\u062e\u0648\u0627\u0647 \u0627\u0639\u0644\u0627\u0646 \u0628\u06af\u06cc\u0631\u06cc\u062f.\n\u2022 \u0641\u0647\u0631\u0633\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0627 \u0628\u06cc\u0646 \u062f\u0633\u062a\u06af\u0627\u0647\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0647\u0645\u06af\u0627\u0645 \u06a9\u0646\u06cc\u062f.\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0633\u06a9\u0631\u06cc\u0646\u200c\u0634\u0627\u062a\u200c\u0647\u0627 \u0647\u0645 \u0646\u0628\u0627\u06cc\u062f \u0641\u0642\u0637 \u062a\u0635\u0627\u0648\u06cc\u0631 \u062e\u0627\u0645 \u0648 \u0646\u0627\u0645\u0641\u0647\u0648\u0645 \u0628\u0627\u0634\u0646. \u0628\u0647\u062a\u0631\u0647 \u0647\u0631 \u062a\u0635\u0648\u06cc\u0631 \u06cc\u06a9 \u0642\u0627\u0628\u0644\u06cc\u062a \u0645\u0634\u062e\u0635 \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647: \u0635\u0641\u062d\u0647 \u067e\u06cc\u06af\u06cc\u0631\u06cc \u0645\u062d\u0635\u0648\u0644\u0627\u062a\u060c \u0646\u0645\u0648\u062f\u0627\u0631 \u062a\u063a\u06cc\u06cc\u0631 \u0642\u06cc\u0645\u062a\u060c \u0633\u0627\u062e\u062a \u0647\u0634\u062f\u0627\u0631\u060c \u0627\u0639\u0644\u0627\u0646 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0648 \u0635\u0641\u062d\u0647 \u062c\u0632\u0626\u06cc\u0627\u062a \u0645\u062d\u0635\u0648\u0644. \u0645\u062a\u0646 \u0631\u0648\u06cc \u062a\u0635\u0648\u06cc\u0631 \u0628\u0627\u06cc\u062f \u06a9\u0648\u062a\u0627\u0647 \u0648 \u062e\u0648\u0627\u0646\u0627 \u0628\u0627\u0634\u0647. \u0622\u06cc\u06a9\u0648\u0646\u060c \u062a\u0635\u0627\u0648\u06cc\u0631 \u0648 \u0627\u0628\u0639\u0627\u062f \u0645\u0648\u0631\u062f\u0646\u06cc\u0627\u0632 \u0645\u0645\u06a9\u0646\u0647 \u062f\u0631 \u0637\u0648\u0644 \u0632\u0645\u0627\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0646\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0639\u062f\u062f\u0647\u0627 \u0648 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a\u200c\u0647\u0627\u06cc \u062f\u0642\u06cc\u0642 \u0631\u0648 \u0645\u0648\u0642\u0639 \u0627\u0646\u062a\u0634\u0627\u0631 \u0627\u0632 \u062e\u0648\u062f Play Console \u0628\u06af\u06cc\u0631\u060c \u0646\u0647 \u0627\u0632 \u06cc\u06a9 \u0645\u0642\u0627\u0644\u0647 \u0642\u062f\u06cc\u0645\u06cc.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Privacy Policy \u0648 \u062d\u0630\u0641 \u062d\u0633\u0627\u0628 \u06a9\u0627\u0631\u0628\u0631\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u062d\u0633\u0627\u0628 \u06a9\u0627\u0631\u0628\u0631\u06cc \u062f\u0627\u0631\u0647\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0630\u062e\u06cc\u0631\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0628\u0647 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0645\u062a\u0635\u0644\u0647 \u0648 \u0627\u062d\u062a\u0645\u0627\u0644\u0627\u064b \u0627\u0632 Firebase \u0628\u0631\u0627\u06cc \u0627\u0639\u0644\u0627\u0646 \u06cc\u0627 \u062a\u062d\u0644\u06cc\u0644 \u062e\u0637\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u067e\u0633 \u0628\u0627\u06cc\u062f \u06cc\u06a9 Privacy Policy \u0648\u0627\u0642\u0639\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645. \u0627\u06cc\u0646 \u0635\u0641\u062d\u0647 \u0646\u0628\u0627\u06cc\u062f \u0686\u0646\u062f \u062c\u0645\u0644\u0647 \u0639\u0645\u0648\u0645\u06cc \u0628\u0627\u0634\u0647 \u06a9\u0647 \u0627\u0632 \u0633\u0627\u06cc\u062a \u062f\u06cc\u06af\u0631\u06cc \u06a9\u067e\u06cc \u0634\u062f\u0647. \u0628\u0627\u06cc\u062f \u0645\u0634\u062e\u0635 \u06a9\u0646\u0647 \u0686\u0647 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc\u06cc \u062c\u0645\u0639 \u0645\u06cc\u0634\u0646\u060c \u0686\u0631\u0627 \u062c\u0645\u0639 \u0645\u06cc\u0634\u0646\u060c \u06a9\u062c\u0627 \u0630\u062e\u06cc\u0631\u0647 \u0645\u06cc\u0634\u0646\u060c \u0628\u0627 \u0686\u0647 \u0633\u0631\u0648\u06cc\u0633\u200c\u0647\u0627\u06cc\u06cc \u0628\u0647 \u0627\u0634\u062a\u0631\u0627\u06a9 \u06af\u0630\u0627\u0634\u062a\u0647 \u0645\u06cc\u0634\u0646\u060c \u0686\u0637\u0648\u0631 \u0645\u062d\u0627\u0641\u0638\u062a \u0645\u06cc\u0634\u0646\u060c \u0686\u0647 \u0645\u062f\u062a \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0645\u06cc\u0634\u0646 \u0648 \u06a9\u0627\u0631\u0628\u0631 \u0686\u0637\u0648\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062d\u0630\u0641 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u0634 \u0631\u0648 \u062b\u0628\u062a \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0637\u0628\u0642 \u0633\u06cc\u0627\u0633\u062a \u0641\u0639\u0644\u06cc Google Play\u060c \u0647\u0645\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627 \u0628\u0627\u06cc\u062f \u0644\u06cc\u0646\u06a9 Privacy Policy \u0631\u0648 \u062f\u0631 Play Console \u062b\u0628\u062a \u06a9\u0646\u0646 \u0648 \u0645\u062a\u0646 \u06cc\u0627 \u0644\u06cc\u0646\u06a9 \u0627\u0648\u0646 \u0631\u0648 \u062f\u0627\u062e\u0644 \u062e\u0648\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645 \u062f\u0631 \u062f\u0633\u062a\u0631\u0633 \u0642\u0631\u0627\u0631 \u0628\u062f\u0646. \u062d\u062a\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0627\u06cc \u06a9\u0647 \u062f\u0627\u062f\u0647 \u0634\u062e\u0635\u06cc \u062c\u0645\u0639 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647 \u0647\u0645 \u0628\u0627\u06cc\u062f \u0641\u0631\u0645 \u0645\u0631\u0628\u0648\u0637 \u0631\u0648 \u062a\u06a9\u0645\u06cc\u0644 \u0648 Privacy Policy \u0627\u0631\u0627\u0626\u0647 \u06a9\u0646\u0647. \u0644\u06cc\u0646\u06a9 \u0628\u0627\u06cc\u062f \u0639\u0645\u0648\u0645\u06cc\u060c \u0641\u0639\u0627\u0644 \u0648 \u0642\u0627\u0628\u0644 \u062f\u0633\u062a\u0631\u0633\u06cc \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u062f\u0627\u062e\u0644 \u0635\u0641\u062d\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u06af\u0632\u06cc\u0646\u0647\u200c\u0627\u06cc \u0628\u0631\u0627\u06cc \u0628\u0627\u0632 \u06a9\u0631\u062f\u0646 Privacy Policy \u0642\u0631\u0627\u0631 \u0628\u062f\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun openPrivacyPolicy(context: Context) {\n    val intent = Intent(\n        Intent.ACTION_VIEW,\n        Uri.parse(\n            \"https:\/\/gheimatban.com\/privacy-policy\"\n        )\n    )\n\n    context.startActivity(intent)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">openPrivacyPolicy<\/span><span style=\"color: #24292E\">(context: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> intent <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Intent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Intent.ACTION_VIEW,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Uri.<\/span><span style=\"color: #6F42C1\">parse<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;https:\/\/gheimatban.com\/privacy-policy&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    context.<\/span><span style=\"color: #6F42C1\">startActivity<\/span><span style=\"color: #24292E\">(intent)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u062f\u0631 Compose:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>TextButton(\n    onClick = {\n        openPrivacyPolicy(context)\n    }\n) {\n    Text(\"\u0633\u06cc\u0627\u0633\u062a \u062d\u0641\u0638 \u062d\u0631\u06cc\u0645 \u062e\u0635\u0648\u0635\u06cc\")\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">TextButton<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onClick <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">openPrivacyPolicy<\/span><span style=\"color: #24292E\">(context)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">Text<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;\u0633\u06cc\u0627\u0633\u062a \u062d\u0641\u0638 \u062d\u0631\u06cc\u0645 \u062e\u0635\u0648\u0635\u06cc&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0628\u062a\u0648\u0646\u0647 \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u062d\u0633\u0627\u0628 \u0628\u0633\u0627\u0632\u0647\u060c Google Play \u0627\u0644\u0632\u0627\u0645 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0645\u0633\u06cc\u0631 \u0642\u0627\u0628\u0644\u200c\u062f\u0633\u062a\u0631\u0633\u06cc \u0628\u0631\u0627\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062d\u0630\u0641 \u062d\u0633\u0627\u0628 \u0648 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0645\u0631\u062a\u0628\u0637 \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u061b \u0627\u06cc\u0646 \u0645\u0633\u06cc\u0631 \u0628\u0627\u06cc\u062f \u0647\u0645 \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648 \u0647\u0645 \u0627\u0632 \u0637\u0631\u06cc\u0642 \u06cc\u06a9 \u0645\u0646\u0628\u0639 \u0648\u0628 \u062f\u0631 \u062f\u0633\u062a\u0631\u0633 \u0628\u0627\u0634\u0647. \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0646 \u0645\u0648\u0642\u062a \u062d\u0633\u0627\u0628 \u062c\u0627\u06cc \u062d\u0630\u0641 \u0648\u0627\u0642\u0639\u06cc \u0631\u0648 \u0646\u0645\u06cc\u200c\u06af\u06cc\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644\u060c \u062f\u0631 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u06a9\u0645\u0647 \u062d\u0630\u0641 \u062d\u0633\u0627\u0628 \u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface AccountApi {\n\n    @DELETE(\"account\")\n    suspend fun deleteAccount(): Response&lt;Unit>\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AccountApi<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@DELETE<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;account&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">deleteAccount<\/span><span style=\"color: #24292E\">(): <\/span><span style=\"color: #6F42C1\">Response<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Unit<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u062f\u0631 ViewModel:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class SettingsViewModel(\n    private val accountApi: AccountApi,\n    private val tokenStorage: TokenStorage\n) : ViewModel() {\n\n    private val _deleteState =\n        MutableStateFlow&lt;DeleteAccountState>(\n            DeleteAccountState.Idle\n        )\n\n    val deleteState =\n        _deleteState.asStateFlow()\n\n    fun deleteAccount() {\n        viewModelScope.launch {\n            _deleteState.value =\n                DeleteAccountState.Loading\n\n            try {\n                val response =\n                    accountApi.deleteAccount()\n\n                if (response.isSuccessful) {\n                    tokenStorage.clear()\n\n                    _deleteState.value =\n                        DeleteAccountState.Success\n                } else {\n                    _deleteState.value =\n                        DeleteAccountState.Error(\n                            \"\u062d\u0630\u0641 \u062d\u0633\u0627\u0628 \u0627\u0646\u062c\u0627\u0645 \u0646\u0634\u062f.\"\n                        )\n                }\n            } catch (exception: Exception) {\n                _deleteState.value =\n                    DeleteAccountState.Error(\n                        \"\u0627\u0631\u062a\u0628\u0627\u0637 \u0628\u0627 \u0633\u0631\u0648\u0631 \u0628\u0631\u0642\u0631\u0627\u0631 \u0646\u0634\u062f.\"\n                    )\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">SettingsViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> accountApi: <\/span><span style=\"color: #6F42C1\">AccountApi<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> tokenStorage: <\/span><span style=\"color: #6F42C1\">TokenStorage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ViewModel<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> _deleteState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">MutableStateFlow<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">DeleteAccountState<\/span><span style=\"color: #24292E\">&gt;(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            DeleteAccountState.Idle<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> deleteState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        _deleteState.<\/span><span style=\"color: #6F42C1\">asStateFlow<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">deleteAccount<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModelScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            _deleteState.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                DeleteAccountState.Loading<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> response <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    accountApi.<\/span><span style=\"color: #6F42C1\">deleteAccount<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (response.isSuccessful) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    tokenStorage.<\/span><span style=\"color: #6F42C1\">clear<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    _deleteState.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        DeleteAccountState.Success<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    _deleteState.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        DeleteAccountState.<\/span><span style=\"color: #6F42C1\">Error<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            <\/span><span style=\"color: #032F62\">&quot;\u062d\u0630\u0641 \u062d\u0633\u0627\u0628 \u0627\u0646\u062c\u0627\u0645 \u0646\u0634\u062f.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            } <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (exception: <\/span><span style=\"color: #6F42C1\">Exception<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                _deleteState.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    DeleteAccountState.<\/span><span style=\"color: #6F42C1\">Error<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        <\/span><span style=\"color: #032F62\">&quot;\u0627\u0631\u062a\u0628\u0627\u0637 \u0628\u0627 \u0633\u0631\u0648\u0631 \u0628\u0631\u0642\u0631\u0627\u0631 \u0646\u0634\u062f.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 State \u0645\u0631\u0628\u0648\u0637:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>sealed interface DeleteAccountState {\n\n    data object Idle : DeleteAccountState\n\n    data object Loading : DeleteAccountState\n\n    data object Success : DeleteAccountState\n\n    data class Error(\n        val message: String\n    ) : DeleteAccountState\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">sealed<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DeleteAccountState<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Idle<\/span><span style=\"color: #24292E\"> : <\/span><span style=\"color: #6F42C1\">DeleteAccountState<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Loading<\/span><span style=\"color: #24292E\"> : <\/span><span style=\"color: #6F42C1\">DeleteAccountState<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Success<\/span><span style=\"color: #24292E\"> : <\/span><span style=\"color: #6F42C1\">DeleteAccountState<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Error<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> message: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">DeleteAccountState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u0645\u062a \u0633\u0631\u0648\u0631 \u0647\u0645 \u0646\u0628\u0627\u06cc\u062f \u0641\u0642\u0637 Token \u0631\u0648 \u0628\u0627\u0637\u0644 \u06a9\u0646\u0647. \u0628\u0627\u06cc\u062f \u0637\u0628\u0642 \u0633\u06cc\u0627\u0633\u062a \u0627\u0639\u0644\u0627\u0645\u200c\u0634\u062f\u0647\u060c \u062d\u0633\u0627\u0628 \u0648 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0645\u0631\u062a\u0628\u0637 \u0631\u0648 \u062d\u0630\u0641 \u06cc\u0627 \u062f\u0631 \u0645\u0648\u0627\u0631\u062f\u06cc \u06a9\u0647 \u0642\u0627\u0646\u0648\u0646 \u0627\u062c\u0627\u0632\u0647 \u062d\u0630\u0641 \u0641\u0648\u0631\u06cc \u0646\u0645\u06cc\u062f\u0647\u060c \u0631\u0648\u0646\u062f \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0648 \u062d\u0630\u0641 \u0631\u0648 \u0634\u0641\u0627\u0641 \u0627\u062c\u0631\u0627 \u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u06a9\u0645\u06cc\u0644 Data Safety \u062f\u0631 Google Play<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0627\u062e\u0644 Play Console \u0628\u0627\u06cc\u062f \u0628\u062e\u0634 Data Safety \u0631\u0648 \u0628\u0631\u0627\u0633\u0627\u0633 \u0631\u0641\u062a\u0627\u0631 \u0648\u0627\u0642\u0639\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u067e\u0631 \u06a9\u0646\u06cc\u0645. \u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644 \u0628\u0627\u06cc\u062f \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645 \u0622\u06cc\u0627 \u0627\u06cc\u0646 \u062f\u0627\u062f\u0647\u200c\u0647\u0627 \u062c\u0645\u0639 \u0645\u06cc\u0634\u0646 \u06cc\u0627 \u0646\u0647:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0627\u0645 \u0648 \u0646\u0627\u0645 \u062e\u0627\u0646\u0648\u0627\u062f\u06af\u06cc\n\u0627\u06cc\u0645\u06cc\u0644 \u06cc\u0627 \u0634\u0645\u0627\u0631\u0647 \u062a\u0644\u0641\u0646\n\u0634\u0646\u0627\u0633\u0647 \u06a9\u0627\u0631\u0628\u0631\n\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062e\u0631\u06cc\u062f\n\u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0630\u062e\u06cc\u0631\u0647\u200c\u0634\u062f\u0647\n\u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u062c\u0633\u062a\u200c\u0648\u062c\u0648\n\u0634\u0646\u0627\u0633\u0647 \u062f\u0633\u062a\u06af\u0627\u0647\nCrash Log\n\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0639\u0645\u0644\u06a9\u0631\u062f \u0628\u0631\u0646\u0627\u0645\u0647\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u062c\u0648\u062f \u06cc\u06a9 SDK \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u067e\u0627\u0633\u062e \u0641\u0631\u0645 \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u0647. \u0645\u062b\u0644\u0627\u064b \u0627\u06af\u0631 Firebase Crashlytics\u060c Analytics\u060c \u062a\u0628\u0644\u06cc\u063a\u0627\u062a \u06cc\u0627 \u0633\u0631\u0648\u06cc\u0633 Push \u062f\u0627\u062f\u0647\u200c\u0627\u06cc \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u06cc \u0641\u0642\u0637 \u06a9\u062f\u0647\u0627\u06cc\u06cc \u0631\u0648 \u06a9\u0647 \u062e\u0648\u062f\u062a \u0646\u0648\u0634\u062a\u0647\u200c\u0627\u06cc \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc. Google Play \u0635\u0631\u06cc\u062d\u0627\u064b \u0627\u0639\u0644\u0627\u0645 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a SDK\u0647\u0627\u06cc \u0634\u062e\u0635 \u062b\u0627\u0644\u062b \u0647\u0645 \u0628\u0627\u06cc\u062f \u062f\u0631 \u0641\u0631\u0645 Data Safety \u0644\u062d\u0627\u0638 \u0628\u0634\u0646 \u0648 \u0645\u0633\u0626\u0648\u0644\u06cc\u062a \u0635\u062d\u062a \u067e\u0627\u0633\u062e\u200c\u0647\u0627 \u0628\u0627 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647\u200c\u0633\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0634\u062a\u0628\u0627\u0647 \u062e\u0637\u0631\u0646\u0627\u06a9 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0628\u0631\u0627\u06cc \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u062a\u0645\u0627\u0645 \u0634\u062f\u0646 \u0641\u0631\u0645\u060c \u0647\u0645\u0647 \u067e\u0627\u0633\u062e\u200c\u0647\u0627 \u0631\u0648 \u0631\u0648\u06cc \u00abNo\u00bb \u0628\u06af\u0630\u0627\u0631\u06cc. \u0627\u06af\u0631 \u0639\u0645\u0644\u06a9\u0631\u062f \u0648\u0627\u0642\u0639\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u060c Manifest\u060c SDK\u0647\u0627 \u06cc\u0627 \u062a\u0631\u0627\u0641\u06cc\u06a9 \u0634\u0628\u06a9\u0647 \u0628\u0627 \u0641\u0631\u0645 \u0645\u063a\u0627\u06cc\u0631\u062a \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u0645\u06a9\u0646\u0647 \u0631\u062f \u06cc\u0627 \u0628\u0639\u062f\u0627\u064b \u062a\u0639\u0644\u06cc\u0642 \u0628\u0634\u0647. \u0641\u0631\u0645 Data Safety\u060c Privacy Policy \u0648 \u0631\u0641\u062a\u0627\u0631 \u0648\u0627\u0642\u0639\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627\u06cc\u062f \u0633\u0647 \u0631\u0648\u0627\u06cc\u062a \u06cc\u06a9\u0633\u0627\u0646 \u0627\u0632 \u0634\u06cc\u0648\u0647 \u0645\u062f\u06cc\u0631\u06cc\u062a \u062f\u0627\u062f\u0647 \u0627\u0631\u0627\u0626\u0647 \u0628\u062f\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0646\u062a\u0634\u0627\u0631 \u0622\u0632\u0645\u0627\u06cc\u0634\u06cc \u062f\u0631 Google Play<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647\u062a\u0631\u0647 \u0627\u0648\u0644\u06cc\u0646 \u0641\u0627\u06cc\u0644 \u0631\u0648 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0648\u0627\u0631\u062f Production \u0646\u06a9\u0646\u06cc\u0645. Google Play \u0645\u0633\u06cc\u0631\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641\u06cc \u0628\u0631\u0627\u06cc \u062a\u0633\u062a \u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Internal Testing<\/strong> \u0628\u0631\u0627\u06cc \u062a\u0633\u062a \u0633\u0631\u06cc\u0639 \u062a\u0648\u0633\u0637 \u06af\u0631\u0648\u0647 \u06a9\u0648\u0686\u06a9\u06cc \u0627\u0632 \u0627\u0639\u0636\u0627\u06cc \u062a\u06cc\u0645 \u06cc\u0627 \u0627\u0641\u0631\u0627\u062f \u0645\u0648\u0631\u062f \u0627\u0639\u062a\u0645\u0627\u062f \u0645\u0646\u0627\u0633\u0628\u0647 \u0648 \u062d\u062f\u0627\u06a9\u062b\u0631 \u062a\u0627 \u06f1\u06f0\u06f0 \u062a\u0633\u062a\u0631 \u0631\u0648 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647. <strong>Closed Testing<\/strong> \u0628\u0631\u0627\u06cc \u06af\u0631\u0648\u0647 \u06a9\u0646\u062a\u0631\u0644\u200c\u0634\u062f\u0647 \u0628\u0632\u0631\u06af\u200c\u062a\u0631\u0647\u060c <strong>Open Testing<\/strong> \u0627\u062c\u0627\u0632\u0647 \u0645\u06cc\u062f\u0647 \u0627\u0641\u0631\u0627\u062f \u0628\u06cc\u0634\u062a\u0631\u06cc \u0648\u0627\u0631\u062f \u0622\u0632\u0645\u0627\u06cc\u0634 \u0639\u0645\u0648\u0645\u06cc \u0628\u0634\u0646 \u0648 <strong>Production<\/strong> \u0646\u0633\u062e\u0647\u200c\u0627\u06cc\u0647 \u06a9\u0647 \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0639\u0645\u0648\u0645\u06cc \u06a9\u0634\u0648\u0631\u0647\u0627\u06cc \u0627\u0646\u062a\u062e\u0627\u0628\u200c\u0634\u062f\u0647 \u0645\u0646\u062a\u0634\u0631 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0627\u0648\u0644\u06cc\u0646 \u062a\u0633\u062a \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0648\u0627\u0631\u062f \u0645\u0633\u06cc\u0631 Internal Testing \u0645\u06cc\u200c\u0634\u06cc\u0645\u060c \u06cc\u06a9 Release \u062c\u062f\u06cc\u062f \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645 \u0648 \u0641\u0627\u06cc\u0644 \u0632\u06cc\u0631 \u0631\u0648 \u0622\u067e\u0644\u0648\u062f \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app-release.aab\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f Release Notes \u0631\u0648 \u0648\u0627\u0631\u062f \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0633\u062e\u0647 \u0622\u0632\u0645\u0627\u06cc\u0634\u06cc \u0627\u0648\u0644\u06cc\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646<br><br>\u2022 \u0627\u0641\u0632\u0648\u062f\u0646 \u0648 \u067e\u06cc\u06af\u06cc\u0631\u06cc \u0645\u062d\u0635\u0648\u0644\u0627\u062a<br>\u2022 \u0645\u0634\u0627\u0647\u062f\u0647 \u0622\u062e\u0631\u06cc\u0646 \u0642\u06cc\u0645\u062a<br>\u2022 \u062a\u0639\u06cc\u06cc\u0646 \u0642\u06cc\u0645\u062a \u0647\u062f\u0641<br>\u2022 \u062f\u0631\u06cc\u0627\u0641\u062a \u0627\u0639\u0644\u0627\u0646 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u067e\u0633 \u0627\u06cc\u0645\u06cc\u0644 \u062a\u0633\u062a\u0631\u0647\u0627 \u0631\u0648 \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0648 \u0644\u06cc\u0646\u06a9 \u0639\u0636\u0648\u06cc\u062a \u062f\u0631 \u062a\u0633\u062a \u0631\u0648 \u0628\u0631\u0627\u06cc \u0627\u0648\u0646\u200c\u0647\u0627 \u0645\u06cc\u200c\u0641\u0631\u0633\u062a\u06cc\u0645. \u0645\u0632\u06cc\u062a \u0627\u06cc\u0646 \u0631\u0648\u0634 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0627\u0632 \u0647\u0645\u0648\u0646 \u0645\u0633\u06cc\u0631 \u0648\u0627\u0642\u0639\u06cc Google Play \u0646\u0635\u0628 \u0645\u06cc\u0634\u0647 \u0648 \u0628\u0647 \u0627\u0645\u0636\u0627\u06cc Play\u060c \u0633\u0631\u0648\u06cc\u0633\u200c\u0647\u0627\u06cc \u062e\u0631\u06cc\u062f\u060c \u0645\u062d\u062f\u0648\u062f\u06cc\u062a\u200c\u0647\u0627\u06cc \u062f\u0633\u062a\u06af\u0627\u0647 \u0648 \u0641\u0631\u0627\u06cc\u0646\u062f \u062a\u062d\u0648\u06cc\u0644 \u0648\u0627\u0642\u0639\u06cc \u0646\u0632\u062f\u06cc\u06a9\u200c\u062a\u0631\u0647. Google Play \u067e\u06cc\u0634\u0646\u0647\u0627\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647 \u062a\u0633\u062a \u062f\u0627\u062e\u0644\u06cc \u0642\u0628\u0644 \u0627\u0632 \u0645\u0633\u06cc\u0631\u0647\u0627\u06cc \u06af\u0633\u062a\u0631\u062f\u0647\u200c\u062a\u0631 \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9 \u0646\u06a9\u062a\u0647 \u0645\u0647\u0645 \u0628\u0631\u0627\u06cc \u062d\u0633\u0627\u0628\u200c\u0647\u0627\u06cc \u0634\u062e\u0635\u06cc \u062c\u062f\u06cc\u062f \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647. \u0628\u0631\u0627\u0633\u0627\u0633 \u0634\u0631\u0627\u06cc\u0637 \u0641\u0639\u0644\u06cc\u060c \u062d\u0633\u0627\u0628\u200c\u0647\u0627\u06cc \u0634\u062e\u0635\u06cc \u0633\u0627\u062e\u062a\u0647\u200c\u0634\u062f\u0647 \u0628\u0639\u062f \u0627\u0632 \u06f1\u06f3 \u0646\u0648\u0627\u0645\u0628\u0631 \u06f2\u06f0\u06f2\u06f3 \u0628\u0627\u06cc\u062f \u067e\u06cc\u0634 \u0627\u0632 \u062f\u0633\u062a\u0631\u0633\u06cc \u0628\u0647 \u0627\u0646\u062a\u0634\u0627\u0631 Production\u060c \u06cc\u06a9 Closed Test \u0628\u0627 \u062d\u062f\u0627\u0642\u0644 \u06f1\u06f2 \u062a\u0633\u062a\u0631 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646 \u06a9\u0647 \u062f\u0633\u062a\u200c\u06a9\u0645 \u06f1\u06f4 \u0631\u0648\u0632 \u067e\u06cc\u0648\u0633\u062a\u0647 \u062f\u0631 \u062a\u0633\u062a \u0639\u0636\u0648 \u0645\u0648\u0646\u062f\u0647 \u0628\u0627\u0634\u0646. \u0628\u0639\u062f \u0627\u0632 \u0628\u0631\u0622\u0648\u0631\u062f\u0647 \u0634\u062f\u0646 \u0627\u06cc\u0646 \u0634\u0631\u0637\u060c \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0628\u0627\u06cc\u062f \u0628\u0631\u0627\u06cc Production Access \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u062f\u0647 \u0648 \u062f\u0631\u0628\u0627\u0631\u0647 \u0641\u0631\u0627\u06cc\u0646\u062f \u062a\u0633\u062a \u0648 \u0622\u0645\u0627\u062f\u06af\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u0648\u0636\u06cc\u062d \u0627\u0631\u0627\u0626\u0647 \u06a9\u0646\u0647. \u0627\u06cc\u0646 \u0642\u0627\u0646\u0648\u0646 \u0645\u0645\u06a9\u0646\u0647 \u062f\u0631 \u0622\u06cc\u0646\u062f\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0645\u0642\u062f\u0627\u0631 \u062f\u0642\u06cc\u0642 \u0634\u0631\u0637 \u0631\u0648 \u062f\u0631 Dashboard \u062d\u0633\u0627\u0628 \u062e\u0648\u062f\u062a \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0633\u0627\u062e\u062a Release \u062f\u0631 Google Play<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 \u062a\u06a9\u0645\u06cc\u0644 \u0628\u062e\u0634\u200c\u0647\u0627\u06cc \u0627\u062c\u0628\u0627\u0631\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0648\u0627\u0631\u062f \u0645\u0633\u06cc\u0631 \u0645\u0648\u0631\u062f\u0646\u0638\u0631 \u0645\u06cc\u200c\u0634\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Test and release\n\u2192 Testing\n\u2192 Internal testing\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Test and release<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\u2192 Testing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\u2192 Internal testing<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627 \u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0646\u0647\u0627\u06cc\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Test and release\n\u2192 Production\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Test and release<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\u2192 Production<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u067e\u0633 \u06af\u0632\u06cc\u0646\u0647 \u0633\u0627\u062e\u062a Release \u062c\u062f\u06cc\u062f \u0631\u0648 \u0645\u06cc\u200c\u0632\u0646\u06cc\u0645\u060c \u0641\u0627\u06cc\u0644 AAB \u0631\u0648 \u0622\u067e\u0644\u0648\u062f \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645\u060c \u0647\u0634\u062f\u0627\u0631\u0647\u0627 \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0648 Release Notes \u0631\u0648 \u0645\u06cc\u200c\u0646\u0648\u06cc\u0633\u06cc\u0645. Google Play \u0628\u0639\u062f \u0627\u0632 \u0622\u067e\u0644\u0648\u062f Bundle\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u06cc \u0645\u062b\u0644 \u062f\u0633\u062a\u06af\u0627\u0647\u200c\u0647\u0627\u06cc \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc\u200c\u0634\u062f\u0647\u060c \u0646\u0633\u062e\u0647\u060c \u0633\u0637\u062d API \u0648 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc \u062a\u0648\u0644\u06cc\u062f\u0634\u062f\u0647 \u0631\u0648 \u062a\u062d\u0644\u06cc\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0647\u0631 Release \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062f\u0631 \u0648\u0636\u0639\u06cc\u062a Draft\u060c Active \u06cc\u0627 Archived \u0642\u0631\u0627\u0631 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0647\u0634\u062f\u0627\u0631 \u0632\u06cc\u0631 \u0631\u0648 \u062f\u06cc\u062f\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Version code 1 has already been used\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0627\u06cc\u062f Gradle \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>versionCode = 2\nversionName = \"1.0.1\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u062f\u0648\u0628\u0627\u0631\u0647 \u062e\u0631\u0648\u062c\u06cc \u0628\u06af\u06cc\u0631\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/gradlew clean bundleRelease\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u062e\u0637\u0627\u06cc Package Name \u062f\u06cc\u062f\u06cc\u0645\u060c \u0628\u0627\u06cc\u062f \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645 \u0641\u0627\u06cc\u0644 \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 Variant \u062f\u0631\u0633\u062a \u0631\u0648 \u0633\u0627\u062e\u062a\u0647\u200c\u0627\u06cc\u0645. \u0645\u0645\u06a9\u0646\u0647 \u0628\u0647\u200c\u062c\u0627\u06cc \u0646\u0633\u062e\u0647 Production\u060c \u0641\u0627\u06cc\u0644 Flavor \u0622\u0632\u0645\u0627\u06cc\u0634\u06cc \u0631\u0648 \u0628\u0627 \u0634\u0646\u0627\u0633\u0647 \u0632\u06cc\u0631 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>com.gheimatban.app.staging\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u062b\u0628\u062a\u200c\u0634\u062f\u0647 \u0627\u06cc\u0646 \u0634\u0646\u0627\u0633\u0647 \u0631\u0648 \u0627\u0646\u062a\u0638\u0627\u0631 \u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>com.gheimatban.app\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u062e\u0637\u0627\u06cc Signing \u062f\u06cc\u062f\u06cc\u0645\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b Bundle \u0628\u0627 Upload Key \u0635\u062d\u06cc\u062d \u0627\u0645\u0636\u0627 \u0646\u0634\u062f\u0647 \u06cc\u0627 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0627\u06cc \u06a9\u0647 \u0642\u0628\u0644\u0627\u064b \u062b\u0628\u062a \u0634\u062f\u0647 \u0627\u0632 \u06a9\u0644\u06cc\u062f \u062f\u06cc\u06af\u0631\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0646\u062a\u0634\u0627\u0631 \u062f\u0631 \u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631 \u0647\u0645 \u0627\u0628\u062a\u062f\u0627 \u0628\u0627\u06cc\u062f \u062d\u0633\u0627\u0628 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0648 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0647\u0648\u06cc\u062a\u06cc \u06cc\u0627 \u062d\u0642\u0648\u0642\u06cc \u0631\u0648 \u062a\u06a9\u0645\u06cc\u0644 \u06a9\u0646\u06cc\u0645\u060c \u0633\u067e\u0633 \u062f\u0627\u062e\u0644 \u067e\u06cc\u0634\u062e\u0627\u0646 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u062c\u062f\u06cc\u062f \u0628\u0633\u0627\u0632\u06cc\u0645. \u0631\u0648\u0646\u062f \u06a9\u0644\u06cc \u0634\u0627\u0645\u0644 \u0633\u0627\u062e\u062a \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u0627\u0646\u062a\u062e\u0627\u0628 \u062f\u0633\u062a\u0647\u200c\u0628\u0646\u062f\u06cc\u060c \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0628\u0633\u062a\u0647\u060c \u062a\u06a9\u0645\u06cc\u0644 \u0646\u0627\u0645 \u0648 \u062a\u0648\u0636\u06cc\u062d\u0627\u062a\u060c \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0622\u06cc\u06a9\u0648\u0646 \u0648 \u062a\u0635\u0627\u0648\u06cc\u0631\u060c \u062f\u0631\u062c \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u0648 \u0627\u0631\u0633\u0627\u0644 \u0646\u0633\u062e\u0647 \u0628\u0631\u0627\u06cc \u0628\u0631\u0631\u0633\u06cc \u06cc\u0627 \u0627\u0646\u062a\u0634\u0627\u0631 \u0645\u06cc\u0634\u0647. \u0646\u0627\u0645 \u062f\u0642\u06cc\u0642 \u06af\u0632\u06cc\u0646\u0647\u200c\u0647\u0627 \u0648 \u0641\u0631\u0645\u062a\u200c\u0647\u0627\u06cc \u0642\u0627\u0628\u0644\u200c\u0642\u0628\u0648\u0644 \u0645\u0645\u06a9\u0646\u0647 \u0628\u0627 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u067e\u06cc\u0634\u062e\u0627\u0646 \u0639\u0648\u0636 \u0628\u0634\u0647\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0647\u0646\u06af\u0627\u0645 \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0627\u06cc\u062f \u0631\u0627\u0647\u0646\u0645\u0627\u06cc \u062f\u0627\u062e\u0644 \u062e\u0648\u062f \u067e\u0646\u0644 \u0631\u0648 \u0645\u0631\u062c\u0639 \u0646\u0647\u0627\u06cc\u06cc \u0642\u0631\u0627\u0631 \u0628\u062f\u06cc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0633\u062a\u0647\u200c\u0627\u06cc \u06a9\u0647 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc \u0628\u0627\u06cc\u062f \u0646\u0633\u062e\u0647 Release \u0627\u0645\u0636\u0627\u0634\u062f\u0647 \u0628\u0627\u0634\u0647\u060c \u0646\u0647 APK Debug. \u0627\u06af\u0631 \u067e\u0646\u0644 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u0648 APK \u0628\u062e\u0648\u0627\u062f\u060c \u0641\u0627\u06cc\u0644 \u0645\u0646\u0627\u0633\u0628 \u0627\u06cc\u0646\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app\/build\/outputs\/apk\/release\/app-release.apk\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 AAB \u067e\u0630\u06cc\u0631\u0641\u062a\u0647 \u0628\u0634\u0647 \u0648 \u0628\u062e\u0648\u0627\u06cc Bundle \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u06cc\u060c \u0641\u0627\u06cc\u0644 \u0627\u06cc\u0646\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app\/build\/outputs\/bundle\/release\/app-release.aab\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631 App Bundle \u0631\u0648 \u0627\u0639\u0644\u0627\u0645 \u06a9\u0631\u062f\u0647\u060c \u0627\u0645\u0627 \u0686\u0648\u0646 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627 \u0648 \u0627\u0644\u0632\u0627\u0645\u0627\u062a \u067e\u0646\u0644 \u0645\u0645\u06a9\u0646\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0646\u060c \u0627\u0646\u062a\u062e\u0627\u0628 \u0646\u0647\u0627\u06cc\u06cc \u0631\u0648 \u0628\u0631\u0627\u0633\u0627\u0633 \u06af\u0632\u06cc\u0646\u0647\u200c\u0647\u0627\u06cc \u0641\u0639\u0627\u0644 \u062f\u0631 \u067e\u06cc\u0634\u062e\u0627\u0646 \u0627\u0646\u062c\u0627\u0645 \u0628\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u062a\u0648\u0636\u06cc\u062d \u06a9\u0648\u062a\u0627\u0647 \u0628\u0627\u0632\u0627\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0627 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646\u060c \u062a\u063a\u06cc\u06cc\u0631 \u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0648 \u062f\u0646\u0628\u0627\u0644 \u06a9\u0646 \u0648\n\u0647\u0646\u06af\u0627\u0645 \u0631\u0633\u06cc\u062f\u0646 \u0628\u0647 \u0642\u06cc\u0645\u062a \u062f\u0644\u062e\u0648\u0627\u0647 \u0628\u0627\u062e\u0628\u0631 \u0634\u0648.\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0648\u0636\u06cc\u062d \u06a9\u0627\u0645\u0644 \u0641\u0627\u0631\u0633\u06cc \u0647\u0645 \u0628\u0627\u06cc\u062f \u062e\u0648\u0627\u0646\u0627\u060c \u062f\u0642\u06cc\u0642 \u0648 \u0628\u062f\u0648\u0646 \u0648\u0639\u062f\u0647 \u063a\u06cc\u0631\u0648\u0627\u0642\u0639\u06cc \u0628\u0627\u0634\u0647. \u0627\u06af\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0642\u06cc\u0645\u062a\u200c\u0647\u0627 \u0631\u0648 \u0628\u0627 \u062a\u0623\u062e\u06cc\u0631 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0646\u0628\u0627\u06cc\u062f \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645 \u00ab\u062a\u0645\u0627\u0645 \u0642\u06cc\u0645\u062a\u200c\u0647\u0627\u06cc \u0628\u0627\u0632\u0627\u0631 \u062f\u0631 \u0647\u0631 \u062b\u0627\u0646\u06cc\u0647 \u0628\u0647\u200c\u0635\u0648\u0631\u062a \u0642\u0637\u0639\u06cc \u0648 \u0644\u062d\u0638\u0647\u200c\u0627\u06cc\u00bb. \u062a\u0648\u0636\u06cc\u062d\u0627\u062a \u0635\u0641\u062d\u0647 \u0645\u0627\u0631\u06a9\u062a \u0628\u062e\u0634\u06cc \u0627\u0632 \u062a\u0639\u0647\u062f \u0645\u062d\u0635\u0648\u0644 \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 \u062f\u0648 \u0645\u0627\u0631\u06a9\u062a \u0648 \u0645\u0633\u0626\u0644\u0647 \u0627\u0645\u0636\u0627<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647\u062a\u0631\u0647 \u0646\u0633\u062e\u0647 Google Play \u0648 \u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631 \u0627\u0632 \u06cc\u06a9 Package Name \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0646 \u062a\u0627 \u0627\u0632 \u062f\u06cc\u062f \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627\u0634\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>com.gheimatban.app\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0628\u0627\u06cc\u062f \u0628\u0627 \u062f\u0642\u062a \u062f\u0631\u0628\u0627\u0631\u0647 \u0645\u062f\u0644 \u0627\u0645\u0636\u0627 \u062a\u0635\u0645\u06cc\u0645 \u0628\u06af\u06cc\u0631\u06cc. Google Play \u062f\u0631 \u062d\u0627\u0644\u062a Play App Signing\u060c APK \u0646\u0647\u0627\u06cc\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0631\u0648 \u0628\u0627 App Signing Key \u062e\u0648\u062f\u0634 \u0627\u0645\u0636\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06af\u0631 \u0646\u0633\u062e\u0647 \u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631 \u0631\u0648 \u0628\u0627 \u06a9\u0644\u06cc\u062f \u0645\u062d\u0644\u06cc \u0645\u062a\u0641\u0627\u0648\u062a\u06cc \u0627\u0645\u0636\u0627 \u06a9\u0646\u06cc\u060c \u06a9\u0627\u0631\u0628\u0631\u06cc \u06a9\u0647 \u0646\u0633\u062e\u0647 \u06cc\u06a9 \u0645\u0627\u0631\u06a9\u062a \u0631\u0648 \u0646\u0635\u0628 \u06a9\u0631\u062f\u0647 \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0646\u0633\u062e\u0647 \u0645\u0627\u0631\u06a9\u062a \u062f\u06cc\u06af\u0647 \u0631\u0648 \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 \u0622\u067e\u062f\u06cc\u062a \u0631\u0648\u06cc \u0647\u0645\u0648\u0646 \u0646\u0635\u0628 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u0647\u061b \u0686\u0648\u0646 \u0627\u0645\u0636\u0627\u0647\u0627 \u0645\u062a\u0641\u0627\u0648\u062a\u0646. \u062f\u0631 \u0628\u0639\u0636\u06cc \u0633\u0646\u0627\u0631\u06cc\u0648\u0647\u0627 \u0627\u06cc\u0646 \u0645\u0648\u0636\u0648\u0639 \u0645\u0647\u0645 \u0646\u06cc\u0633\u062a\u060c \u0686\u0648\u0646 \u0647\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0627\u0632 \u0647\u0645\u0648\u0646 \u0645\u0627\u0631\u06a9\u062a \u062e\u0648\u062f\u0634 \u0622\u067e\u062f\u06cc\u062a \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647. \u0627\u0645\u0627 \u0627\u06af\u0631 \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc \u0627\u0645\u06a9\u0627\u0646 \u062c\u0627\u0628\u0647\u200c\u062c\u0627\u06cc\u06cc \u0628\u06cc\u0646 \u0645\u0627\u0631\u06a9\u062a\u200c\u0647\u0627 \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0628\u0627\u06cc\u062f \u0631\u0627\u0647\u0628\u0631\u062f \u0627\u0645\u0636\u0627 \u0631\u0648 \u0627\u0632 \u0627\u0628\u062a\u062f\u0627 \u0622\u06af\u0627\u0647\u0627\u0646\u0647 \u0637\u0631\u0627\u062d\u06cc \u06a9\u0646\u06cc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9 \u0631\u0627\u0647 \u062f\u06cc\u06af\u0647 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0628\u0631\u0627\u06cc \u0647\u0631 \u0645\u0627\u0631\u06a9\u062a Application ID \u0645\u062a\u0641\u0627\u0648\u062a \u062a\u0639\u0631\u06cc\u0641 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>android {\n    flavorDimensions += \"store\"\n\n    productFlavors {\n        create(\"googlePlay\") {\n            dimension = \"store\"\n            applicationId = \"com.gheimatban.app\"\n        }\n\n        create(\"bazaar\") {\n            dimension = \"store\"\n            applicationId = \"com.gheimatban.app.bazaar\"\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">android<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    flavorDimensions <\/span><span style=\"color: #D73A49\">+=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;store&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">productFlavors<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;googlePlay&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            dimension <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;store&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            applicationId <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;com.gheimatban.app&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;bazaar&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            dimension <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;store&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            applicationId <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;com.gheimatban.app.bazaar&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u062d\u0627\u0644\u062a \u062f\u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u0633\u062a\u0642\u0644 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u0634\u0646 \u0648 \u062d\u062a\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0646\u0635\u0628 \u0628\u0634\u0646. \u0627\u0645\u0627 \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0645\u0639\u0627\u06cc\u0628\u06cc \u0647\u0645 \u062f\u0627\u0631\u0647: \u0622\u0645\u0627\u0631 \u0646\u0635\u0628\u060c Deep Link\u060c Firebase\u060c OAuth\u060c \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u060c \u062a\u0646\u0638\u06cc\u0645\u0627\u062a Backend \u0648 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0646\u0633\u062e\u0647\u200c\u0647\u0627 \u0627\u0632 \u0647\u0645 \u062c\u062f\u0627 \u0645\u06cc\u0634\u0646. \u0628\u0631\u0627\u06cc \u0628\u06cc\u0634\u062a\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627 \u0628\u0647\u062a\u0631\u0647 \u0628\u062f\u0648\u0646 \u062f\u0644\u06cc\u0644 \u062c\u062f\u06cc\u060c Package Name \u0631\u0648 \u0628\u06cc\u0646 \u0645\u0627\u0631\u06a9\u062a\u200c\u0647\u0627 \u062c\u062f\u0627 \u0646\u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 Flavor\u0647\u0627 \u0631\u0648 \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0648\u0627\u0628\u0633\u062a\u06af\u06cc\u200c\u0647\u0627\u06cc \u0645\u062e\u0635\u0648\u0635 \u0645\u0627\u0631\u06a9\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645 \u0648 Application ID \u0631\u0648 \u06cc\u06a9\u0633\u0627\u0646 \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>android {\n    flavorDimensions += \"store\"\n\n    productFlavors {\n        create(\"googlePlay\") {\n            dimension = \"store\"\n\n            buildConfigField(\n                \"String\",\n                \"STORE_NAME\",\n                \"\\\"Google Play\\\"\"\n            )\n        }\n\n        create(\"bazaar\") {\n            dimension = \"store\"\n\n            buildConfigField(\n                \"String\",\n                \"STORE_NAME\",\n                \"\\\"Cafe Bazaar\\\"\"\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">android<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    flavorDimensions <\/span><span style=\"color: #D73A49\">+=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;store&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">productFlavors<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;googlePlay&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            dimension <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;store&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">buildConfigField<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;String&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;STORE_NAME&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;<\/span><span style=\"color: #005CC5\">\\&quot;<\/span><span style=\"color: #032F62\">Google Play<\/span><span style=\"color: #005CC5\">\\&quot;<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;bazaar&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            dimension <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;store&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">buildConfigField<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;String&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;STORE_NAME&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;<\/span><span style=\"color: #005CC5\">\\&quot;<\/span><span style=\"color: #032F62\">Cafe Bazaar<\/span><span style=\"color: #005CC5\">\\&quot;<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0627\u06af\u0631 \u0628\u062e\u0648\u0627\u06cc\u0645 \u0635\u0641\u062d\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 \u0645\u0627\u0631\u06a9\u062a \u0645\u0631\u0628\u0648\u0637 \u0631\u0648 \u0628\u0627\u0632 \u06a9\u0646\u06cc\u0645\u060c \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u0631\u0627\u0633\u0627\u0633 Flavor \u0631\u0641\u062a\u0627\u0631 \u0645\u062a\u0641\u0627\u0648\u062a\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun openStorePage(context: Context) {\n    val packageName = context.packageName\n\n    val uri = when (BuildConfig.STORE_NAME) {\n        \"Cafe Bazaar\" -> {\n            Uri.parse(\n                \"bazaar:\/\/details?id=$packageName\"\n            )\n        }\n\n        else -> {\n            Uri.parse(\n                \"market:\/\/details?id=$packageName\"\n            )\n        }\n    }\n\n    val intent = Intent(\n        Intent.ACTION_VIEW,\n        uri\n    )\n\n    context.startActivity(intent)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">openStorePage<\/span><span style=\"color: #24292E\">(context: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> packageName <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> context.packageName<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> uri <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (BuildConfig.STORE_NAME) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;Cafe Bazaar&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Uri.<\/span><span style=\"color: #6F42C1\">parse<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;bazaar:\/\/details?id=<\/span><span style=\"color: #005CC5\">$packageName<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Uri.<\/span><span style=\"color: #6F42C1\">parse<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;market:\/\/details?id=<\/span><span style=\"color: #005CC5\">$packageName<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> intent <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Intent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Intent.ACTION_VIEW,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        uri<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    context.<\/span><span style=\"color: #6F42C1\">startActivity<\/span><span style=\"color: #24292E\">(intent)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u062f\u0631 \u0635\u0648\u0631\u062a \u0646\u0635\u0628 \u0646\u0628\u0648\u062f\u0646 \u0645\u0627\u0631\u06a9\u062a \u0628\u0631\u0646\u0627\u0645\u0647 Crash \u0646\u06a9\u0646\u0647\u060c \u0646\u0633\u062e\u0647 \u0645\u0642\u0627\u0648\u0645\u200c\u062a\u0631\u06cc \u0645\u06cc\u200c\u0646\u0648\u06cc\u0633\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun openStorePage(context: Context) {\n    val packageName = context.packageName\n\n    val primaryUrl = when (BuildConfig.STORE_NAME) {\n        \"Cafe Bazaar\" -> {\n            \"bazaar:\/\/details?id=$packageName\"\n        }\n\n        else -> {\n            \"market:\/\/details?id=$packageName\"\n        }\n    }\n\n    val fallbackUrl = when (BuildConfig.STORE_NAME) {\n        \"Cafe Bazaar\" -> {\n            \"https:\/\/cafebazaar.ir\/app\/$packageName\"\n        }\n\n        else -> {\n            \"https:\/\/play.google.com\/store\/apps\/details?id=$packageName\"\n        }\n    }\n\n    try {\n        context.startActivity(\n            Intent(\n                Intent.ACTION_VIEW,\n                Uri.parse(primaryUrl)\n            )\n        )\n    } catch (exception: ActivityNotFoundException) {\n        context.startActivity(\n            Intent(\n                Intent.ACTION_VIEW,\n                Uri.parse(fallbackUrl)\n            )\n        )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">openStorePage<\/span><span style=\"color: #24292E\">(context: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> packageName <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> context.packageName<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> primaryUrl <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (BuildConfig.STORE_NAME) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;Cafe Bazaar&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;bazaar:\/\/details?id=<\/span><span style=\"color: #005CC5\">$packageName<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;market:\/\/details?id=<\/span><span style=\"color: #005CC5\">$packageName<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> fallbackUrl <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (BuildConfig.STORE_NAME) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;Cafe Bazaar&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;https:\/\/cafebazaar.ir\/app\/<\/span><span style=\"color: #005CC5\">$packageName<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;https:\/\/play.google.com\/store\/apps\/details?id=<\/span><span style=\"color: #005CC5\">$packageName<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        context.<\/span><span style=\"color: #6F42C1\">startActivity<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">Intent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Intent.ACTION_VIEW,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Uri.<\/span><span style=\"color: #6F42C1\">parse<\/span><span style=\"color: #24292E\">(primaryUrl)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    } <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (exception: <\/span><span style=\"color: #6F42C1\">ActivityNotFoundException<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        context.<\/span><span style=\"color: #6F42C1\">startActivity<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">Intent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Intent.ACTION_VIEW,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Uri.<\/span><span style=\"color: #6F42C1\">parse<\/span><span style=\"color: #24292E\">(fallbackUrl)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0646\u062a\u0634\u0627\u0631 \u0646\u0633\u062e\u0647 \u062f\u0648\u0645 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0646\u0633\u062e\u0647 <code>1.0.0<\/code> \u0645\u0646\u062a\u0634\u0631 \u0634\u062f\u0647 \u0648 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u06af\u0632\u0627\u0631\u0634 \u062f\u0627\u062f\u0646 \u0628\u0639\u062f \u0627\u0632 \u0642\u0637\u0639 \u0648 \u0648\u0635\u0644 \u0634\u062f\u0646 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a\u060c \u0628\u0639\u0636\u06cc \u0642\u06cc\u0645\u062a\u200c\u0647\u0627 \u062a\u0627\u0632\u0647\u200c\u0633\u0627\u0632\u06cc \u0646\u0645\u06cc\u0634\u0646. \u0645\u0634\u06a9\u0644 \u0631\u0648 \u0627\u0635\u0644\u0627\u062d \u06a9\u0631\u062f\u06cc\u0645 \u0648 \u062d\u0627\u0644\u0627 \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc\u0645 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u06cc\u0645. \u0627\u0648\u0644 \u0646\u0633\u062e\u0647 \u0631\u0648 \u0627\u0641\u0632\u0627\u06cc\u0634 \u0645\u06cc\u200c\u062f\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>defaultConfig {\n    versionCode = 2\n    versionName = \"1.0.1\"\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">defaultConfig<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    versionCode <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    versionName <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;1.0.1&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u067e\u0633 \u062a\u0633\u062a\u200c\u0647\u0627 \u0631\u0648 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/gradlew test\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u062a\u0633\u062a\u200c\u0647\u0627\u06cc Instrumented \u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/gradlew connectedAndroidTest\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u062e\u0631\u0648\u062c\u06cc Release \u0631\u0648 \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/gradlew clean bundleRelease\n.\/gradlew assembleRelease\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AAB \u0631\u0648 \u0628\u0631\u0627\u06cc Google Play \u0648 APK \u06cc\u0627 AAB \u0645\u0648\u0631\u062f\u0646\u06cc\u0627\u0632 \u0631\u0648 \u0628\u0631\u0627\u06cc \u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631 \u0622\u067e\u0644\u0648\u062f \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. Release Notes \u0646\u0633\u062e\u0647 \u062f\u0648\u0645 \u0628\u0627\u06cc\u062f \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0642\u0627\u0628\u0644\u200c\u0641\u0647\u0645 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0646\u0633\u062e\u0647 \u06f1.\u06f0.\u06f1\n\n\u2022 \u0628\u0631\u0637\u0631\u0641 \u0634\u062f\u0646 \u0645\u0634\u06a9\u0644 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0642\u06cc\u0645\u062a \u067e\u0633 \u0627\u0632 \u0627\u062a\u0635\u0627\u0644 \u0645\u062c\u062f\u062f \u0627\u06cc\u0646\u062a\u0631\u0646\u062a\n\u2022 \u0628\u0647\u0628\u0648\u062f \u0633\u0631\u0639\u062a \u0646\u0645\u0627\u06cc\u0634 \u0641\u0647\u0631\u0633\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a\n\u2022 \u0631\u0641\u0639 \u0686\u0646\u062f \u062e\u0637\u0627\u06cc \u062c\u0632\u0626\u06cc\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0648\u0634\u062a\u0646 \u0639\u0628\u0627\u0631\u062a\u200c\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 \u00abBug Fix\u00bb \u06cc\u0627 \u00ab\u0628\u0647\u0628\u0648\u062f\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641\u00bb \u0628\u0631\u0627\u06cc \u062a\u0645\u0627\u0645 \u0646\u0633\u062e\u0647\u200c\u0647\u0627 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0641\u06cc\u062f\u06cc \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0646\u0645\u06cc\u062f\u0647. \u0644\u0627\u0632\u0645 \u0646\u06cc\u0633\u062a \u062c\u0632\u0626\u06cc\u0627\u062a \u0641\u0646\u06cc \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645\u060c \u0627\u0645\u0627 \u0628\u0627\u06cc\u062f \u0645\u0634\u062e\u0635 \u0628\u0627\u0634\u0647 \u0646\u0633\u062e\u0647 \u0686\u0647 \u0686\u06cc\u0632\u06cc \u0631\u0648 \u0628\u0647\u062a\u0631 \u06a9\u0631\u062f\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062e\u0637\u0627\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u0632\u0645\u0627\u0646 \u0627\u0646\u062a\u0634\u0627\u0631<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u062e\u0637\u0627\u0647\u0627\u06cc \u0645\u062a\u062f\u0627\u0648\u0644 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0646\u0633\u062e\u0647 Release \u0628\u0647 API \u0648\u0635\u0644 \u0646\u0645\u06cc\u0634\u0647\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 Debug \u062f\u0631\u0633\u062a \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0622\u062f\u0631\u0633 <code>BASE_URL<\/code> \u0627\u0634\u062a\u0628\u0627\u0647\u0647\u060c \u0641\u0627\u06cc\u0644 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a Release \u0646\u0627\u0642\u0635\u0647\u060c Certificate Pinning \u0628\u0627 \u06af\u0648\u0627\u0647\u06cc \u0648\u0627\u0642\u0639\u06cc \u0647\u0645\u0627\u0647\u0646\u06af \u0646\u06cc\u0633\u062a \u06cc\u0627 \u0633\u0631\u0648\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0646\u0633\u062e\u0647 \u0646\u0647\u0627\u06cc\u06cc \u0631\u0648 \u0631\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u0637\u0627\u06cc \u062f\u0648\u0645 \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 Firebase\u0647. \u0627\u06af\u0631 \u0627\u0645\u0636\u0627\u06cc Release \u0628\u0627 Debug \u0641\u0631\u0642 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 \u0633\u0631\u0648\u06cc\u0633\u200c\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 Google Sign-In \u062f\u0631\u0633\u062a \u06a9\u0627\u0631 \u0646\u06a9\u0646\u0646. \u0628\u0627\u06cc\u062f SHA-1 \u0648 SHA-256 \u06a9\u0644\u06cc\u062f \u0645\u0631\u0628\u0648\u0637 \u0631\u0648 \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>keytool -list -v \\\n-keystore gheimatban-release.jks \\\n-alias gheimatban\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">keytool <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">list <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">v \\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">keystore gheimatban<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">release.jks \\<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">alias gheimatban<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0648\u06cc\u0646\u062f\u0648\u0632 \u0647\u0645 \u062f\u0633\u062a\u0648\u0631 \u0628\u0647 \u0647\u0645\u06cc\u0646 \u0635\u0648\u0631\u062a\u0647 \u0648 \u0641\u0642\u0637 \u0645\u0633\u06cc\u0631 \u0641\u0627\u06cc\u0644 \u0645\u0645\u06a9\u0646\u0647 \u0641\u0631\u0642 \u06a9\u0646\u0647. \u0627\u062b\u0631 \u0627\u0646\u06af\u0634\u062a\u200c\u0647\u0627\u06cc \u0644\u0627\u0632\u0645 \u0631\u0648 \u062f\u0631 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a Firebase \u06cc\u0627 \u0633\u0631\u0648\u06cc\u0633 \u0645\u0631\u0628\u0648\u0637 \u062b\u0628\u062a \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. \u062f\u0631 Google Play \u0628\u0627\u06cc\u062f \u062a\u0648\u062c\u0647 \u06a9\u0646\u06cc\u0645 \u06a9\u0647 \u06af\u0648\u0627\u0647\u06cc App Signing \u0646\u0647\u0627\u06cc\u06cc \u0645\u0645\u06a9\u0646\u0647 \u0628\u0627 Upload Key \u0645\u062a\u0641\u0627\u0648\u062a \u0628\u0627\u0634\u0647\u061b \u067e\u0633 \u0628\u0631\u0627\u06cc \u0628\u0639\u0636\u06cc \u0633\u0631\u0648\u06cc\u0633\u200c\u0647\u0627 \u0628\u0627\u06cc\u062f SHA \u06af\u0648\u0627\u0647\u06cc App Signing \u0645\u0648\u062c\u0648\u062f \u062f\u0631 Play Console \u0647\u0645 \u0627\u0636\u0627\u0641\u0647 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u0637\u0627\u06cc \u0633\u0648\u0645\u060c Crash \u0634\u062f\u0646 \u0646\u0633\u062e\u0647 Release \u0628\u0647 \u062f\u0644\u06cc\u0644 R8 \u0647\u0633\u062a. \u062f\u0631 \u0627\u06cc\u0646 \u062d\u0627\u0644\u062a \u0628\u0627\u06cc\u062f Stack Trace \u0631\u0648 \u0628\u0627 \u0641\u0627\u06cc\u0644 Mapping \u062a\u062d\u0644\u06cc\u0644 \u06a9\u0646\u06cc\u0645. \u0641\u0627\u06cc\u0644 Mapping \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0633\u06cc\u0631 \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app\/build\/outputs\/mapping\/release\/mapping.txt\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0641\u0627\u06cc\u0644 \u0631\u0648 \u0628\u0631\u0627\u06cc \u0647\u0631 \u0646\u0633\u062e\u0647 \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u06cc\u0645. \u0627\u06af\u0631 Stack Trace \u0645\u0628\u0647\u0645\u200c\u0634\u062f\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645\u060c \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0627\u0648\u0646 \u0631\u0648 Retrace \u06a9\u0646\u06cc\u0645. \u062d\u0630\u0641 \u0627\u06cc\u0646 \u0641\u0627\u06cc\u0644 \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u062a\u062d\u0644\u06cc\u0644 Crash\u0647\u0627\u06cc Obfuscate\u0634\u062f\u0647 \u0628\u0633\u06cc\u0627\u0631 \u0633\u062e\u062a\u200c\u062a\u0631 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u0637\u0627\u06cc \u0686\u0647\u0627\u0631\u0645\u060c \u0641\u0631\u0627\u0645\u0648\u0634 \u06a9\u0631\u062f\u0646 \u0627\u0641\u0632\u0627\u06cc\u0634 <code>versionCode<\/code> \u0647\u0633\u062a. \u067e\u06cc\u0634 \u0627\u0632 \u0647\u0631 Build \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0627\u06cc\u062f \u0627\u06cc\u0646 \u0645\u0642\u062f\u0627\u0631 \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645. \u062e\u0637\u0627\u06cc \u067e\u0646\u062c\u0645 \u0647\u0645 \u0622\u067e\u0644\u0648\u062f \u06a9\u0631\u062f\u0646 Variant \u0627\u0634\u062a\u0628\u0627\u0647\u0647\u061b \u0645\u062b\u0644\u0627\u064b <code>stagingRelease<\/code> \u0628\u0647\u200c\u062c\u0627\u06cc <code>productionRelease<\/code>. \u0646\u0627\u0645 \u0633\u0631\u0648\u0631\u060c Package Name \u0648 \u062d\u062a\u06cc \u0622\u06cc\u06a9\u0648\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062f\u0631 \u0627\u06cc\u0646 \u062f\u0648 Variant \u0645\u062a\u0641\u0627\u0648\u062a \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u06a9\u200c\u0644\u06cc\u0633\u062a \u0639\u0645\u0644\u06cc \u0642\u0628\u0644 \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0642\u0628\u0644 \u0627\u0632 \u0627\u06cc\u0646\u06a9\u0647 \u0646\u0633\u062e\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0631\u0648 \u0628\u0631\u0627\u06cc \u0628\u0631\u0631\u0633\u06cc \u0646\u0647\u0627\u06cc\u06cc \u0628\u0641\u0631\u0633\u062a\u06cc\u0645\u060c \u0627\u06cc\u0646 \u0645\u0648\u0627\u0631\u062f \u0631\u0648 \u06cc\u06a9\u200c\u0628\u0627\u0631 \u06a9\u0627\u0645\u0644 \u06a9\u0646\u062a\u0631\u0644 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>applicationId<\/code> \u0646\u0647\u0627\u06cc\u06cc \u0648 \u0635\u062d\u06cc\u062d \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li><code>versionCode<\/code> \u0627\u0632 \u062a\u0645\u0627\u0645 \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u0642\u0628\u0644\u06cc \u0628\u0632\u0631\u06af\u200c\u062a\u0631 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li><code>versionName<\/code> \u062f\u0631\u0633\u062a \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u0641\u0627\u06cc\u0644 \u0628\u0627 Keystore \u0635\u062d\u06cc\u062d \u0627\u0645\u0636\u0627 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0646\u0633\u062e\u0647 Release \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0648\u0627\u0642\u0639\u06cc \u0646\u0635\u0628 \u0648 \u062a\u0633\u062a \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0648\u0631\u0648\u062f\u060c \u062e\u0631\u0648\u062c\u060c \u062b\u0628\u062a\u200c\u0646\u0627\u0645 \u0648 \u062d\u0630\u0641 \u062d\u0633\u0627\u0628 \u06a9\u0627\u0631 \u06a9\u0646\u0646.<\/li>\n\n\n\n<li>API \u0646\u0633\u062e\u0647 \u0646\u0647\u0627\u06cc\u06cc \u0628\u0647 \u0633\u0631\u0648\u0631 Production \u0645\u062a\u0635\u0644 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>Log \u0634\u0627\u0645\u0644 Token\u060c \u0631\u0645\u0632\u060c \u0634\u0645\u0627\u0631\u0647 \u062a\u0644\u0641\u0646 \u06cc\u0627 \u067e\u0627\u0633\u062e \u062d\u0633\u0627\u0633 \u0633\u0631\u0648\u0631 \u0646\u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>R8 \u0628\u0627\u0639\u062b Crash \u06cc\u0627 \u062d\u0630\u0641 \u0645\u062f\u0644\u200c\u0647\u0627 \u0646\u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627 \u062f\u0631 Foreground \u0648 Background \u06a9\u0627\u0631 \u06a9\u0646\u0646.<\/li>\n\n\n\n<li>Deep Link\u0647\u0627 \u0628\u0647 \u0635\u0641\u062d\u0647 \u062f\u0631\u0633\u062a \u0628\u0631\u0646.<\/li>\n\n\n\n<li>\u0622\u06cc\u06a9\u0648\u0646 \u0648 \u0646\u0627\u0645 Release \u0635\u062d\u06cc\u062d \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>Permission \u0627\u0636\u0627\u0641\u06cc \u062f\u0627\u062e\u0644 Merged Manifest \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>Privacy Policy \u0628\u0627 \u0631\u0641\u062a\u0627\u0631 \u0648\u0627\u0642\u0639\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645\u0627\u0647\u0646\u06af \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>Data Safety \u0628\u0631\u0627\u0633\u0627\u0633 SDK\u0647\u0627 \u0648 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc \u062a\u06a9\u0645\u06cc\u0644 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0644\u06cc\u0646\u06a9 \u062d\u0630\u0641 \u062d\u0633\u0627\u0628 \u0641\u0639\u0627\u0644 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0627\u0633\u06a9\u0631\u06cc\u0646\u200c\u0634\u0627\u062a\u200c\u0647\u0627 \u0648 \u062a\u0648\u0636\u06cc\u062d\u0627\u062a \u0645\u0627\u0631\u06a9\u062a \u0646\u0647\u0627\u06cc\u06cc \u0634\u062f\u0647 \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li><code>mapping.txt<\/code> \u0646\u0633\u062e\u0647 Release \u0630\u062e\u06cc\u0631\u0647 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>Keystore \u0648 \u0631\u0645\u0632\u0647\u0627\u06cc \u0627\u0648\u0646 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646 \u0627\u0645\u0646 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>Release Notes \u0646\u0648\u0634\u062a\u0647 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0646\u0633\u062e\u0647 \u0627\u0628\u062a\u062f\u0627 \u062f\u0631 \u0645\u0633\u06cc\u0631 \u0622\u0632\u0645\u0627\u06cc\u0634\u06cc \u0645\u0646\u062a\u0634\u0631 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0646\u062a\u0634\u0627\u0631 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0635\u0631\u0641\u0627\u064b \u06af\u0631\u0641\u062a\u0646 \u06cc\u06a9 APK \u0648 \u06af\u0630\u0627\u0634\u062a\u0646 \u0627\u0648\u0646 \u062f\u0627\u062e\u0644 \u06cc\u06a9 \u0645\u0627\u0631\u06a9\u062a \u0646\u06cc\u0633\u062a. \u0645\u0627 \u0628\u0627\u06cc\u062f \u0647\u0648\u06cc\u062a \u062b\u0627\u0628\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0627 <code>applicationId<\/code> \u0645\u0634\u062e\u0635 \u06a9\u0646\u06cc\u0645\u060c \u0646\u0633\u062e\u0647\u200c\u0647\u0627 \u0631\u0648 \u0628\u0627 <code>versionCode<\/code> \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc\u0645\u060c \u0641\u0627\u06cc\u0644 Release \u0631\u0648 \u0628\u0627 \u06a9\u0644\u06cc\u062f \u062f\u0631\u0633\u062a \u0627\u0645\u0636\u0627 \u06a9\u0646\u06cc\u0645\u060c AAB \u0645\u0646\u0627\u0633\u0628 Google Play \u0648 \u062e\u0631\u0648\u062c\u06cc \u0645\u0646\u0627\u0633\u0628 \u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631 \u0631\u0648 \u0628\u0633\u0627\u0632\u06cc\u0645\u060c \u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u0648\u0646 \u0646\u0633\u062e\u0647 \u0646\u0647\u0627\u06cc\u06cc \u0631\u0648 \u0631\u0648\u06cc \u062f\u0633\u062a\u06af\u0627\u0647 \u0648\u0627\u0642\u0639\u06cc \u0622\u0632\u0645\u0627\u06cc\u0634 \u06a9\u0646\u06cc\u0645 \u0648 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0631\u06cc\u0645 \u062e\u0635\u0648\u0635\u06cc\u060c \u062d\u0630\u0641 \u062d\u0633\u0627\u0628\u060c \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u062c\u0645\u0639\u200c\u0622\u0648\u0631\u06cc\u200c\u0634\u062f\u0647 \u0648 \u0635\u0641\u062d\u0647 \u0645\u0639\u0631\u0641\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0627 \u0631\u0641\u062a\u0627\u0631 \u0648\u0627\u0642\u0639\u06cc \u0645\u062d\u0635\u0648\u0644 \u0647\u0645\u0627\u0647\u0646\u06af \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0646\u0633\u062e\u0647 \u0627\u0648\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646\u060c \u0645\u0633\u06cc\u0631 \u0645\u0637\u0645\u0626\u0646 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0627\u0628\u062a\u062f\u0627 APK Release \u0631\u0648 \u0631\u0648\u06cc \u0686\u0646\u062f \u062f\u0633\u062a\u06af\u0627\u0647 \u0622\u0632\u0645\u0627\u06cc\u0634 \u06a9\u0646\u06cc\u0645\u060c AAB \u0627\u0645\u0636\u0627\u0634\u062f\u0647 \u0631\u0648 \u062f\u0631 Internal Testing \u06af\u0648\u06af\u0644\u200c\u067e\u0644\u06cc \u0642\u0631\u0627\u0631 \u0628\u062f\u06cc\u0645\u060c \u062a\u0633\u062a\u0631\u0647\u0627 \u0645\u0633\u06cc\u0631\u0647\u0627\u06cc \u0627\u0635\u0644\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u0646\u060c \u0633\u067e\u0633 \u0634\u0631\u0627\u06cc\u0637 Closed Testing \u0648 Production \u062d\u0633\u0627\u0628 \u0631\u0648 \u062a\u06a9\u0645\u06cc\u0644 \u06a9\u0646\u06cc\u0645. \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0646\u0633\u062e\u0647 \u0645\u0646\u0627\u0633\u0628 \u06a9\u0627\u0641\u0647\u200c\u0628\u0627\u0632\u0627\u0631 \u0631\u0648 \u062f\u0631 \u067e\u06cc\u0634\u062e\u0627\u0646 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0648 \u0628\u0639\u062f \u0627\u0632 \u0628\u0631\u0631\u0633\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u060c \u0627\u0648\u0646 \u0631\u0648 \u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0645\u06cc\u200c\u0641\u0631\u0633\u062a\u06cc\u0645. \u0627\u0632 \u0646\u0633\u062e\u0647 \u062f\u0648\u0645 \u0628\u0647 \u0628\u0639\u062f \u0647\u0645 \u0647\u0631 \u0628\u0627\u0631 <code>versionCode<\/code> \u0631\u0648 \u0627\u0641\u0632\u0627\u06cc\u0634 \u0645\u06cc\u200c\u062f\u06cc\u0645\u060c \u062e\u0631\u0648\u062c\u06cc \u062a\u0627\u0632\u0647 \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645\u060c Release Notes \u0645\u06cc\u200c\u0646\u0648\u06cc\u0633\u06cc\u0645 \u0648 \u0628\u0647\u200c\u062c\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0639\u062c\u0648\u0644\u0627\u0646\u0647 \u0628\u0631\u0627\u06cc \u062a\u0645\u0627\u0645 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646\u060c \u0627\u0628\u062a\u062f\u0627 \u0646\u0633\u062e\u0647 \u0631\u0648 \u0631\u0648\u06cc \u06af\u0631\u0648\u0647 \u06a9\u0648\u0686\u06a9\u06cc \u0622\u0632\u0645\u0627\u06cc\u0634 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. \u0627\u06cc\u0646 \u0641\u0631\u0627\u06cc\u0646\u062f \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0632 \u06cc\u06a9 \u0627\u062a\u0641\u0627\u0642 \u067e\u0631\u0631\u06cc\u0633\u06a9 \u0628\u0647 \u06cc\u06a9 \u0631\u0648\u0646\u062f \u06a9\u0646\u062a\u0631\u0644\u200c\u0634\u062f\u0647 \u0648 \u0642\u0627\u0628\u0644\u200c\u062a\u06a9\u0631\u0627\u0631 \u062a\u0628\u062f\u06cc\u0644 \u0628\u0634\u0647.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u200c\u0648\u0633\u0648\u0645<\/h3>\n\n\n\n<h1 class=\"wp-block-heading\">\u0645\u0642\u06cc\u0627\u0633\u200c\u067e\u0630\u06cc\u0631\u06cc \u0648 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0647\u0645\u200c\u0632\u0645\u0627\u0646<\/h1>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"819\" height=\"1024\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-08-1-819x1024.avif\" alt=\"\" class=\"wp-image-6163\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-08-1-819x1024.avif 819w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-08-1-240x300.avif 240w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-08-1-768x960.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-08-1.avif 1122w\" sizes=\"(max-width: 819px) 100vw, 819px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u0648\u0642\u062a\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0641\u0642\u0637 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u062e\u0648\u062f\u062a \u0648 \u0686\u0646\u062f \u0646\u0641\u0631 \u0627\u0632 \u062f\u0648\u0633\u062a\u0627\u0646\u062a \u0646\u0635\u0628\u0647\u060c \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0631 \u0645\u0639\u0645\u0627\u0631\u06cc\u200c\u0627\u06cc \u062e\u0648\u0628 \u0628\u0647 \u0646\u0638\u0631 \u0645\u06cc\u200c\u0631\u0633\u0647. \u06a9\u0627\u0631\u0628\u0631 \u0635\u0641\u062d\u0647 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0648 \u0628\u0627\u0632 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0647 API \u0645\u06cc\u200c\u0641\u0631\u0633\u062a\u0647\u060c \u0633\u0631\u0648\u0631 \u0627\u0632 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0648 \u0645\u06cc\u200c\u062e\u0648\u0646\u0647 \u0648 \u062c\u0648\u0627\u0628 \u0631\u0648 \u0628\u0631\u0645\u06cc\u200c\u06af\u0631\u062f\u0648\u0646\u0647. \u0686\u0648\u0646 \u062a\u0639\u062f\u0627\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u06a9\u0645\u0647\u060c \u062d\u062a\u06cc \u0627\u06af\u0631 Query\u0647\u0627 \u0628\u0647\u06cc\u0646\u0647 \u0646\u0628\u0627\u0634\u0646\u060c \u067e\u0627\u0633\u062e API \u06a9\u0645\u06cc \u0633\u0646\u06af\u06cc\u0646 \u0628\u0627\u0634\u0647 \u06cc\u0627 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0627 \u0647\u0631 \u0628\u0627\u0631 \u0644\u0645\u0633 \u062f\u06a9\u0645\u0647 \u0686\u0646\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062a\u06a9\u0631\u0627\u0631\u06cc \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0647\u060c \u0627\u062d\u062a\u0645\u0627\u0644\u0627\u064b \u0647\u06cc\u0686 \u0645\u0634\u06a9\u0644\u06cc \u062f\u06cc\u062f\u0647 \u0646\u0645\u06cc\u0634\u0647. \u0627\u0645\u0627 \u0648\u0642\u062a\u06cc \u062a\u0639\u062f\u0627\u062f \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0627\u0641\u0632\u0627\u06cc\u0634 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0636\u0639\u0641\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0642\u0628\u0644\u0627\u064b \u067e\u0646\u0647\u0627\u0646 \u0628\u0648\u062f\u0646 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u062e\u0648\u062f\u0634\u0648\u0646 \u0631\u0648 \u0646\u0634\u0648\u0646 \u0645\u06cc\u062f\u0646\u061b CPU \u0633\u0631\u0648\u0631 \u062f\u0631\u06af\u06cc\u0631 \u0645\u06cc\u0634\u0647\u060c \u062a\u0639\u062f\u0627\u062f \u0627\u062a\u0635\u0627\u0644\u200c\u0647\u0627\u06cc \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0628\u0627\u0644\u0627 \u0645\u06cc\u0631\u0647\u060c \u0635\u0641 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u0637\u0648\u0644\u0627\u0646\u06cc \u0645\u06cc\u0634\u0647\u060c \u0632\u0645\u0627\u0646 \u067e\u0627\u0633\u062e \u0627\u0641\u0632\u0627\u06cc\u0634 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0628\u0631\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0635\u0641\u062d\u0647 \u0628\u0627\u0632 \u0646\u0634\u062f\u0647 \u062f\u0648\u0628\u0627\u0631\u0647 \u062f\u06a9\u0645\u0647 \u0631\u0648 \u0644\u0645\u0633 \u0645\u06cc\u200c\u06a9\u0646\u0646. \u0647\u0645\u06cc\u0646 \u0631\u0641\u062a\u0627\u0631\u060c \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0628\u06cc\u0634\u062a\u0631\u06cc \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u0641\u0634\u0627\u0631 \u0633\u06cc\u0633\u062a\u0645 \u0631\u0648 \u0634\u062f\u06cc\u062f\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0642\u06cc\u0627\u0633\u200c\u067e\u0630\u06cc\u0631\u06cc \u06cc\u0639\u0646\u06cc \u0633\u06cc\u0633\u062a\u0645 \u0628\u0627 \u0627\u0641\u0632\u0627\u06cc\u0634 \u062a\u0639\u062f\u0627\u062f \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0648 \u062d\u062c\u0645 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u060c \u0647\u0645\u0686\u0646\u0627\u0646 \u0628\u062a\u0648\u0646\u0647 \u0639\u0645\u0644\u06a9\u0631\u062f \u0642\u0627\u0628\u0644\u200c\u0642\u0628\u0648\u0644\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u0627\u06cc\u0646 \u062a\u0639\u0631\u06cc\u0641 \u0628\u0647 \u0627\u06cc\u0646 \u0645\u0639\u0646\u0627 \u0646\u06cc\u0633\u062a \u06a9\u0647 \u06cc\u06a9 \u0633\u0631\u0648\u0631 \u0628\u0627\u06cc\u062f \u0628\u06cc\u200c\u0646\u0647\u0627\u06cc\u062a \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0631\u0648 \u062a\u062d\u0645\u0644 \u06a9\u0646\u0647. \u0647\u06cc\u0686 \u0633\u06cc\u0633\u062a\u0645 \u0648\u0627\u0642\u0639\u06cc \u0638\u0631\u0641\u06cc\u062a \u0646\u0627\u0645\u062d\u062f\u0648\u062f \u0646\u062f\u0627\u0631\u0647. \u0645\u0633\u0626\u0644\u0647 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0645\u0639\u0645\u0627\u0631\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0637\u0648\u0631\u06cc \u0637\u0631\u0627\u062d\u06cc \u0628\u0634\u0647 \u06a9\u0647 \u0628\u0627 \u0631\u0634\u062f \u06a9\u0627\u0631\u0628\u0631\u0627\u0646\u060c \u0628\u062a\u0648\u0646\u06cc\u0645 \u0638\u0631\u0641\u06cc\u062a \u0631\u0648 \u0628\u0647\u200c\u0634\u06a9\u0644 \u06a9\u0646\u062a\u0631\u0644\u200c\u0634\u062f\u0647 \u0627\u0641\u0632\u0627\u06cc\u0634 \u0628\u062f\u06cc\u0645 \u0648 \u0627\u0632 \u062a\u0648\u0644\u06cc\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u06a9\u0646\u06cc\u0645. \u0645\u062f\u06cc\u0631\u06cc\u062a \u0686\u0646\u062f \u0647\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0641\u0642\u0637 \u0645\u0633\u0626\u0648\u0644\u06cc\u062a Backend \u0646\u06cc\u0633\u062a\u061b \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0628\u0627 Cache\u060c Pagination\u060c Debounce\u060c Retry \u0635\u062d\u06cc\u062d \u0648 \u0647\u0645\u06af\u0627\u0645\u200c\u0633\u0627\u0632\u06cc \u0647\u0648\u0634\u0645\u0646\u062f\u060c \u0628\u062e\u0634 \u0628\u0632\u0631\u06af\u06cc \u0627\u0632 \u0641\u0634\u0627\u0631 \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u0631\u0648\u06cc \u0633\u0631\u0648\u0631 \u0631\u0648 \u06a9\u0645 \u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00ab\u06a9\u0627\u0631\u0628\u0631 \u0647\u0645\u200c\u0632\u0645\u0627\u0646\u00bb \u062f\u0642\u06cc\u0642\u0627\u064b \u06cc\u0639\u0646\u06cc \u0686\u06cc\u061f<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"683\" height=\"1024\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-10-1-683x1024.avif\" alt=\"\" class=\"wp-image-6165\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-10-1-683x1024.avif 683w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-10-1-200x300.avif 200w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-10-1-768x1152.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-10-1.avif 1024w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0635\u062f \u0647\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u062b\u0628\u062a\u200c\u0634\u062f\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u0627\u06cc\u0646 \u0639\u062f\u062f \u0628\u0647\u200c\u062a\u0646\u0647\u0627\u06cc\u06cc \u0646\u0645\u06cc\u06af\u0647 \u0633\u0631\u0648\u0631 \u0628\u0627\u06cc\u062f \u062f\u0631 \u0647\u0631 \u0644\u062d\u0638\u0647 \u0635\u062f \u0647\u0632\u0627\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0631\u0648 \u067e\u0627\u0633\u062e \u0628\u062f\u0647. \u0645\u0645\u06a9\u0646\u0647 \u0641\u0642\u0637 \u067e\u0646\u062c \u0647\u0632\u0627\u0631 \u0646\u0641\u0631 \u062f\u0631 \u06cc\u06a9 \u0633\u0627\u0639\u062a \u0645\u0634\u062e\u0635 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0627\u0632 \u06a9\u0646\u0646 \u0648 \u0647\u0631\u06a9\u062f\u0648\u0645 \u0647\u0645 \u0686\u0646\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0641\u0631\u0633\u062a\u0646. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0628\u0631\u0627\u06cc \u0633\u0646\u062c\u0634 \u0641\u0634\u0627\u0631 \u0648\u0627\u0642\u0639\u06cc \u0633\u06cc\u0633\u062a\u0645\u060c \u0628\u0627\u06cc\u062f \u0628\u0647 \u062a\u0639\u062f\u0627\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0631 \u062b\u0627\u0646\u06cc\u0647\u060c \u0632\u0645\u0627\u0646 \u067e\u0631\u062f\u0627\u0632\u0634 \u0647\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u060c \u062a\u0639\u062f\u0627\u062f \u0627\u062a\u0635\u0627\u0644\u200c\u0647\u0627\u06cc \u0641\u0639\u0627\u0644 \u0648 \u062d\u062c\u0645 \u062f\u0627\u062f\u0647 \u0645\u0646\u062a\u0642\u0644\u200c\u0634\u062f\u0647 \u062a\u0648\u062c\u0647 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u062f\u0647 \u0647\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062f\u0631 \u06cc\u06a9 \u0632\u0645\u0627\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0627\u0632 \u0645\u06cc\u200c\u06a9\u0646\u0646 \u0648 \u0635\u0641\u062d\u0647 \u0627\u0635\u0644\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0647\u0646\u06af\u0627\u0645 \u0627\u062c\u0631\u0627 \u0633\u0647 API \u0631\u0648 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/profile\nGET \/tracked-products\nGET \/notifications\/unread-count\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u062d\u0627\u0644\u062a\u060c \u062f\u0647 \u0647\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u062f\u0631 \u0645\u062f\u062a \u06a9\u0648\u062a\u0627\u0647\u06cc \u0633\u06cc \u0647\u0632\u0627\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062a\u0648\u0644\u06cc\u062f \u06a9\u0646\u0646. \u0627\u06af\u0631 WorkManager \u0647\u0645 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0642\u06cc\u0645\u062a\u200c\u0647\u0627 \u0631\u0648 Sync \u06a9\u0646\u0647 \u0648 \u0647\u0631 \u0645\u062d\u0635\u0648\u0644 \u062c\u062f\u0627\u06af\u0627\u0646\u0647 \u0627\u0632 \u0633\u0631\u0648\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0634\u0647\u060c \u062a\u0639\u062f\u0627\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u062e\u06cc\u0644\u06cc \u0628\u06cc\u0634\u062a\u0631 \u0645\u06cc\u0634\u0647. \u0645\u062b\u0644\u0627\u064b \u0627\u06af\u0631 \u0647\u0631 \u06a9\u0627\u0631\u0628\u0631 \u067e\u0646\u062c\u0627\u0647 \u0645\u062d\u0635\u0648\u0644 \u0630\u062e\u06cc\u0631\u0647\u200c\u0634\u062f\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647 \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0631\u0627\u06cc \u0647\u0631 \u0645\u062d\u0635\u0648\u0644 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0641\u0631\u0633\u062a\u0647\u060c \u062f\u0647 \u0647\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u067e\u0627\u0646\u0635\u062f \u0647\u0632\u0627\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>10,000 users \u00d7 50 products = 500,000 requests\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0634\u06a9\u0644 \u0627\u0635\u0644\u06cc \u0647\u0645\u06cc\u0634\u0647 \u062a\u0639\u062f\u0627\u062f \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0646\u06cc\u0633\u062a\u061b \u06af\u0627\u0647\u06cc \u0637\u0631\u0627\u062d\u06cc \u0627\u0634\u062a\u0628\u0627\u0647 API \u0648 \u0631\u0641\u062a\u0627\u0631 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0647\u200c\u0627\u0646\u062f\u0627\u0632\u0647 \u062f\u0647\u200c\u0647\u0627 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0647 \u0633\u0631\u0648\u0631 \u0641\u0634\u0627\u0631 \u0648\u0627\u0631\u062f \u06a9\u0646\u0647. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0642\u0628\u0644 \u0627\u0632 \u062e\u0631\u06cc\u062f \u0633\u0631\u0648\u0631 \u0642\u0648\u06cc\u200c\u062a\u0631 \u0628\u0627\u06cc\u062f \u0628\u0641\u0647\u0645\u06cc\u0645 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u0627\u0632 \u06a9\u062c\u0627 \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u0634\u0646 \u0648 \u0622\u06cc\u0627 \u0648\u0627\u0642\u0639\u0627\u064b \u0636\u0631\u0648\u0631\u06cc \u0647\u0633\u062a\u0646 \u06cc\u0627 \u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0648\u0644\u06cc\u0646 \u0642\u0627\u0646\u0648\u0646 \u0645\u0642\u06cc\u0627\u0633\u200c\u067e\u0630\u06cc\u0631\u06cc: \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u0631\u0648 \u0627\u0635\u0644\u0627\u064b \u0627\u06cc\u062c\u0627\u062f \u0646\u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647\u06cc\u0646\u0647\u200c\u062a\u0631\u06cc\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u060c \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u06cc \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0633\u0631\u0648\u0631 \u0627\u0648\u0646 \u0631\u0648 \u062f\u0631 \u062f\u0647 \u0645\u06cc\u0644\u06cc\u200c\u062b\u0627\u0646\u06cc\u0647 \u067e\u0627\u0633\u062e \u0628\u062f\u0647\u061b \u0628\u0647\u06cc\u0646\u0647\u200c\u062a\u0631\u06cc\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u060c \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u06cc\u0647 \u06a9\u0647 \u0627\u0635\u0644\u0627\u064b \u0644\u0627\u0632\u0645 \u0646\u0628\u0627\u0634\u0647 \u0628\u0647 \u0633\u0631\u0648\u0631 \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0647. \u0641\u0631\u0636 \u06a9\u0646 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631 \u0635\u0641\u062d\u0647 \u062c\u0633\u062a\u200c\u0648\u062c\u0648\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0639\u0628\u0627\u0631\u062a \u00ab\u0644\u067e\u200c\u062a\u0627\u067e\u00bb \u0631\u0648 \u062a\u0627\u06cc\u067e \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06af\u0631 \u0628\u0627 \u0648\u0627\u0631\u062f \u0634\u062f\u0646 \u0647\u0631 \u062d\u0631\u0641 \u0641\u0648\u0631\u0627\u064b API \u062c\u0633\u062a\u200c\u0648\u062c\u0648 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0628\u0634\u0647\u060c \u062a\u0627\u06cc\u067e \u0647\u0645\u06cc\u0646 \u06cc\u06a9 \u06a9\u0644\u0645\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0686\u0646\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062a\u0648\u0644\u06cc\u062f \u06a9\u0646\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u0644\n\u0644\u067e\n\u0644\u067e\u200c\n\u0644\u067e\u200c\u062a\n\u0644\u067e\u200c\u062a\u0627\n\u0644\u067e\u200c\u062a\u0627\u067e\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0633\u0627\u062f\u0647 \u0645\u0645\u06a9\u0646\u0647 \u0628\u0647 \u0627\u06cc\u0646 \u0634\u06a9\u0644 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun onSearchTextChanged(query: String) {\n    viewModelScope.launch {\n        repository.searchProducts(query)\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onSearchTextChanged<\/span><span style=\"color: #24292E\">(query: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    viewModelScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        repository.<\/span><span style=\"color: #6F42C1\">searchProducts<\/span><span style=\"color: #24292E\">(query)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0645\u062f\u0644\u060c \u0647\u0631 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u062a\u0646 \u06cc\u06a9 Coroutine \u062a\u0627\u0632\u0647 \u0648 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0634\u0628\u06a9\u0647 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0633\u0631\u06cc\u0639 \u062a\u0627\u06cc\u067e \u06a9\u0646\u0647\u060c \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 \u0639\u0628\u0627\u0631\u062a \u0646\u0627\u0642\u0635 \u0647\u0646\u0648\u0632 \u062f\u0631 \u062d\u0627\u0644 \u0627\u062c\u0631\u0627\u0633\u062a \u06a9\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0639\u062f\u06cc \u0641\u0631\u0633\u062a\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647. \u062d\u062a\u06cc \u0645\u0645\u06a9\u0646\u0647 \u067e\u0627\u0633\u062e \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0642\u062f\u06cc\u0645\u06cc \u062f\u06cc\u0631\u062a\u0631 \u0628\u0631\u06af\u0631\u062f\u0647 \u0648 \u0646\u062a\u06cc\u062c\u0647 \u062c\u062f\u06cc\u062f\u062a\u0631 \u0631\u0648 \u0628\u0627 \u062f\u0627\u062f\u0647 \u0645\u0646\u0633\u0648\u062e \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u0627\u0647 \u0645\u0646\u0627\u0633\u0628 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 <code>StateFlow<\/code>\u060c <code>debounce<\/code> \u0648 <code>distinctUntilChanged<\/code> \u0647\u0633\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductSearchViewModel(\n    private val repository: ProductRepository\n) : ViewModel() {\n\n    private val searchQuery =\n        MutableStateFlow(\"\")\n\n    val searchResult =\n        searchQuery\n            .map { query ->\n                query.trim()\n            }\n            .debounce(500)\n            .distinctUntilChanged()\n            .flatMapLatest { query ->\n                if (query.length &lt; 2) {\n                    flowOf(emptyList())\n                } else {\n                    repository.searchProducts(query)\n                }\n            }\n            .stateIn(\n                scope = viewModelScope,\n                started = SharingStarted.WhileSubscribed(5_000),\n                initialValue = emptyList()\n            )\n\n    fun onSearchTextChanged(query: String) {\n        searchQuery.value = query\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductSearchViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> repository: <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ViewModel<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> searchQuery <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">MutableStateFlow<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> searchResult <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        searchQuery<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> { query <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                query.<\/span><span style=\"color: #6F42C1\">trim<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">debounce<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">500<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">distinctUntilChanged<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">flatMapLatest<\/span><span style=\"color: #24292E\"> { query <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (query.length <\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">2<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #6F42C1\">flowOf<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #6F42C1\">emptyList<\/span><span style=\"color: #24292E\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    repository.<\/span><span style=\"color: #6F42C1\">searchProducts<\/span><span style=\"color: #24292E\">(query)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">stateIn<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                scope <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> viewModelScope,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                started <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> SharingStarted.<\/span><span style=\"color: #6F42C1\">WhileSubscribed<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">5_000<\/span><span style=\"color: #24292E\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                initialValue <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">emptyList<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onSearchTextChanged<\/span><span style=\"color: #24292E\">(query: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        searchQuery.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> query<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><code>debounce(500)<\/code> \u0635\u0628\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u062a\u0627 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0631\u0627\u06cc \u067e\u0627\u0646\u0635\u062f \u0645\u06cc\u0644\u06cc\u200c\u062b\u0627\u0646\u06cc\u0647 \u062a\u0627\u06cc\u067e \u0631\u0648 \u0645\u062a\u0648\u0642\u0641 \u06a9\u0646\u0647. <code>distinctUntilChanged()<\/code> \u0627\u062c\u0627\u0632\u0647 \u0646\u0645\u06cc\u062f\u0647 \u0639\u0628\u0627\u0631\u062a \u06cc\u06a9\u0633\u0627\u0646 \u062f\u0648\u0628\u0627\u0631\u0647 \u067e\u0631\u062f\u0627\u0632\u0634 \u0628\u0634\u0647 \u0648 <code>flatMapLatest<\/code> \u0647\u0645 \u0648\u0642\u062a\u06cc \u0639\u0628\u0627\u0631\u062a \u062c\u062f\u06cc\u062f\u06cc \u0648\u0627\u0631\u062f \u0645\u06cc\u0634\u0647\u060c \u062f\u0631\u06cc\u0627\u0641\u062a \u0646\u062a\u06cc\u062c\u0647 \u0642\u0628\u0644\u06cc \u0631\u0648 \u06a9\u0646\u0627\u0631 \u0645\u06cc\u200c\u06af\u0630\u0627\u0631\u0647. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u062a\u0627\u06cc\u067e \u06cc\u06a9 \u06a9\u0644\u0645\u0647 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0628\u0647\u200c\u062c\u0627\u06cc \u0634\u0634 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u060c \u0641\u0642\u0637 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0646\u0647\u0627\u06cc\u06cc \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06cc\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u0631\u0648\u06cc \u06cc\u06a9 \u06af\u0648\u0634\u06cc \u0633\u0627\u062f\u0647 \u0628\u0647 \u0646\u0638\u0631 \u0645\u06cc\u200c\u0631\u0633\u0647\u060c \u0627\u0645\u0627 \u062f\u0631 \u0645\u0642\u06cc\u0627\u0633 \u062f\u0647\u200c\u0647\u0627 \u0647\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0645\u06cc\u0644\u06cc\u0648\u0646\u200c\u0647\u0627 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u0636\u0627\u0641\u06cc \u0631\u0648 \u062d\u0630\u0641 \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u06cc\u0646 \u0645\u0646\u0637\u0642 \u0628\u0631\u0627\u06cc \u062f\u06a9\u0645\u0647 Refresh \u0647\u0645 \u0644\u0627\u0632\u0645\u0647. \u06a9\u0627\u0631\u0628\u0631 \u0645\u0645\u06a9\u0646\u0647 \u0628\u0647\u200c\u062e\u0627\u0637\u0631 \u06a9\u0646\u062f \u0628\u0648\u062f\u0646 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0686\u0646\u062f \u0628\u0627\u0631 \u067e\u0634\u062a \u0633\u0631 \u0647\u0645 \u062f\u06a9\u0645\u0647 \u0631\u0648 \u0644\u0645\u0633 \u06a9\u0646\u0647. \u0627\u06af\u0631 \u0647\u0631 \u0644\u0645\u0633 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u0633\u062a\u0642\u0644 \u0628\u0633\u0627\u0632\u0647\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0627\u062e\u0648\u0627\u0633\u062a\u0647 \u062d\u0645\u0644\u0647 \u06a9\u0648\u0686\u06a9\u06cc \u0639\u0644\u06cc\u0647 \u0633\u0631\u0648\u0631 \u062e\u0648\u062f\u0634 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0647. \u0633\u0627\u062f\u0647\u200c\u062a\u0631\u06cc\u0646 \u0631\u0627\u0647 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0647\u0646\u06af\u0627\u0645 \u0627\u062c\u0631\u0627\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u060c \u062f\u06a9\u0645\u0647 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u0628\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class PriceUiState(\n    val isLoading: Boolean = false,\n    val products: List&lt;Product> = emptyList(),\n    val errorMessage: String? = null\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceUiState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isLoading: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">emptyList<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> errorMessage: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class PriceViewModel(\n    private val repository: PriceRepository\n) : ViewModel() {\n\n    private val _uiState =\n        MutableStateFlow(PriceUiState())\n\n    val uiState =\n        _uiState.asStateFlow()\n\n    fun refreshPrices() {\n        if (_uiState.value.isLoading) {\n            return\n        }\n\n        viewModelScope.launch {\n            _uiState.update {\n                it.copy(\n                    isLoading = true,\n                    errorMessage = null\n                )\n            }\n\n            runCatching {\n                repository.refreshPrices()\n            }.onSuccess { products ->\n                _uiState.value = PriceUiState(\n                    isLoading = false,\n                    products = products\n                )\n            }.onFailure {\n                _uiState.update { state ->\n                    state.copy(\n                        isLoading = false,\n                        errorMessage =\n                            \"\u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0642\u06cc\u0645\u062a\u200c\u0647\u0627 \u0627\u0646\u062c\u0627\u0645 \u0646\u0634\u062f.\"\n                    )\n                }\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> repository: <\/span><span style=\"color: #6F42C1\">PriceRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ViewModel<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> _uiState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">MutableStateFlow<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #6F42C1\">PriceUiState<\/span><span style=\"color: #24292E\">())<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> uiState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        _uiState.<\/span><span style=\"color: #6F42C1\">asStateFlow<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">refreshPrices<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (_uiState.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\">.isLoading) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModelScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            _uiState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    isLoading <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    errorMessage <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">runCatching<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                repository.<\/span><span style=\"color: #6F42C1\">refreshPrices<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }.<\/span><span style=\"color: #6F42C1\">onSuccess<\/span><span style=\"color: #24292E\"> { products <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                _uiState.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceUiState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    isLoading <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    products <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> products<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }.<\/span><span style=\"color: #6F42C1\">onFailure<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                _uiState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> { state <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    state.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        isLoading <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        errorMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            <\/span><span style=\"color: #032F62\">&quot;\u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0642\u06cc\u0645\u062a\u200c\u0647\u0627 \u0627\u0646\u062c\u0627\u0645 \u0646\u0634\u062f.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0631\u0627\u0628\u0637 Compose \u0647\u0645 \u0648\u0636\u0639\u06cc\u062a \u062f\u06a9\u0645\u0647 \u0631\u0648 \u0628\u0647 <code>isLoading<\/code> \u0645\u062a\u0635\u0644 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Button(\n    onClick = viewModel::refreshPrices,\n    enabled = !uiState.isLoading\n) {\n    if (uiState.isLoading) {\n        CircularProgressIndicator()\n    } else {\n        Text(\"\u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0642\u06cc\u0645\u062a\u200c\u0647\u0627\")\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">Button<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onClick <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> viewModel::<\/span><span style=\"color: #6F42C1\">refreshPrices<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    enabled <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">!<\/span><span style=\"color: #24292E\">uiState.isLoading<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (uiState.isLoading) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">CircularProgressIndicator<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">Text<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;\u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0642\u06cc\u0645\u062a\u200c\u0647\u0627&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06a9\u0646\u062a\u0631\u0644 \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u062a\u062c\u0631\u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0646\u06cc\u0633\u062a\u061b \u0628\u062e\u0634\u06cc \u0627\u0632 \u062d\u0641\u0627\u0638\u062a \u0638\u0631\u0641\u06cc\u062a \u0633\u0631\u0648\u0631 \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0647\u0645\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0648 \u06cc\u06a9\u200c\u062c\u0627 \u062f\u0631\u06cc\u0627\u0641\u062a \u0646\u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u067e\u0646\u062c \u0647\u0632\u0627\u0631 \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 \u062f\u0646\u0628\u0627\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06af\u0631 API \u062a\u0645\u0627\u0645 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0648 \u062f\u0631 \u06cc\u06a9 \u067e\u0627\u0633\u062e \u0628\u0631\u06af\u0631\u062f\u0648\u0646\u0647\u060c \u0633\u0631\u0648\u0631 \u0628\u0627\u06cc\u062f \u067e\u0646\u062c \u0647\u0632\u0627\u0631 \u0631\u062f\u06cc\u0641 \u0631\u0648 \u0627\u0632 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0628\u062e\u0648\u0646\u0647\u060c \u0627\u0648\u0646\u200c\u0647\u0627 \u0631\u0648 \u062a\u0628\u062f\u06cc\u0644 \u0628\u0647 JSON \u06a9\u0646\u0647 \u0648 \u0631\u0648\u06cc \u0634\u0628\u06a9\u0647 \u0628\u0641\u0631\u0633\u062a\u0647. \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0647\u0645 \u0628\u0627\u06cc\u062f \u06a9\u0644 \u067e\u0627\u0633\u062e \u0631\u0648 \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u0646\u06af\u0647 \u062f\u0627\u0631\u0647\u060c Parse \u06a9\u0646\u0647 \u0648 \u062f\u0631 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0645\u062d\u0644\u06cc \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0646\u0647\u061b \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631 \u0644\u062d\u0638\u0647 \u0641\u0642\u0637 \u0686\u0646\u062f \u0645\u062d\u0635\u0648\u0644 \u0627\u0648\u0644 \u0631\u0648 \u0645\u06cc\u200c\u0628\u06cc\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">API \u0646\u0627\u0645\u0646\u0627\u0633\u0628 \u0645\u0645\u06a9\u0646\u0647 \u0627\u06cc\u0646\u200c\u0637\u0648\u0631 \u0637\u0631\u0627\u062d\u06cc \u0634\u062f\u0647 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/tracked-products\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u0628\u062f\u0648\u0646 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a\u060c \u0647\u0645\u0647 \u0631\u06a9\u0648\u0631\u062f\u0647\u0627 \u0631\u0648 \u0628\u0631\u06af\u0631\u062f\u0648\u0646\u0647. API \u0645\u0646\u0627\u0633\u0628 \u0628\u0627\u06cc\u062f Pagination \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/tracked-products?page=1&amp;pageSize=30\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627 \u062f\u0631 \u0633\u06cc\u0633\u062a\u0645\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af\u200c\u062a\u0631 \u0627\u0632 Cursor \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/tracked-products?cursor=eyJpZCI6MTUwMH0=&amp;limit=30\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Retrofit \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 Endpoint \u0635\u0641\u062d\u0647\u200c\u0628\u0646\u062f\u06cc\u200c\u0634\u062f\u0647 \u062a\u0639\u0631\u06cc\u0641 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface ProductApi {\n\n    @GET(\"tracked-products\")\n    suspend fun getTrackedProducts(\n        @Query(\"page\") page: Int,\n        @Query(\"pageSize\") pageSize: Int\n    ): ProductPageDto\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductApi<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@GET<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;tracked-products&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getTrackedProducts<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;page&quot;<\/span><span style=\"color: #24292E\">) page: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;pageSize&quot;<\/span><span style=\"color: #24292E\">) pageSize: <\/span><span style=\"color: #6F42C1\">Int<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">ProductPageDto<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class ProductPageDto(\n    val items: List&lt;ProductDto>,\n    val page: Int,\n    val pageSize: Int,\n    val hasNextPage: Boolean\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductPageDto<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> items: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">ProductDto<\/span><span style=\"color: #24292E\">&gt;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> page: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> pageSize: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> hasNextPage: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0627\u0632 Paging 3 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0641\u0642\u0637 \u0635\u0641\u062d\u0647\u200c\u0647\u0627\u06cc \u0645\u0648\u0631\u062f\u0646\u06cc\u0627\u0632 \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class TrackedProductPagingSource(\n    private val api: ProductApi\n) : PagingSource&lt;Int, Product>() {\n\n    override suspend fun load(\n        params: LoadParams&lt;Int>\n    ): LoadResult&lt;Int, Product> {\n        val page = params.key ?: 1\n\n        return try {\n            val response = api.getTrackedProducts(\n                page = page,\n                pageSize = params.loadSize\n            )\n\n            LoadResult.Page(\n                data = response.items.map {\n                    it.toDomain()\n                },\n                prevKey = if (page == 1) {\n                    null\n                } else {\n                    page - 1\n                },\n                nextKey = if (response.hasNextPage) {\n                    page + 1\n                } else {\n                    null\n                }\n            )\n        } catch (exception: Exception) {\n            LoadResult.Error(exception)\n        }\n    }\n\n    override fun getRefreshKey(\n        state: PagingState&lt;Int, Product>\n    ): Int? {\n        val anchorPosition =\n            state.anchorPosition ?: return null\n\n        val anchorPage =\n            state.closestPageToPosition(\n                anchorPosition\n            )\n\n        return anchorPage?.prevKey?.plus(1)\n            ?: anchorPage?.nextKey?.minus(1)\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductPagingSource<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> api: <\/span><span style=\"color: #6F42C1\">ProductApi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">PagingSource<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt;() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">load<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        params: <\/span><span style=\"color: #6F42C1\">LoadParams<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">LoadResult<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt; {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> page <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> params.key ?: <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> response <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> api.<\/span><span style=\"color: #6F42C1\">getTrackedProducts<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                page <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> page,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                pageSize <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> params.loadSize<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            LoadResult.<\/span><span style=\"color: #6F42C1\">Page<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> response.items.<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">toDomain<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                prevKey <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (page <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    page <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                nextKey <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (response.hasNextPage) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    page <\/span><span style=\"color: #D73A49\">+<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        } <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (exception: <\/span><span style=\"color: #6F42C1\">Exception<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            LoadResult.<\/span><span style=\"color: #6F42C1\">Error<\/span><span style=\"color: #24292E\">(exception)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getRefreshKey<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        state: <\/span><span style=\"color: #6F42C1\">PagingState<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">? {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> anchorPosition <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state.anchorPosition ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> anchorPage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state.<\/span><span style=\"color: #6F42C1\">closestPageToPosition<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                anchorPosition<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> anchorPage?.prevKey?.<\/span><span style=\"color: #6F42C1\">plus<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ?: anchorPage?.nextKey?.<\/span><span style=\"color: #6F42C1\">minus<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Repository \u06cc\u06a9 <code>Pager<\/code> \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductRepository(\n    private val api: ProductApi\n) {\n\n    fun getTrackedProducts():\n        Flow&lt;PagingData&lt;Product>> {\n\n        return Pager(\n            config = PagingConfig(\n                pageSize = 30,\n                prefetchDistance = 5,\n                enablePlaceholders = false\n            ),\n            pagingSourceFactory = {\n                TrackedProductPagingSource(api)\n            }\n        ).flow\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> api: <\/span><span style=\"color: #6F42C1\">ProductApi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getTrackedProducts<\/span><span style=\"color: #24292E\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">Flow<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">PagingData<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt;&gt; {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Pager<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            config <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PagingConfig<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                pageSize <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">30<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                prefetchDistance <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">5<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                enablePlaceholders <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            pagingSourceFactory <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">TrackedProductPagingSource<\/span><span style=\"color: #24292E\">(api)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ).flow<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u062f\u0631 ViewModel \u062c\u0631\u06cc\u0627\u0646 \u062f\u0627\u062f\u0647 \u0631\u0648 Cache \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductListViewModel(\n    repository: ProductRepository\n) : ViewModel() {\n\n    val products =\n        repository\n            .getTrackedProducts()\n            .cachedIn(viewModelScope)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductListViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    repository: <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ViewModel<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        repository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">getTrackedProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">cachedIn<\/span><span style=\"color: #24292E\">(viewModelScope)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc \u0647\u0645 \u0645\u0635\u0631\u0641 \u062d\u0627\u0641\u0638\u0647 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0631\u0648 \u06a9\u0627\u0647\u0634 \u0645\u06cc\u062f\u0647 \u0648 \u0647\u0645 \u0641\u0634\u0627\u0631 \u0648\u0627\u0631\u062f\u0634\u062f\u0647 \u0628\u0647 API \u0648 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0631\u0648 \u06a9\u0646\u062a\u0631\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u0644\u0628\u062a\u0647 Pagination \u0641\u0642\u0637 \u0632\u0645\u0627\u0646\u06cc \u0645\u0624\u062b\u0631\u0647 \u06a9\u0647 Backend \u0647\u0645 Query \u062f\u0631\u0633\u062a \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u0627\u06af\u0631 \u0633\u0631\u0648\u0631 \u0628\u0631\u0627\u06cc \u0628\u0631\u06af\u0631\u062f\u0627\u0646\u062f\u0646 \u0633\u06cc \u0645\u062d\u0635\u0648\u0644\u060c \u0627\u0628\u062a\u062f\u0627 \u062a\u0645\u0627\u0645 \u067e\u0646\u062c \u0647\u0632\u0627\u0631 \u0631\u06a9\u0648\u0631\u062f \u0631\u0648 \u0628\u062e\u0648\u0646\u0647 \u0648 \u0628\u0639\u062f \u0633\u06cc \u0645\u0648\u0631\u062f \u0631\u0648 \u062c\u062f\u0627 \u06a9\u0646\u0647\u060c \u0641\u0642\u0637 \u067e\u0627\u0633\u062e \u0634\u0628\u06a9\u0647 \u06a9\u0648\u0686\u06a9 \u0634\u062f\u0647 \u0648 \u0641\u0634\u0627\u0631 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0647\u0645\u0686\u0646\u0627\u0646 \u0628\u0627\u0642\u06cc \u0645\u0648\u0646\u062f\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0631\u0627\u06cc \u0686\u0646\u062f \u0645\u062d\u0635\u0648\u0644\u060c \u0646\u0647 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0631\u0627\u06cc \u0647\u0631 \u0645\u062d\u0635\u0648\u0644<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u062f\u0631 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646\u200c\u0647\u0627\u06cc \u0642\u06cc\u0645\u062a \u0648 \u0641\u0631\u0648\u0634\u06af\u0627\u0647 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0628\u0631\u0627\u06cc \u0647\u0631 \u0622\u06cc\u062a\u0645 \u06cc\u06a9 API \u062c\u062f\u0627\u06af\u0627\u0646\u0647 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0628\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>products.forEach { product ->\n    repository.getLatestPrice(product.id)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">products.<\/span><span style=\"color: #6F42C1\">forEach<\/span><span style=\"color: #24292E\"> { product <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    repository.<\/span><span style=\"color: #6F42C1\">getLatestPrice<\/span><span style=\"color: #24292E\">(product.id)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u067e\u0646\u062c\u0627\u0647 \u0645\u062d\u0635\u0648\u0644 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0627\u06cc\u0646 \u062d\u0644\u0642\u0647 \u067e\u0646\u062c\u0627\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0634\u0628\u06a9\u0647 \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. \u062f\u0631 \u0645\u0642\u06cc\u0627\u0633 \u0647\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631\u060c \u0647\u0645\u06cc\u0646 \u0635\u0641\u062d\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u067e\u0646\u062c\u0627\u0647 \u0647\u0632\u0627\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0647. \u0631\u0627\u0647 \u0628\u0647\u062a\u0631 \u0637\u0631\u0627\u062d\u06cc Endpoint \u06af\u0631\u0648\u0647\u06cc\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>POST \/products\/latest-prices\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u062f\u0646\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"productIds\": &#91;101, 102, 103, 104, 105&#93;\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;productIds&quot;<\/span><span style=\"color: #24292E\">: &#91;<\/span><span style=\"color: #005CC5\">101<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #005CC5\">102<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #005CC5\">103<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #005CC5\">104<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #005CC5\">105<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u067e\u0627\u0633\u062e:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"prices\": &#91;\n    {\n      \"productId\": 101,\n      \"price\": 42500000\n    },\n    {\n      \"productId\": 102,\n      \"price\": 18600000\n    }\n  &#93;\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;prices&quot;<\/span><span style=\"color: #24292E\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;productId&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #6F42C1\">101<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;price&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #6F42C1\">42500000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;productId&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #6F42C1\">102<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;price&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #6F42C1\">18600000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  &#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Retrofit:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class LatestPriceRequest(\n    val productIds: List&lt;Long>\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">LatestPriceRequest<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productIds: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface PriceApi {\n\n    @POST(\"products\/latest-prices\")\n    suspend fun getLatestPrices(\n        @Body request: LatestPriceRequest\n    ): List&lt;LatestPriceDto>\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceApi<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@POST<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;products\/latest-prices&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getLatestPrices<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Body<\/span><span style=\"color: #24292E\"> request: <\/span><span style=\"color: #6F42C1\">LatestPriceRequest<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">LatestPriceDto<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun loadLatestPrices(\n    products: List&lt;Product>\n): List&lt;LatestPrice> {\n\n    if (products.isEmpty()) {\n        return emptyList()\n    }\n\n    return priceApi\n        .getLatestPrices(\n            LatestPriceRequest(\n                productIds = products.map {\n                    it.id\n                }\n            )\n        )\n        .map {\n            it.toDomain()\n        }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">loadLatestPrices<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    products: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">): <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">LatestPrice<\/span><span style=\"color: #24292E\">&gt; {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (products.<\/span><span style=\"color: #6F42C1\">isEmpty<\/span><span style=\"color: #24292E\">()) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">emptyList<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> priceApi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">getLatestPrices<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">LatestPriceRequest<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                productIds <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> products.<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.id<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            it.<\/span><span style=\"color: #6F42C1\">toDomain<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0628\u0627\u06cc\u062f \u062a\u0639\u062f\u0627\u062f \u0634\u0646\u0627\u0633\u0647\u200c\u0647\u0627 \u0631\u0648 \u0647\u0645 \u0646\u0627\u0645\u062d\u062f\u0648\u062f \u0628\u06af\u0630\u0627\u0631\u06cc\u0645. \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0647 \u0647\u0632\u0627\u0631 \u0645\u062d\u0635\u0648\u0644 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0627\u0631\u0633\u0627\u0644 \u0647\u0645\u0647 \u0634\u0646\u0627\u0633\u0647\u200c\u0647\u0627 \u062f\u0631 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062e\u0648\u062f\u0634 \u0645\u0634\u06a9\u0644 \u062a\u0627\u0632\u0647\u200c\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0634\u0646\u0627\u0633\u0647\u200c\u0647\u0627 \u0631\u0648 \u0628\u0647 \u06af\u0631\u0648\u0647\u200c\u0647\u0627\u06cc \u0645\u062d\u062f\u0648\u062f \u062a\u0642\u0633\u06cc\u0645 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun loadLatestPrices(\n    productIds: List&lt;Long>\n): List&lt;LatestPrice> {\n\n    return productIds\n        .chunked(100)\n        .flatMap { chunk ->\n            priceApi\n                .getLatestPrices(\n                    LatestPriceRequest(chunk)\n                )\n                .map {\n                    it.toDomain()\n                }\n        }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">loadLatestPrices<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    productIds: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">): <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">LatestPrice<\/span><span style=\"color: #24292E\">&gt; {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> productIds<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">chunked<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">100<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">flatMap<\/span><span style=\"color: #24292E\"> { chunk <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            priceApi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">getLatestPrices<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #6F42C1\">LatestPriceRequest<\/span><span style=\"color: #24292E\">(chunk)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">toDomain<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0627\u06cc\u0646 \u062a\u0631\u062a\u06cc\u0628\u060c \u067e\u0646\u062c\u0627\u0647 \u0645\u062d\u0635\u0648\u0644 \u0628\u0627 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0648 \u0647\u0632\u0627\u0631 \u0645\u062d\u0635\u0648\u0644 \u0628\u0627 \u062f\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u0646\u062a\u0631\u0644\u200c\u0634\u062f\u0647 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u0634\u0646\u060c \u0646\u0647 \u0647\u0632\u0627\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u0633\u062a\u0642\u0644.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cache \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0633\u0631\u0639\u062a \u0646\u06cc\u0633\u062a\u061b \u0628\u0631\u0627\u06cc \u062d\u0641\u0638 \u0638\u0631\u0641\u06cc\u062a \u0633\u06cc\u0633\u062a\u0645\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0635\u0641\u062d\u0647 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0648 \u0628\u0627\u0632 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0644\u0627\u0632\u0645 \u0646\u06cc\u0633\u062a \u0647\u0645\u06cc\u0634\u0647 \u0645\u0646\u062a\u0638\u0631 \u067e\u0627\u0633\u062e \u0634\u0628\u06a9\u0647 \u0628\u0645\u0648\u0646\u0647. \u0627\u06af\u0631 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0642\u0628\u0644\u06cc \u062f\u0627\u062e\u0644 Room \u0630\u062e\u06cc\u0631\u0647 \u0634\u062f\u0647 \u0628\u0627\u0634\u0646\u060c \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0641\u0648\u0631\u0627\u064b \u0627\u0648\u0646\u200c\u0647\u0627 \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647 \u0648 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0634\u0628\u06a9\u0647 \u062f\u0631 \u067e\u0633\u200c\u0632\u0645\u06cc\u0646\u0647 \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647. \u0627\u06cc\u0646 \u0627\u0644\u06af\u0648 \u0639\u0644\u0627\u0648\u0647 \u0628\u0631 \u062a\u062c\u0631\u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0628\u0647\u062a\u0631\u060c \u062f\u0631 \u0632\u0645\u0627\u0646 \u0627\u062e\u062a\u0644\u0627\u0644 \u0633\u0631\u0648\u0631 \u06cc\u0627 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0647\u0645 \u0627\u062c\u0627\u0632\u0647 \u0645\u06cc\u062f\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645\u0686\u0646\u0627\u0646 \u0642\u0627\u0628\u0644\u200c\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0628\u0645\u0648\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">DAO \u0645\u062d\u0635\u0648\u0644\u0627\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Dao\ninterface ProductDao {\n\n    @Query(\n        \"\"\"\n        SELECT *\n        FROM tracked_products\n        ORDER BY updatedAt DESC\n        \"\"\"\n    )\n    fun observeProducts():\n        Flow&lt;List&lt;ProductEntity>>\n\n    @Insert(\n        onConflict = OnConflictStrategy.REPLACE\n    )\n    suspend fun insertAll(\n        products: List&lt;ProductEntity>\n    )\n\n    @Query(\n        \"\"\"\n        DELETE FROM tracked_products\n        WHERE id NOT IN (:activeIds)\n        \"\"\"\n    )\n    suspend fun deleteMissing(\n        activeIds: List&lt;Long>\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Dao<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductDao<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        SELECT *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        FROM tracked_products<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        ORDER BY updatedAt DESC<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        &quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">observeProducts<\/span><span style=\"color: #24292E\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Flow<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">List<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">ProductEntity<\/span><span style=\"color: #D73A49\">&gt;&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@Insert<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        onConflict <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> OnConflictStrategy.REPLACE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">insertAll<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        products: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">ProductEntity<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        DELETE FROM tracked_products<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        WHERE id NOT IN (:activeIds)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        &quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">deleteMissing<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        activeIds: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Repository \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0645\u062d\u0644\u06cc \u0631\u0648 \u0645\u0646\u0628\u0639 \u0627\u0635\u0644\u06cc \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0642\u0631\u0627\u0631 \u0628\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductRepository(\n    private val api: ProductApi,\n    private val productDao: ProductDao,\n    private val database: GheimatBanDatabase\n) {\n\n    fun observeProducts():\n        Flow&lt;List&lt;Product>> {\n\n        return productDao\n            .observeProducts()\n            .map { entities ->\n                entities.map {\n                    it.toDomain()\n                }\n            }\n    }\n\n    suspend fun syncProducts() {\n        val remoteProducts =\n            api.getTrackedProducts(\n                page = 1,\n                pageSize = 100\n            ).items\n\n        database.withTransaction {\n            productDao.insertAll(\n                remoteProducts.map {\n                    it.toEntity()\n                }\n            )\n\n            productDao.deleteMissing(\n                remoteProducts.map {\n                    it.id\n                }\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> api: <\/span><span style=\"color: #6F42C1\">ProductApi<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productDao: <\/span><span style=\"color: #6F42C1\">ProductDao<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> database: <\/span><span style=\"color: #6F42C1\">GheimatBanDatabase<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">observeProducts<\/span><span style=\"color: #24292E\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">Flow<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt;&gt; {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> productDao<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">observeProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> { entities <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                entities.<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">toDomain<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">syncProducts<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> remoteProducts <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            api.<\/span><span style=\"color: #6F42C1\">getTrackedProducts<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                page <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                pageSize <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">100<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ).items<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        database.<\/span><span style=\"color: #6F42C1\">withTransaction<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            productDao.<\/span><span style=\"color: #6F42C1\">insertAll<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                remoteProducts.<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">toEntity<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            productDao.<\/span><span style=\"color: #6F42C1\">deleteMissing<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                remoteProducts.<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.id<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u0635\u0641\u062d\u0647 \u0628\u0627\u0632 \u0645\u06cc\u0634\u0647\u060c ViewModel \u0645\u0646\u062a\u0638\u0631 Network \u0646\u0645\u06cc\u200c\u0645\u0648\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductViewModel(\n    private val repository: ProductRepository\n) : ViewModel() {\n\n    val products =\n        repository\n            .observeProducts()\n            .stateIn(\n                scope = viewModelScope,\n                started =\n                    SharingStarted\n                        .WhileSubscribed(5_000),\n                initialValue = emptyList()\n            )\n\n    init {\n        viewModelScope.launch {\n            runCatching {\n                repository.syncProducts()\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> repository: <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ViewModel<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        repository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">observeProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">stateIn<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                scope <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> viewModelScope,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                started <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    SharingStarted<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">WhileSubscribed<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">5_000<\/span><span style=\"color: #24292E\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                initialValue <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">emptyList<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">init<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModelScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">runCatching<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                repository.<\/span><span style=\"color: #6F42C1\">syncProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 Cache \u0646\u0628\u0627\u06cc\u062f \u0628\u0647 \u0627\u06cc\u0646 \u0645\u0639\u0646\u0627 \u0628\u0627\u0634\u0647 \u06a9\u0647 \u062f\u0631 \u0647\u0631 \u0628\u0627\u0631 \u0628\u0627\u0632 \u0634\u062f\u0646 \u0635\u0641\u062d\u0647\u060c \u0628\u062f\u0648\u0646 \u062a\u0648\u062c\u0647 \u0628\u0647 \u0632\u0645\u0627\u0646 \u0622\u062e\u0631\u06cc\u0646 Sync \u062f\u0648\u0628\u0627\u0631\u0647 \u0634\u0628\u06a9\u0647 \u0631\u0648 \u0635\u062f\u0627 \u0628\u0632\u0646\u06cc\u0645. \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u0631\u0627\u06cc \u062f\u0627\u062f\u0647\u200c\u0647\u0627 \u0632\u0645\u0627\u0646 \u0627\u0639\u062a\u0628\u0627\u0631 \u062f\u0631 \u0646\u0638\u0631 \u0628\u06af\u06cc\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class SyncPolicy(\n    private val preferences:\n        SharedPreferences\n) {\n\n    fun shouldSync(\n        maxAgeMillis: Long\n    ): Boolean {\n        val lastSync =\n            preferences.getLong(\n                \"products_last_sync\",\n                0L\n            )\n\n        return System.currentTimeMillis() -\n            lastSync > maxAgeMillis\n    }\n\n    fun markSynced() {\n        preferences\n            .edit()\n            .putLong(\n                \"products_last_sync\",\n                System.currentTimeMillis()\n            )\n            .apply()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">SyncPolicy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> preferences:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        SharedPreferences<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">shouldSync<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        maxAgeMillis: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> lastSync <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            preferences.<\/span><span style=\"color: #6F42C1\">getLong<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;products_last_sync&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #005CC5\">0L<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> System.<\/span><span style=\"color: #6F42C1\">currentTimeMillis<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">-<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            lastSync <\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\"> maxAgeMillis<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">markSynced<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        preferences<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">edit<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">putLong<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;products_last_sync&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                System.<\/span><span style=\"color: #6F42C1\">currentTimeMillis<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">apply<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062f\u0631 Repository:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun syncProductsIfNeeded() {\n    val fiveMinutes =\n        5 * 60 * 1000L\n\n    if (!syncPolicy.shouldSync(fiveMinutes)) {\n        return\n    }\n\n    syncProducts()\n    syncPolicy.markSynced()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">syncProductsIfNeeded<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> fiveMinutes <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">5<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">60<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1000L<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><span style=\"color: #D73A49\">!<\/span><span style=\"color: #24292E\">syncPolicy.<\/span><span style=\"color: #6F42C1\">shouldSync<\/span><span style=\"color: #24292E\">(fiveMinutes)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">syncProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    syncPolicy.<\/span><span style=\"color: #6F42C1\">markSynced<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631 \u0645\u062f\u062a \u06a9\u0648\u062a\u0627\u0647\u06cc \u0686\u0646\u062f \u0628\u0627\u0631 \u0648\u0627\u0631\u062f \u0635\u0641\u062d\u0647 \u0628\u0634\u0647\u060c \u062f\u0627\u062f\u0647 \u0627\u0632 Room \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647 \u0648 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062a\u06a9\u0631\u0627\u0631\u06cc \u0628\u0647 \u0633\u0631\u0648\u0631 \u0646\u0645\u06cc\u200c\u0631\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u062a\u06a9\u0631\u0627\u0631\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06af\u0627\u0647\u06cc \u0686\u0646\u062f \u0628\u062e\u0634 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u06cc\u06a9 \u062f\u0627\u062f\u0647 \u0645\u0634\u062a\u0631\u06a9 \u0631\u0648 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u06cc\u200c\u06a9\u0646\u0646. \u0645\u062b\u0644\u0627\u064b \u0635\u0641\u062d\u0647 \u0627\u0635\u0644\u06cc\u060c Notification Worker \u0648 \u0635\u0641\u062d\u0647 \u062c\u0632\u0626\u06cc\u0627\u062a \u0647\u0631 \u0633\u0647 \u0645\u06cc\u200c\u062e\u0648\u0627\u0646 \u067e\u0631\u0648\u0641\u0627\u06cc\u0644 \u06a9\u0627\u0631\u0628\u0631 \u0631\u0648 \u062a\u0627\u0632\u0647\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u0646. \u0627\u06af\u0631 Repository \u0647\u06cc\u0686 \u06a9\u0646\u062a\u0631\u0644\u06cc \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0633\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06cc\u06a9\u0633\u0627\u0646 \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u0634\u0647. \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u0627 <code>Mutex<\/code> \u0645\u0637\u0645\u0626\u0646 \u0628\u0634\u06cc\u0645 \u062f\u0631 \u0647\u0631 \u0644\u062d\u0638\u0647 \u0641\u0642\u0637 \u06cc\u06a9 Sync \u0627\u062c\u0631\u0627 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class UserRepository(\n    private val api: UserApi,\n    private val userDao: UserDao\n) {\n\n    private val syncMutex = Mutex()\n\n    suspend fun syncUser() {\n        syncMutex.withLock {\n            val user =\n                api.getCurrentUser()\n\n            userDao.insert(\n                user.toEntity()\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">UserRepository<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> api: <\/span><span style=\"color: #6F42C1\">UserApi<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> userDao: <\/span><span style=\"color: #6F42C1\">UserDao<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> syncMutex <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Mutex<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">syncUser<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        syncMutex.<\/span><span style=\"color: #6F42C1\">withLock<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> user <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                api.<\/span><span style=\"color: #6F42C1\">getCurrentUser<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            userDao.<\/span><span style=\"color: #6F42C1\">insert<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                user.<\/span><span style=\"color: #6F42C1\">toEntity<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0627\u06cc\u0646 \u06a9\u062f \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0648\u0645 \u0645\u0646\u062a\u0638\u0631 \u067e\u0627\u06cc\u0627\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u0648\u0644 \u0628\u0645\u0648\u0646\u0647 \u0648 \u0628\u0639\u062f \u062f\u0648\u0628\u0627\u0631\u0647 \u0647\u0645\u0648\u0646 Sync \u0631\u0648 \u0627\u062c\u0631\u0627 \u06a9\u0646\u0647. \u0628\u0631\u0627\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u06a9\u0627\u0645\u0644 \u0627\u0632 \u0627\u062c\u0631\u0627\u06cc \u062a\u06a9\u0631\u0627\u0631\u06cc\u060c \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0632\u0645\u0627\u0646 \u0622\u062e\u0631\u06cc\u0646 Sync \u0631\u0648 \u0647\u0645 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645 \u06cc\u0627 \u06cc\u06a9 Deferred \u0645\u0634\u062a\u0631\u06a9 \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class UserRepository(\n    private val api: UserApi,\n    private val userDao: UserDao,\n    private val externalScope:\n        CoroutineScope\n) {\n\n    private val requestMutex = Mutex()\n\n    private var activeRequest:\n        Deferred&lt;User>? = null\n\n    suspend fun getFreshUser(): User {\n        val request =\n            requestMutex.withLock {\n                activeRequest\n                    ?.takeIf {\n                        it.isActive\n                    }\n                    ?: externalScope\n                        .async {\n                            api\n                                .getCurrentUser()\n                                .toDomain()\n                        }\n                        .also {\n                            activeRequest = it\n                        }\n            }\n\n        return try {\n            request.await().also {\n                userDao.insert(\n                    it.toEntity()\n                )\n            }\n        } finally {\n            requestMutex.withLock {\n                if (\n                    activeRequest === request &amp;&amp;\n                    request.isCompleted\n                ) {\n                    activeRequest = null\n                }\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">UserRepository<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> api: <\/span><span style=\"color: #6F42C1\">UserApi<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> userDao: <\/span><span style=\"color: #6F42C1\">UserDao<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> externalScope:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        CoroutineScope<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> requestMutex <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Mutex<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> activeRequest:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Deferred<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">User<\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getFreshUser<\/span><span style=\"color: #24292E\">(): <\/span><span style=\"color: #6F42C1\">User<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> request <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            requestMutex.<\/span><span style=\"color: #6F42C1\">withLock<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                activeRequest<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ?.<\/span><span style=\"color: #6F42C1\">takeIf<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        it.isActive<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ?: externalScope<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">async<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            api<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                .<\/span><span style=\"color: #6F42C1\">getCurrentUser<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                .<\/span><span style=\"color: #6F42C1\">toDomain<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">also<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            activeRequest <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> it<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            request.<\/span><span style=\"color: #6F42C1\">await<\/span><span style=\"color: #24292E\">().<\/span><span style=\"color: #6F42C1\">also<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                userDao.<\/span><span style=\"color: #6F42C1\">insert<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">toEntity<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        } <\/span><span style=\"color: #D73A49\">finally<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            requestMutex.<\/span><span style=\"color: #6F42C1\">withLock<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    activeRequest <\/span><span style=\"color: #D73A49\">===<\/span><span style=\"color: #24292E\"> request <\/span><span style=\"color: #D73A49\">&amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    request.isCompleted<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    activeRequest <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0645\u062f\u0644 \u0627\u06af\u0631 \u0633\u0647 \u0628\u062e\u0634 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 <code>getFreshUser()<\/code> \u0631\u0648 \u0627\u062c\u0631\u0627 \u06a9\u0646\u0646\u060c \u0647\u0631 \u0633\u0647 \u0645\u0646\u062a\u0638\u0631 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u0634\u062a\u0631\u06a9 \u0645\u06cc\u200c\u0645\u0648\u0646\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Retry \u0627\u0634\u062a\u0628\u0627\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0633\u0631\u0648\u0631 \u0646\u06cc\u0645\u0647\u200c\u062e\u0631\u0627\u0628 \u0631\u0648 \u06a9\u0627\u0645\u0644\u0627\u064b \u0627\u0632 \u06a9\u0627\u0631 \u0628\u0646\u062f\u0627\u0632\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0634\u06a9\u0633\u062a \u0645\u06cc\u200c\u062e\u0648\u0631\u0647\u060c \u0627\u0648\u0644\u06cc\u0646 \u0648\u0627\u06a9\u0646\u0634 \u062e\u06cc\u0644\u06cc \u0627\u0632 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0686\u0646\u062f \u0628\u0627\u0631 \u0633\u0631\u06cc\u0639 \u062f\u0648\u0628\u0627\u0631\u0647 \u062a\u0644\u0627\u0634 \u06a9\u0646\u0646:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>repeat(3) {\n    runCatching {\n        api.getPrices()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">repeat<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">3<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">runCatching<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        api.<\/span><span style=\"color: #6F42C1\">getPrices<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0633\u0631\u0648\u0631 \u0632\u06cc\u0631 \u0641\u0634\u0627\u0631 \u0642\u0631\u0627\u0631 \u06af\u0631\u0641\u062a\u0647 \u0648 \u0646\u06cc\u0645\u06cc \u0627\u0632 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u0634\u06a9\u0633\u062a \u0645\u06cc\u200c\u062e\u0648\u0631\u0646. \u0627\u06af\u0631 \u0647\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0633\u0647 \u0628\u0627\u0631 \u0641\u0648\u0631\u06cc Retry \u06a9\u0646\u0647\u060c \u062a\u0639\u062f\u0627\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u0686\u0646\u062f \u0628\u0631\u0627\u0628\u0631 \u0645\u06cc\u0634\u0647 \u0648 \u0633\u0631\u0648\u0631\u06cc \u06a9\u0647 \u0641\u0642\u0637 \u06a9\u0646\u062f \u0634\u062f\u0647 \u0628\u0648\u062f \u0645\u0645\u06a9\u0646\u0647 \u06a9\u0627\u0645\u0644\u0627\u064b \u0627\u0632 \u062f\u0633\u062a\u0631\u0633 \u062e\u0627\u0631\u062c \u0628\u0634\u0647. Retry \u0628\u0627\u06cc\u062f \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u062e\u0637\u0627\u0647\u0627\u06cc \u0645\u0648\u0642\u062a\u06cc \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647 \u0648 \u0628\u06cc\u0646 \u062a\u0644\u0627\u0634\u200c\u0647\u0627 \u0641\u0627\u0635\u0644\u0647 \u0627\u0641\u0632\u0627\u06cc\u0634\u06cc \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9 \u062a\u0627\u0628\u0639 Exponential Backoff \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0627\u06cc\u0646\u200c\u0637\u0648\u0631 \u0646\u0648\u0634\u062a\u0647 \u0628\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun &lt;T> retryWithBackoff(\n    maxAttempts: Int = 4,\n    initialDelayMillis: Long = 1_000,\n    maxDelayMillis: Long = 10_000,\n    block: suspend () -> T\n): T {\n    var currentDelay =\n        initialDelayMillis\n\n    repeat(maxAttempts - 1) {\n        try {\n            return block()\n        } catch (\n            exception:\n            IOException\n        ) {\n            delay(currentDelay)\n\n            currentDelay =\n                (currentDelay * 2)\n                    .coerceAtMost(\n                        maxDelayMillis\n                    )\n        }\n    }\n\n    return block()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> &lt;<\/span><span style=\"color: #6F42C1\">T<\/span><span style=\"color: #24292E\">&gt; <\/span><span style=\"color: #6F42C1\">retryWithBackoff<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    maxAttempts: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">4<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    initialDelayMillis: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1_000<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    maxDelayMillis: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">10_000<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    block: <\/span><span style=\"color: #6F42C1\">suspend<\/span><span style=\"color: #24292E\"> () <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> T<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">): <\/span><span style=\"color: #6F42C1\">T<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> currentDelay <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        initialDelayMillis<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">repeat<\/span><span style=\"color: #24292E\">(maxAttempts <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">block<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        } <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            exception:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">delay<\/span><span style=\"color: #24292E\">(currentDelay)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            currentDelay <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                (currentDelay <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">2<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">coerceAtMost<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        maxDelayMillis<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">block<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0633\u062a\u0641\u0627\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val products =\n    retryWithBackoff {\n        productApi\n            .getTrackedProducts(\n                page = 1,\n                pageSize = 30\n            )\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">retryWithBackoff<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productApi<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">getTrackedProducts<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                page <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                pageSize <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">30<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0627\u0635\u0644\u0647 \u062a\u0644\u0627\u0634\u200c\u0647\u0627 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0628\u0647 \u0627\u06cc\u0646 \u0634\u06a9\u0644 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0644\u0627\u0634 \u0627\u0648\u0644: \u0628\u0644\u0627\u0641\u0627\u0635\u0644\u0647\n\u062a\u0644\u0627\u0634 \u062f\u0648\u0645: \u0628\u0639\u062f \u0627\u0632 \u06f1 \u062b\u0627\u0646\u06cc\u0647\n\u062a\u0644\u0627\u0634 \u0633\u0648\u0645: \u0628\u0639\u062f \u0627\u0632 \u06f2 \u062b\u0627\u0646\u06cc\u0647\n\u062a\u0644\u0627\u0634 \u0686\u0647\u0627\u0631\u0645: \u0628\u0639\u062f \u0627\u0632 \u06f4 \u062b\u0627\u0646\u06cc\u0647\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0633\u06cc\u0633\u062a\u0645\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af \u0628\u0647\u062a\u0631\u0647 \u06a9\u0645\u06cc \u0645\u0642\u062f\u0627\u0631 \u062a\u0635\u0627\u062f\u0641\u06cc \u06cc\u0627 Jitter \u0647\u0645 \u0628\u0647 \u062a\u0623\u062e\u06cc\u0631 \u0627\u0636\u0627\u0641\u0647 \u0628\u0634\u0647. \u062f\u0644\u06cc\u0644\u0634 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0627\u06af\u0631 \u062f\u0647 \u0647\u0632\u0627\u0631 \u06af\u0648\u0634\u06cc \u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0646\u0627\u0645\u0648\u0641\u0642 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u0646 \u0648 \u0647\u0645\u06af\u06cc \u062f\u0642\u06cc\u0642\u0627\u064b \u06cc\u06a9 \u062b\u0627\u0646\u06cc\u0647 \u0628\u0639\u062f Retry \u06a9\u0646\u0646\u060c \u06cc\u06a9 \u0645\u0648\u062c \u062a\u0627\u0632\u0647 \u0627\u0632 \u062f\u0647 \u0647\u0632\u0627\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u0634\u0647. \u0628\u0627 Jitter\u060c \u0632\u0645\u0627\u0646 Retry \u062f\u0633\u062a\u06af\u0627\u0647\u200c\u0647\u0627 \u067e\u062e\u0634 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun &lt;T> retryWithJitter(\n    maxAttempts: Int = 4,\n    initialDelayMillis: Long = 1_000,\n    block: suspend () -> T\n): T {\n    var currentDelay =\n        initialDelayMillis\n\n    repeat(maxAttempts - 1) {\n        try {\n            return block()\n        } catch (\n            exception:\n            IOException\n        ) {\n            val jitter =\n                Random.nextLong(\n                    0,\n                    currentDelay \/ 2 + 1\n                )\n\n            delay(\n                currentDelay + jitter\n            )\n\n            currentDelay =\n                (currentDelay * 2)\n                    .coerceAtMost(30_000)\n        }\n    }\n\n    return block()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> &lt;<\/span><span style=\"color: #6F42C1\">T<\/span><span style=\"color: #24292E\">&gt; <\/span><span style=\"color: #6F42C1\">retryWithJitter<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    maxAttempts: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">4<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    initialDelayMillis: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1_000<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    block: <\/span><span style=\"color: #6F42C1\">suspend<\/span><span style=\"color: #24292E\"> () <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> T<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">): <\/span><span style=\"color: #6F42C1\">T<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> currentDelay <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        initialDelayMillis<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">repeat<\/span><span style=\"color: #24292E\">(maxAttempts <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">block<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        } <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            exception:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> jitter <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Random.<\/span><span style=\"color: #6F42C1\">nextLong<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #005CC5\">0<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    currentDelay <\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">2<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">+<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">delay<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                currentDelay <\/span><span style=\"color: #D73A49\">+<\/span><span style=\"color: #24292E\"> jitter<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            currentDelay <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                (currentDelay <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">2<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">coerceAtMost<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">30_000<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">block<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u062e\u0637\u0627\u0647\u0627 \u0647\u0645 \u0646\u0628\u0627\u06cc\u062f Retry \u0628\u0634\u0646. \u062e\u0637\u0627\u06cc <code>401<\/code> \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0628\u0647 Token \u0645\u0631\u0628\u0648\u0637\u0647\u060c <code>403<\/code> \u06cc\u0639\u0646\u06cc \u062f\u0633\u062a\u0631\u0633\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u0647\u060c <code>404<\/code> \u0645\u0645\u06a9\u0646\u0647 \u0645\u0646\u0628\u0639 \u062d\u0630\u0641 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647 \u0648 \u0628\u0633\u06cc\u0627\u0631\u06cc \u0627\u0632 \u062e\u0637\u0627\u0647\u0627\u06cc <code>400<\/code> \u0628\u0627 \u062a\u0644\u0627\u0634 \u062f\u0648\u0628\u0627\u0631\u0647 \u062d\u0644 \u0646\u0645\u06cc\u0634\u0646. Retry \u0628\u06cc\u0634\u062a\u0631 \u0628\u0631\u0627\u06cc \u062e\u0637\u0627\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647\u060c Timeout \u0648 \u0628\u0639\u0636\u06cc \u067e\u0627\u0633\u062e\u200c\u0647\u0627\u06cc \u0645\u0648\u0642\u062a <code>5xx<\/code> \u0645\u0646\u0627\u0633\u0628\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">WorkManager \u0631\u0648 \u0628\u0631\u0627\u06cc \u0647\u0645\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u062f\u0631 \u06cc\u06a9 \u0632\u0645\u0627\u0646 \u0627\u062c\u0631\u0627 \u0646\u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0647\u0631 \u0631\u0648\u0632 \u0633\u0627\u0639\u062a \u06f8 \u0635\u0628\u062d \u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0648 Sync \u06a9\u0646\u0647. \u0627\u06af\u0631 \u0635\u062f \u0647\u0632\u0627\u0631 \u062f\u0633\u062a\u06af\u0627\u0647 \u062f\u0642\u06cc\u0642\u0627\u064b \u0633\u0627\u0639\u062a \u06f8 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0641\u0631\u0633\u062a\u0646\u060c \u06cc\u06a9 Traffic Spike \u0634\u062f\u06cc\u062f \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u0634\u0647. \u062d\u062a\u06cc \u0627\u06af\u0631 \u0645\u06cc\u0627\u0646\u06af\u06cc\u0646 \u0638\u0631\u0641\u06cc\u062a \u0633\u0631\u0648\u0631 \u06a9\u0627\u0641\u06cc \u0628\u0627\u0634\u0647\u060c \u0647\u0645\u06cc\u0646 \u0647\u062c\u0648\u0645 \u06a9\u0648\u062a\u0627\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0633\u06cc\u0633\u062a\u0645 \u0631\u0648 \u0627\u0632 \u06a9\u0627\u0631 \u0628\u0646\u062f\u0627\u0632\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647\u200c\u062c\u0627\u06cc \u0632\u0645\u0627\u0646\u200c\u0628\u0646\u062f\u06cc \u06a9\u0627\u0645\u0644\u0627\u064b \u06cc\u06a9\u0633\u0627\u0646\u060c \u0628\u0647\u062a\u0631\u0647 \u0627\u062c\u0631\u0627\u06cc \u06a9\u0627\u0631 \u062f\u0631 \u0628\u0627\u0632\u0647 \u0632\u0645\u0627\u0646\u06cc \u067e\u062e\u0634 \u0628\u0634\u0647. WorkManager \u0630\u0627\u062a\u0627\u064b \u0627\u062c\u0631\u0627\u06cc \u062f\u0642\u06cc\u0642 \u062b\u0627\u0646\u06cc\u0647\u200c\u0627\u06cc \u0631\u0648 \u062a\u0636\u0645\u06cc\u0646 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0627\u0645\u0627 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u0631\u0627\u06cc \u0627\u0648\u0644\u06cc\u0646 \u0627\u062c\u0631\u0627\u06cc One-Time Work \u062a\u0623\u062e\u06cc\u0631 \u062a\u0635\u0627\u062f\u0641\u06cc \u062a\u0639\u06cc\u06cc\u0646 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun schedulePriceSync(\n    context: Context\n) {\n    val randomDelayMinutes =\n        Random.nextLong(\n            from = 0,\n            until = 60\n        )\n\n    val constraints =\n        Constraints.Builder()\n            .setRequiredNetworkType(\n                NetworkType.CONNECTED\n            )\n            .build()\n\n    val request =\n        OneTimeWorkRequestBuilder&lt;\n            PriceSyncWorker\n        >()\n            .setConstraints(constraints)\n            .setInitialDelay(\n                randomDelayMinutes,\n                TimeUnit.MINUTES\n            )\n            .build()\n\n    WorkManager\n        .getInstance(context)\n        .enqueueUniqueWork(\n            \"price_sync\",\n            ExistingWorkPolicy.KEEP,\n            request\n        )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">schedulePriceSync<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    context: <\/span><span style=\"color: #6F42C1\">Context<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> randomDelayMinutes <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Random.<\/span><span style=\"color: #6F42C1\">nextLong<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            from <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">0<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            until <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">60<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> constraints <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Constraints.<\/span><span style=\"color: #6F42C1\">Builder<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setRequiredNetworkType<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NetworkType.CONNECTED<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> request <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        OneTimeWorkRequestBuilder<\/span><span style=\"color: #D73A49\">&lt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PriceSyncWorker<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setConstraints<\/span><span style=\"color: #24292E\">(constraints)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setInitialDelay<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                randomDelayMinutes,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                TimeUnit.MINUTES<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    WorkManager<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">getInstance<\/span><span style=\"color: #24292E\">(context)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">enqueueUniqueWork<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;price_sync&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ExistingWorkPolicy.KEEP,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            request<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><code>enqueueUniqueWork<\/code> \u0647\u0645 \u0645\u0627\u0646\u0639 \u0645\u06cc\u0634\u0647 \u0686\u0646\u062f \u0628\u062e\u0634 \u0628\u0631\u0646\u0627\u0645\u0647 \u0686\u0646\u062f Work \u06cc\u06a9\u0633\u0627\u0646 \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0646. \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631 \u062f\u0648\u0631\u0647\u200c\u0627\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val request =\n    PeriodicWorkRequestBuilder&lt;\n        PriceSyncWorker\n    >(\n        6,\n        TimeUnit.HOURS\n    )\n        .setConstraints(\n            Constraints.Builder()\n                .setRequiredNetworkType(\n                    NetworkType.CONNECTED\n                )\n                .build()\n        )\n        .setBackoffCriteria(\n            BackoffPolicy.EXPONENTIAL,\n            30,\n            TimeUnit.SECONDS\n        )\n        .build()\n\nWorkManager\n    .getInstance(context)\n    .enqueueUniquePeriodicWork(\n        \"periodic_price_sync\",\n        ExistingPeriodicWorkPolicy.KEEP,\n        request\n    )\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> request <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    PeriodicWorkRequestBuilder<\/span><span style=\"color: #D73A49\">&lt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        PriceSyncWorker<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">6<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TimeUnit.HOURS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">setConstraints<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Constraints.<\/span><span style=\"color: #6F42C1\">Builder<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setRequiredNetworkType<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    NetworkType.CONNECTED<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">setBackoffCriteria<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            BackoffPolicy.EXPONENTIAL,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #005CC5\">30<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TimeUnit.SECONDS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">WorkManager<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    .<\/span><span style=\"color: #6F42C1\">getInstance<\/span><span style=\"color: #24292E\">(context)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    .<\/span><span style=\"color: #6F42C1\">enqueueUniquePeriodicWork<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;periodic_price_sync&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ExistingPeriodicWorkPolicy.KEEP,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        request<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u06a9\u0627\u0631 Background \u0646\u0628\u0627\u06cc\u062f \u0628\u062f\u0648\u0646 \u0646\u06cc\u0627\u0632 \u0647\u0645\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u0647. \u0627\u06af\u0631 \u0633\u0631\u0648\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0641\u0642\u0637 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0628\u0639\u062f \u0627\u0632 \u0622\u062e\u0631\u06cc\u0646 Sync \u0631\u0648 \u0628\u0631\u06af\u0631\u062f\u0648\u0646\u0647\u060c \u0628\u0627\u06cc\u062f \u0632\u0645\u0627\u0646 \u06cc\u0627 Cursor \u0622\u062e\u0631\u06cc\u0646 \u0647\u0645\u06af\u0627\u0645\u200c\u0633\u0627\u0632\u06cc \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>GET \/price-changes?since=2026-07-19T08:30:00Z\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">GET <\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #24292E\">price<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">changes?since<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #005CC5\">2026<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">07<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">19T08:<\/span><span style=\"color: #6F42C1\">30<\/span><span style=\"color: #24292E\">:<\/span><span style=\"color: #6F42C1\">00Z<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0627\u06cc\u0646 \u0645\u062f\u0644 Delta Sync \u06af\u0641\u062a\u0647 \u0645\u06cc\u0634\u0647. \u0628\u0647\u200c\u062c\u0627\u06cc \u062f\u0631\u06cc\u0627\u0641\u062a \u062f\u0648\u0628\u0627\u0631\u0647 \u0647\u0632\u0627\u0631\u0627\u0646 \u0631\u06a9\u0648\u0631\u062f\u060c \u0641\u0642\u0637 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u062a\u063a\u06cc\u06cc\u0631\u06a9\u0631\u062f\u0647 \u0645\u0646\u062a\u0642\u0644 \u0645\u06cc\u0634\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Polling \u062f\u0627\u0626\u0645\u06cc \u06cc\u0627 Push\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0647\u0631 \u0633\u06cc \u062b\u0627\u0646\u06cc\u0647 \u0627\u0632 \u0633\u0631\u0648\u0631 \u0628\u067e\u0631\u0633\u0647 \u00ab\u0642\u06cc\u0645\u062a \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f\u0647\u061f\u00bb\u060c \u062d\u062a\u06cc \u0648\u0642\u062a\u06cc \u0647\u06cc\u0686 \u062a\u063a\u06cc\u06cc\u0631\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>while (isActive) {\n    repository.refreshPrices()\n    delay(30_000)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">while<\/span><span style=\"color: #24292E\"> (isActive) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    repository.<\/span><span style=\"color: #6F42C1\">refreshPrices<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">delay<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">30_000<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u062f\u0647 \u0647\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0622\u0646\u0644\u0627\u06cc\u0646 \u0628\u0627\u0634\u0646\u060c \u0627\u06cc\u0646 \u0637\u0631\u0627\u062d\u06cc \u062d\u062f\u0648\u062f \u06f3\u06f3\u06f3 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0631 \u0647\u0631 \u062b\u0627\u0646\u06cc\u0647 \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u067e\u0631\u0633\u06cc\u062f\u0646 \u06cc\u06a9 \u0633\u0624\u0627\u0644 \u062a\u06a9\u0631\u0627\u0631\u06cc \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>10,000 \u00f7 30 \u2248 333 requests per second\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0628\u0633\u06cc\u0627\u0631\u06cc \u0627\u0632 \u0633\u0646\u0627\u0631\u06cc\u0648\u0647\u0627 \u0628\u0647\u062a\u0631\u0647 Backend \u0647\u0646\u06af\u0627\u0645 \u0648\u0642\u0648\u0639 \u062a\u063a\u06cc\u06cc\u0631\u060c \u0627\u0632 FCM \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0627\u0639\u0644\u0627\u0646 \u0628\u0641\u0631\u0633\u062a\u0647. \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0639\u062f \u0627\u0632 \u062f\u0631\u06cc\u0627\u0641\u062a \u0627\u0639\u0644\u0627\u0646 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0641\u0642\u0637 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0631\u062a\u0628\u0637 \u0631\u0648 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u06a9\u0646\u0647. \u0628\u0631\u0627\u06cc \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0628\u0627\u06cc\u062f \u0644\u062d\u0638\u0647\u200c\u0627\u06cc \u062f\u0627\u062e\u0644 \u0635\u0641\u062d\u0647 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0628\u0634\u0646\u060c WebSocket \u06cc\u0627 Socket.IO \u0645\u0645\u06a9\u0646\u0647 \u0645\u0646\u0627\u0633\u0628 \u0628\u0627\u0634\u0647\u060c \u0627\u0645\u0627 \u0627\u062a\u0635\u0627\u0644 \u062f\u0627\u0626\u0645\u06cc \u0647\u0645 \u0631\u0627\u06cc\u06af\u0627\u0646 \u0646\u06cc\u0633\u062a. \u0647\u0631 \u0627\u062a\u0635\u0627\u0644 \u062d\u0627\u0641\u0638\u0647\u060c File Descriptor \u0648 \u0638\u0631\u0641\u06cc\u062a \u0634\u0628\u06a9\u0647 \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0646\u0628\u0627\u06cc\u062f \u0641\u0642\u0637 \u0628\u0647\u200c\u062e\u0627\u0637\u0631 \u062c\u0630\u0627\u0628 \u0628\u0648\u062f\u0646 \u0641\u0646\u0627\u0648\u0631\u06cc\u060c \u0628\u0631\u0627\u06cc \u0635\u0641\u062d\u0647\u200c\u0627\u06cc \u06a9\u0647 \u0647\u0631 \u0686\u0646\u062f \u062f\u0642\u06cc\u0642\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647 WebSocket \u0628\u0633\u0627\u0632\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc \u0645\u0646\u0637\u0642\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0627\u06cc\u0646 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u063a\u06cc\u06cc\u0631 \u0642\u06cc\u0645\u062a \u0645\u0647\u0645 \u0648 \u062e\u0627\u0631\u062c \u0627\u0632 \u0628\u0631\u0646\u0627\u0645\u0647:\nFCM Notification\n\n\u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0645\u0639\u0645\u0648\u0644\u06cc \u0641\u0647\u0631\u0633\u062a:\nAPI + Cache + Delta Sync\n\n\u0646\u0645\u0627\u06cc\u0634 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0628\u0633\u06cc\u0627\u0631 \u0633\u0631\u06cc\u0639 \u062f\u0631 \u0635\u0641\u062d\u0647 \u0628\u0627\u0632:\nWebSocket\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Rate Limiting\u061b \u0647\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0646\u0628\u0627\u06cc\u062f \u0638\u0631\u0641\u06cc\u062a \u0646\u0627\u0645\u062d\u062f\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u062a\u06cc \u0627\u06af\u0631 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u062f\u0631\u0633\u062a \u0637\u0631\u0627\u062d\u06cc \u0634\u062f\u0647 \u0628\u0627\u0634\u0647\u060c \u0646\u0628\u0627\u06cc\u062f Backend \u0628\u0647 \u0647\u0631 Client \u0627\u0639\u062a\u0645\u0627\u062f \u06a9\u0627\u0645\u0644 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u06a9\u0627\u0631\u0628\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0646\u0633\u062e\u0647 \u062f\u0633\u062a\u06a9\u0627\u0631\u06cc\u200c\u0634\u062f\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0633\u0627\u0632\u0647\u060c Script \u0628\u0646\u0648\u06cc\u0633\u0647 \u06cc\u0627 \u06cc\u06a9 Endpoint \u0631\u0648 \u0647\u0632\u0627\u0631\u0627\u0646 \u0628\u0627\u0631 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u06a9\u0646\u0647. \u0633\u0631\u0648\u0631 \u0628\u0627\u06cc\u062f \u0628\u0631\u0627\u06cc Endpoint\u0647\u0627\u06cc \u062d\u0633\u0627\u0633 Rate Limit \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062c\u0633\u062a\u200c\u0648\u062c\u0648:\n\u062d\u062f\u0627\u06a9\u062b\u0631 \u06f3\u06f0 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0631 \u062f\u0642\u06cc\u0642\u0647 \u0628\u0631\u0627\u06cc \u0647\u0631 \u06a9\u0627\u0631\u0628\u0631\n\n\u0648\u0631\u0648\u062f:\n\u062d\u062f\u0627\u06a9\u062b\u0631 \u06f5 \u062a\u0644\u0627\u0634 \u062f\u0631 \u06f1\u06f0 \u062f\u0642\u06cc\u0642\u0647\n\n\u0627\u0631\u0633\u0627\u0644 \u06a9\u062f \u062a\u0623\u06cc\u06cc\u062f:\n\u062d\u062f\u0627\u06a9\u062b\u0631 \u06f3 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0631 \u0633\u0627\u0639\u062a\n\n\u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u062f\u0633\u062a\u06cc \u0642\u06cc\u0645\u062a:\n\u062d\u062f\u0627\u06a9\u062b\u0631 \u06f1\u06f0 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0631 \u062f\u0642\u06cc\u0642\u0647\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0631\u062f \u0628\u0634\u0647\u060c \u0633\u0631\u0648\u0631 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u067e\u0627\u0633\u062e <code>429 Too Many Requests<\/code> \u0645\u06cc\u062f\u0647 \u0648 \u0645\u0645\u06a9\u0646\u0647 \u0647\u062f\u0631 <code>Retry-After<\/code> \u0631\u0648 \u0647\u0645 \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>HTTP\/1.1 429 Too Many Requests\nRetry-After: 60\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">HTTP<\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #005CC5\">1.1<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">429<\/span><span style=\"color: #24292E\"> Too Many Requests<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Retry<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">After: <\/span><span style=\"color: #6F42C1\">60<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0646\u0628\u0627\u06cc\u062f \u062f\u0631 \u067e\u0627\u0633\u062e \u0628\u0647 <code>429<\/code> \u0641\u0648\u0631\u0627\u064b Retry \u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class RateLimitInterceptor :\n    Interceptor {\n\n    override fun intercept(\n        chain: Interceptor.Chain\n    ): Response {\n        val response =\n            chain.proceed(\n                chain.request()\n            )\n\n        if (response.code == 429) {\n            val retryAfter =\n                response.header(\n                    \"Retry-After\"\n                )\n\n            Log.w(\n                \"RateLimit\",\n                \"Retry after: $retryAfter\"\n            )\n        }\n\n        return response\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">RateLimitInterceptor<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">Interceptor<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">intercept<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        chain: <\/span><span style=\"color: #6F42C1\">Interceptor<\/span><span style=\"color: #24292E\">.Chain<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">Response<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> response <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            chain.<\/span><span style=\"color: #6F42C1\">proceed<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                chain.<\/span><span style=\"color: #6F42C1\">request<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (response.code <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">429<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> retryAfter <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                response.<\/span><span style=\"color: #6F42C1\">header<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;Retry-After&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Log.<\/span><span style=\"color: #6F42C1\">w<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;RateLimit&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;Retry after: <\/span><span style=\"color: #005CC5\">$retryAfter<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> response<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0633\u0637\u062d Repository \u0628\u0647\u062a\u0631\u0647 \u0648\u0636\u0639\u06cc\u062a \u0642\u0627\u0628\u0644\u200c\u0641\u0647\u0645\u06cc \u0628\u0647 UI \u0628\u0631\u06af\u0631\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>sealed interface RefreshResult {\n\n    data class Success(\n        val products: List&lt;Product>\n    ) : RefreshResult\n\n    data class RateLimited(\n        val retryAfterSeconds: Long?\n    ) : RefreshResult\n\n    data class Failure(\n        val message: String\n    ) : RefreshResult\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">sealed<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">RefreshResult<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Success<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">RefreshResult<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">RateLimited<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> retryAfterSeconds: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">?<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">RefreshResult<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Failure<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> message: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">RefreshResult<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun refreshProducts():\n    RefreshResult {\n\n    val response =\n        api.getProductsResponse()\n\n    return when {\n        response.isSuccessful -> {\n            RefreshResult.Success(\n                response.body()\n                    .orEmpty()\n                    .map {\n                        it.toDomain()\n                    }\n            )\n        }\n\n        response.code() == 429 -> {\n            RefreshResult.RateLimited(\n                retryAfterSeconds =\n                    response.headers()\n                        &#91;\"Retry-After\"&#93;\n                        ?.toLongOrNull()\n            )\n        }\n\n        else -> {\n            RefreshResult.Failure(\n                \"\u062f\u0631\u06cc\u0627\u0641\u062a \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0627\u0646\u062c\u0627\u0645 \u0646\u0634\u062f.\"\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">refreshProducts<\/span><span style=\"color: #24292E\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">RefreshResult<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> response <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        api.<\/span><span style=\"color: #6F42C1\">getProductsResponse<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        response.isSuccessful <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            RefreshResult.<\/span><span style=\"color: #6F42C1\">Success<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                response.<\/span><span style=\"color: #6F42C1\">body<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">orEmpty<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        it.<\/span><span style=\"color: #6F42C1\">toDomain<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        response.<\/span><span style=\"color: #6F42C1\">code<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">429<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            RefreshResult.<\/span><span style=\"color: #6F42C1\">RateLimited<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                retryAfterSeconds <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    response.<\/span><span style=\"color: #6F42C1\">headers<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        &#91;<\/span><span style=\"color: #032F62\">&quot;Retry-After&quot;<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        ?.<\/span><span style=\"color: #6F42C1\">toLongOrNull<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            RefreshResult.<\/span><span style=\"color: #6F42C1\">Failure<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;\u062f\u0631\u06cc\u0627\u0641\u062a \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0627\u0646\u062c\u0627\u0645 \u0646\u0634\u062f.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">\u0633\u0645\u062a \u0633\u0631\u0648\u0631 \u06a9\u062c\u0627 \u06af\u0644\u0648\u06af\u0627\u0647 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u0634\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0641\u0642\u0637 \u0628\u062e\u0634\u06cc \u0627\u0632 \u0645\u0627\u062c\u0631\u0627\u0633\u062a. \u0627\u06af\u0631 Backend \u0628\u0631\u0627\u06cc \u0647\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06cc\u06a9 Query \u0633\u0646\u06af\u06cc\u0646 \u0627\u062c\u0631\u0627 \u06a9\u0646\u0647\u060c Cache \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647 \u06cc\u0627 \u062a\u0639\u062f\u0627\u062f \u0627\u062a\u0635\u0627\u0644\u200c\u0647\u0627\u06cc \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0646\u0634\u062f\u0647 \u0628\u0627\u0634\u0647\u060c \u06a9\u0627\u0647\u0634 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc Client \u0647\u0645 \u0628\u0647\u200c\u062a\u0646\u0647\u0627\u06cc\u06cc \u06a9\u0627\u0641\u06cc \u0646\u06cc\u0633\u062a. \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u06af\u0644\u0648\u06af\u0627\u0647 \u062f\u0631 \u06cc\u06a9\u06cc \u0627\u0632 \u0627\u06cc\u0646 \u0628\u062e\u0634\u200c\u0647\u0627 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>CPU:<\/strong> \u062a\u0628\u062f\u06cc\u0644 \u062f\u0627\u062f\u0647\u060c \u0631\u0645\u0632\u0646\u06af\u0627\u0631\u06cc \u0633\u0646\u06af\u06cc\u0646\u060c \u067e\u0631\u062f\u0627\u0632\u0634 \u062a\u0635\u0648\u06cc\u0631 \u06cc\u0627 \u0627\u0644\u06af\u0648\u0631\u06cc\u062a\u0645\u200c\u0647\u0627\u06cc \u067e\u0631\u0647\u0632\u06cc\u0646\u0647 CPU \u0631\u0648 \u0627\u0634\u063a\u0627\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0646.<br><strong>RAM:<\/strong> \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u067e\u0627\u0633\u062e\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af\u060c Session\u0647\u0627\u06cc \u0632\u06cc\u0627\u062f \u06cc\u0627 Memory Leak \u0628\u0627\u0639\u062b \u067e\u0631 \u0634\u062f\u0646 \u062d\u0627\u0641\u0638\u0647 \u0645\u06cc\u0634\u0647.<br><strong>Database:<\/strong> Query \u0628\u062f\u0648\u0646 Index\u060c Join \u0633\u0646\u06af\u06cc\u0646\u060c Lock \u0637\u0648\u0644\u0627\u0646\u06cc \u0648 \u0627\u062a\u0635\u0627\u0644\u200c\u0647\u0627\u06cc \u0632\u06cc\u0627\u062f \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0635\u0644\u06cc\u200c\u062a\u0631\u06cc\u0646 \u0639\u0648\u0627\u0645\u0644 \u06a9\u0646\u062f\u06cc \u0647\u0633\u062a\u0646.<br><strong>Network:<\/strong> \u067e\u0627\u0633\u062e\u200c\u0647\u0627\u06cc \u062d\u062c\u06cc\u0645\u060c \u062a\u0635\u0627\u0648\u06cc\u0631 \u0628\u062f\u0648\u0646 \u0641\u0634\u0631\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0648 \u0627\u0646\u062a\u0642\u0627\u0644 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u062a\u06a9\u0631\u0627\u0631\u06cc \u067e\u0647\u0646\u0627\u06cc \u0628\u0627\u0646\u062f \u0631\u0648 \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0646.<br><strong>\u0633\u0631\u0648\u06cc\u0633 \u062e\u0627\u0631\u062c\u06cc:<\/strong> \u0645\u0645\u06a9\u0646\u0647 \u062e\u0648\u062f API \u0633\u0631\u06cc\u0639 \u0628\u0627\u0634\u0647\u060c \u0627\u0645\u0627 \u0628\u0631\u0627\u06cc \u0647\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u0646\u062a\u0638\u0631 \u06cc\u06a9 \u0633\u0631\u0648\u06cc\u0633 \u067e\u0631\u062f\u0627\u062e\u062a\u060c \u067e\u06cc\u0627\u0645\u06a9 \u06cc\u0627 \u0642\u06cc\u0645\u062a\u200c\u06af\u06cc\u0631\u06cc \u062e\u0627\u0631\u062c\u06cc \u0628\u0645\u0648\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 Endpoint \u0635\u0641\u062d\u0647 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0628\u0631\u0627\u06cc \u0647\u0631 \u0645\u062d\u0635\u0648\u0644 \u06cc\u06a9 Query \u062c\u062f\u0627 \u0627\u062c\u0631\u0627 \u06a9\u0646\u0647. \u0627\u0628\u062a\u062f\u0627 \u0633\u06cc \u0645\u062d\u0635\u0648\u0644 \u06af\u0631\u0641\u062a\u0647 \u0645\u06cc\u0634\u0647 \u0648 \u0628\u0639\u062f \u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a \u0647\u0631 \u0645\u062d\u0635\u0648\u0644 \u06cc\u06a9 Query \u062c\u062f\u0627 \u0627\u062c\u0631\u0627 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1 Query \u0628\u0631\u0627\u06cc \u0645\u062d\u0635\u0648\u0644\u0627\u062a\n30 Query \u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0647\u0627\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0645\u0634\u06a9\u0644 \u0628\u0647 N+1 Query \u0645\u0639\u0631\u0648\u0641\u0647. \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u0627\u0631\u0628\u0631 \u0628\u0647 \u06f3\u06f1 Query \u062a\u0628\u062f\u06cc\u0644 \u0645\u06cc\u0634\u0647. \u0627\u06af\u0631 \u0647\u0632\u0627\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0631 \u062f\u0642\u06cc\u0642\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645\u060c \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0628\u0627 \u0633\u06cc\u200c\u0648\u06cc\u06a9 \u0647\u0632\u0627\u0631 Query \u0631\u0648\u0628\u0647\u200c\u0631\u0648 \u0645\u06cc\u0634\u0647. \u0631\u0627\u0647\u200c\u062d\u0644 \u0645\u0639\u0645\u0648\u0644 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Join\u060c Batch Query \u06cc\u0627 Precomputed Data \u0647\u0633\u062a.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cache \u0633\u0645\u062a \u0633\u0631\u0648\u0631 \u0648 Redis<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u0636\u06cc \u062f\u0627\u062f\u0647\u200c\u0647\u0627 \u0628\u0631\u0627\u06cc \u0647\u0632\u0627\u0631\u0627\u0646 \u06a9\u0627\u0631\u0628\u0631 \u06cc\u06a9\u0633\u0627\u0646 \u0647\u0633\u062a\u0646. \u0645\u062b\u0644\u0627\u064b \u0641\u0647\u0631\u0633\u062a \u062f\u0633\u062a\u0647\u200c\u0628\u0646\u062f\u06cc\u200c\u0647\u0627\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0639\u0645\u0648\u0645\u06cc \u0641\u0631\u0648\u0634\u06af\u0627\u0647\u200c\u0647\u0627 \u06cc\u0627 \u0642\u06cc\u0645\u062a \u06cc\u06a9 \u0645\u062d\u0635\u0648\u0644 \u0645\u062d\u0628\u0648\u0628 \u0645\u0645\u06a9\u0646\u0647 \u062f\u0631 \u0645\u062f\u062a \u06a9\u0648\u062a\u0627\u0647\u06cc \u0628\u0627\u0631\u0647\u0627 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0634\u0647. \u0627\u062c\u0631\u0627\u06cc Query \u06cc\u06a9\u0633\u0627\u0646 \u0628\u0631\u0627\u06cc \u0647\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0627\u062a\u0644\u0627\u0641 \u0645\u0646\u0627\u0628\u0639\u0647. Backend \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0646\u062a\u06cc\u062c\u0647 \u0631\u0648 \u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647 \u06cc\u0627 \u0686\u0646\u062f \u062f\u0642\u06cc\u0642\u0647 \u062f\u0627\u062e\u0644 Redis \u0646\u06af\u0647 \u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Request 1:\nDatabase \u2192 Redis \u2192 Response\n\nRequest 2 \u062a\u0627 1000:\nRedis \u2192 Response\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Request <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Database \u2192 Redis \u2192 Response<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Request <\/span><span style=\"color: #005CC5\">2<\/span><span style=\"color: #24292E\"> \u062a\u0627 <\/span><span style=\"color: #005CC5\">1000<\/span><span style=\"color: #24292E\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Redis \u2192 Response<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Cache \u0646\u0628\u0627\u06cc\u062f \u0628\u062f\u0648\u0646 \u0633\u06cc\u0627\u0633\u062a \u0628\u0627\u0634\u0647. \u0628\u0627\u06cc\u062f \u0645\u0634\u062e\u0635 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cache Key \u0686\u06cc\u0633\u062a\u061f\n\u062f\u0627\u062f\u0647 \u062a\u0627 \u0686\u0647 \u0645\u062f\u062a \u0645\u0639\u062a\u0628\u0631\u0647\u061f\n\u067e\u0633 \u0627\u0632 \u062a\u063a\u06cc\u06cc\u0631 \u0642\u06cc\u0645\u062a \u0686\u0637\u0648\u0631 Cache \u062d\u0630\u0641 \u0645\u06cc\u0634\u0647\u061f\n\u0627\u06af\u0631 Redis \u062f\u0631 \u062f\u0633\u062a\u0631\u0633 \u0646\u0628\u0648\u062f \u0686\u0647 \u0627\u062a\u0641\u0627\u0642\u06cc \u0645\u06cc\u200c\u0627\u0641\u062a\u0647\u061f\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644 \u06a9\u0644\u06cc\u062f \u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>product:101:latest-price\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0632\u0645\u0627\u0646 \u0627\u0639\u062a\u0628\u0627\u0631:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TTL = 60 seconds\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c Backend \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 Cache \u0645\u0631\u0628\u0648\u0637 \u0631\u0648 \u062d\u0630\u0641 \u06cc\u0627 \u0645\u0642\u062f\u0627\u0631 \u062a\u0627\u0632\u0647 \u0631\u0648 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u06a9\u0646\u0647. \u0627\u06cc\u0646 \u0645\u062f\u0644 \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u0647\u0632\u0627\u0631\u0627\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062e\u0648\u0627\u0646\u062f\u0646\u060c \u0628\u0647\u200c\u062c\u0627\u06cc \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0627\u0635\u0644\u06cc \u0627\u0632 \u062d\u0627\u0641\u0638\u0647 \u0633\u0631\u06cc\u0639 Redis \u067e\u0627\u0633\u062e \u062f\u0627\u062f\u0647 \u0628\u0634\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Load Balancer \u0648 \u0686\u0646\u062f \u0633\u0631\u0648\u0631<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u06cc\u06a9 Backend \u0628\u0647 \u0633\u0642\u0641 \u0638\u0631\u0641\u06cc\u062a \u062e\u0648\u062f\u0634 \u0631\u0633\u06cc\u062f\u0647 \u0628\u0627\u0634\u0647\u060c \u062f\u0648 \u0631\u0627\u0647 \u06a9\u0644\u06cc \u062f\u0627\u0631\u06cc\u0645. \u062f\u0631 <strong>Vertical Scaling<\/strong> \u0645\u0646\u0627\u0628\u0639 \u0647\u0645\u0648\u0646 \u0633\u0631\u0648\u0631 \u0631\u0648 \u0627\u0641\u0632\u0627\u06cc\u0634 \u0645\u06cc\u200c\u062f\u06cc\u0645\u061b \u0645\u062b\u0644\u0627\u064b CPU \u0631\u0648 \u0627\u0632 \u0686\u0647\u0627\u0631 \u0647\u0633\u062a\u0647 \u0628\u0647 \u0634\u0627\u0646\u0632\u062f\u0647 \u0647\u0633\u062a\u0647 \u0648 RAM \u0631\u0648 \u0627\u0632 \u0647\u0634\u062a \u06af\u06cc\u06af\u0627\u0628\u0627\u06cc\u062a \u0628\u0647 \u0633\u06cc\u200c\u0648\u062f\u0648 \u06af\u06cc\u06af\u0627\u0628\u0627\u06cc\u062a \u0645\u06cc\u200c\u0631\u0633\u0648\u0646\u06cc\u0645. \u0627\u06cc\u0646 \u0631\u0648\u0634 \u0633\u0627\u062f\u0647\u200c\u0633\u062a\u060c \u0627\u0645\u0627 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u062f\u0627\u0631\u0647 \u0648 \u06cc\u06a9 \u062e\u0631\u0627\u0628\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u06a9\u0644 \u0633\u0631\u0648\u06cc\u0633 \u0631\u0648 \u0627\u0632 \u062f\u0633\u062a\u0631\u0633 \u062e\u0627\u0631\u062c \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 <strong>Horizontal Scaling<\/strong> \u0686\u0646\u062f \u0646\u0645\u0648\u0646\u0647 \u0627\u0632 \u0628\u0631\u0646\u0627\u0645\u0647 \u0633\u0631\u0648\u0631 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Client Requests\n       \u2193\nLoad Balancer\n   \u2193    \u2193    \u2193\nServer 1\nServer 2\nServer 3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Load Balancer \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u0631\u0648 \u0628\u06cc\u0646 \u0633\u0631\u0648\u0631\u0647\u0627 \u062a\u0642\u0633\u06cc\u0645 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0628\u0631\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0627\u06cc\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc \u062f\u0631\u0633\u062a \u06a9\u0627\u0631 \u06a9\u0646\u0647\u060c Backend \u0628\u0647\u062a\u0631\u0647 Stateless \u0628\u0627\u0634\u0647\u061b \u06cc\u0639\u0646\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0636\u0631\u0648\u0631\u06cc Session \u0641\u0642\u0637 \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u06cc\u06a9 \u0633\u0631\u0648\u0631 \u062e\u0627\u0635 \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0646\u0634\u0647. \u0627\u06af\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0648\u0631\u0648\u062f \u0628\u0647 Server 1 \u0648 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0639\u062f\u06cc \u0628\u0647 Server 3 \u0628\u0631\u0647\u060c Server 3 \u0647\u0645 \u0628\u0627\u06cc\u062f \u0628\u062a\u0648\u0646\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0631\u0648 \u0634\u0646\u0627\u0633\u0627\u06cc\u06cc \u06a9\u0646\u0647. Token\u0647\u0627\u06cc \u0642\u0627\u0628\u0644\u200c\u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc\u060c Redis Session Store \u06cc\u0627 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0645\u0634\u062a\u0631\u06a9 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u0627\u06cc\u0646 \u0645\u0634\u06a9\u0644 \u0631\u0648 \u062d\u0644 \u06a9\u0646\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0641\u0632\u0648\u062f\u0646 \u0633\u0631\u0648\u0631 \u0628\u06cc\u0634\u062a\u0631 \u0647\u0645\u0647 \u0645\u0634\u06a9\u0644\u0627\u062a \u0631\u0648 \u062d\u0644 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06af\u0631 \u0647\u0631 \u0633\u0647 \u0633\u0631\u0648\u0631 \u0628\u0647 \u06cc\u06a9 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u06a9\u0646\u062f \u0645\u062a\u0635\u0644 \u0628\u0627\u0634\u0646\u060c \u0641\u0642\u0637 \u062a\u0639\u062f\u0627\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0631\u0633\u06cc\u062f\u0647 \u0628\u0647 \u06af\u0644\u0648\u06af\u0627\u0647 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0627\u0641\u0632\u0627\u06cc\u0634 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0645\u0642\u06cc\u0627\u0633\u200c\u067e\u0630\u06cc\u0631\u06cc \u0628\u0627\u06cc\u062f \u0627\u0646\u062a\u0647\u0627\u0628\u0647\u200c\u0627\u0646\u062a\u0647\u0627 \u0628\u0631\u0631\u0633\u06cc \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Queue \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0647\u0627\u06cc \u0633\u0646\u06af\u06cc\u0646 \u0648 \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u062f\u0631 \u067e\u0627\u0633\u062e \u0641\u0648\u0631\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u06a9\u0627\u0631\u0628\u0631 \u06cc\u06a9 \u0645\u062d\u0635\u0648\u0644 \u062c\u062f\u06cc\u062f \u0628\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0633\u0631\u0648\u0631 \u0628\u0627\u06cc\u062f \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0646\u0647\u060c \u0635\u0641\u062d\u0647 \u0641\u0631\u0648\u0634\u06af\u0627\u0647 \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u0647\u060c \u062a\u0635\u0648\u06cc\u0631 \u0631\u0648 \u067e\u0631\u062f\u0627\u0632\u0634 \u06a9\u0646\u0647\u060c \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0627\u0648\u0644\u06cc\u0647 \u0642\u06cc\u0645\u062a \u0631\u0648 \u0628\u0633\u0627\u0632\u0647 \u0648 \u0634\u0627\u06cc\u062f \u0627\u0639\u0644\u0627\u0646 \u0647\u0645 \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u0647. \u0627\u06af\u0631 \u0647\u0645\u0647 \u0627\u06cc\u0646 \u06a9\u0627\u0631\u0647\u0627 \u062f\u0627\u062e\u0644 \u0647\u0645\u0648\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a HTTP \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0646\u060c \u06a9\u0627\u0631\u0628\u0631 \u0686\u0646\u062f\u06cc\u0646 \u062b\u0627\u0646\u06cc\u0647 \u0645\u0646\u062a\u0638\u0631 \u0645\u06cc\u200c\u0645\u0648\u0646\u0647 \u0648 Worker \u0648\u0628 \u0647\u0645 \u062f\u0631\u06af\u06cc\u0631 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647\u062a\u0631\u0647 \u0639\u0645\u0644\u06cc\u0627\u062a \u0627\u0635\u0644\u06cc \u0633\u0631\u06cc\u0639 \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647 \u0648 \u06a9\u0627\u0631\u0647\u0627\u06cc \u0633\u0646\u06af\u06cc\u0646 \u0648\u0627\u0631\u062f Queue \u0628\u0634\u0646:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">POST \/tracked-products<br>\u2193<br>\u0630\u062e\u06cc\u0631\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a<br>\u2193<br>202 Accepted<br>\u2193<br>Queue<br>\u2193<br>Price Worker<br>Image Worker<br>Notification Worker<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0645\u062f\u0644 API \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u067e\u0627\u0633\u062e \u0628\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"id\": 8472,\n  \"status\": \"processing\"\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;id&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #6F42C1\">8472<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;status&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;processing&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0648\u0636\u0639\u06cc\u062a \u067e\u0631\u062f\u0627\u0632\u0634 \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>enum class TrackingStatus {\n    PROCESSING,\n    ACTIVE,\n    FAILED\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">enum<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackingStatus<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    PROCESSING,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ACTIVE,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    FAILED<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0635\u0641\u200c\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 RabbitMQ\u060c Kafka\u060c SQS \u06cc\u0627 \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc Job Queue \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0646 \u06a9\u0627\u0631\u0647\u0627\u06cc \u0633\u0646\u06af\u06cc\u0646 \u0628\u0627 \u0633\u0631\u0639\u062a \u06a9\u0646\u062a\u0631\u0644\u200c\u0634\u062f\u0647 \u067e\u0631\u062f\u0627\u0632\u0634 \u0628\u0634\u0646. \u0627\u06af\u0631 \u0646\u0627\u06af\u0647\u0627\u0646 \u062f\u0647 \u0647\u0632\u0627\u0631 \u0645\u062d\u0635\u0648\u0644 \u062b\u0628\u062a \u0628\u0634\u0647\u060c \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u06af\u0645 \u0646\u0645\u06cc\u0634\u0646\u061b \u062f\u0627\u062e\u0644 \u0635\u0641 \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0646 \u0648 Worker\u0647\u0627 \u0628\u0647\u200c\u0627\u0646\u062f\u0627\u0632\u0647 \u0638\u0631\u0641\u06cc\u062a \u0633\u06cc\u0633\u062a\u0645 \u0627\u0648\u0646\u200c\u0647\u0627 \u0631\u0648 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Timeout \u0648 \u0644\u063a\u0648 \u062f\u0631\u062e\u0648\u0627\u0633\u062a<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u06cc\u0686 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0634\u0628\u06a9\u0647\u200c\u0627\u06cc \u0646\u0628\u0627\u06cc\u062f \u0628\u06cc\u200c\u0646\u0647\u0627\u06cc\u062a \u0645\u0646\u062a\u0638\u0631 \u0628\u0645\u0648\u0646\u0647. \u0627\u06af\u0631 \u0633\u0631\u0648\u0631 \u067e\u0627\u0633\u062e \u0646\u0645\u06cc\u062f\u0647\u060c \u0627\u062a\u0635\u0627\u0644\u200c\u0647\u0627\u06cc \u0645\u0639\u0644\u0642 \u0647\u0645 \u0645\u0646\u0627\u0628\u0639 \u06af\u0648\u0634\u06cc \u0648 \u0647\u0645 \u0645\u0646\u0627\u0628\u0639 \u0633\u0631\u0648\u0631 \u0631\u0648 \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0646. \u062f\u0631 OkHttp \u0628\u0627\u06cc\u062f Timeout\u0647\u0627\u06cc \u0645\u0639\u0642\u0648\u0644 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val okHttpClient =\n    OkHttpClient.Builder()\n        .connectTimeout(\n            10,\n            TimeUnit.SECONDS\n        )\n        .readTimeout(\n            20,\n            TimeUnit.SECONDS\n        )\n        .writeTimeout(\n            20,\n            TimeUnit.SECONDS\n        )\n        .callTimeout(\n            30,\n            TimeUnit.SECONDS\n        )\n        .build()\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> okHttpClient <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    OkHttpClient.<\/span><span style=\"color: #6F42C1\">Builder<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">connectTimeout<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #005CC5\">10<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TimeUnit.SECONDS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">readTimeout<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #005CC5\">20<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TimeUnit.SECONDS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">writeTimeout<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #005CC5\">20<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TimeUnit.SECONDS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">callTimeout<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #005CC5\">30<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TimeUnit.SECONDS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0639\u062f\u0627\u062f \u0645\u0646\u0627\u0633\u0628 \u0628\u0647 \u0646\u0648\u0639 API \u0628\u0633\u062a\u06af\u06cc \u062f\u0627\u0631\u0646. Endpoint \u062f\u0631\u06cc\u0627\u0641\u062a \u0686\u0646\u062f \u062f\u0627\u062f\u0647 \u0645\u062a\u0646\u06cc \u0646\u0628\u0627\u06cc\u062f \u06cc\u06a9 \u062f\u0642\u06cc\u0642\u0647 \u0645\u0639\u0637\u0644 \u0628\u0645\u0648\u0646\u0647\u060c \u0627\u0645\u0627 Upload \u0641\u0627\u06cc\u0644 \u0645\u0645\u06a9\u0646\u0647 \u0628\u0647 \u0632\u0645\u0627\u0646 \u0628\u06cc\u0634\u062a\u0631\u06cc \u0646\u06cc\u0627\u0632 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u0647\u0645\u0686\u0646\u06cc\u0646 \u0648\u0642\u062a\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0627\u0632 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0645\u06cc\u0634\u0647\u060c \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u063a\u06cc\u0631\u0636\u0631\u0648\u0631\u06cc \u0628\u0627\u06cc\u062f \u0644\u063a\u0648 \u0628\u0634\u0647. \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 <code>viewModelScope<\/code> \u0648 Retrofit Coroutine \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u0628\u0627 \u067e\u0627\u06a9 \u0634\u062f\u0646 ViewModel\u060c Coroutine \u0648 Call \u0645\u0631\u0628\u0648\u0637 \u0647\u0645 \u0644\u063a\u0648 \u0628\u0634\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0628\u0627\u06cc\u062f \u0639\u0645\u0644\u06cc\u0627\u062a \u0645\u0647\u0645\u06cc \u0645\u062b\u0644 \u062b\u0628\u062a \u067e\u0631\u062f\u0627\u062e\u062a \u0631\u0648 \u0641\u0642\u0637 \u0628\u0647\u200c\u062e\u0627\u0637\u0631 \u0628\u0633\u062a\u0647 \u0634\u062f\u0646 \u0635\u0641\u062d\u0647 \u0628\u062f\u0648\u0646 \u0637\u0631\u0627\u062d\u06cc \u062f\u0631\u0633\u062a \u0644\u063a\u0648 \u06a9\u0646\u06cc\u0645. \u0628\u0631\u0627\u06cc \u0639\u0645\u0644\u06cc\u0627\u062a \u062d\u0633\u0627\u0633 \u0628\u0627\u06cc\u062f Idempotency \u0648 \u0648\u0636\u0639\u06cc\u062a \u0633\u0645\u062a \u0633\u0631\u0648\u0631 \u062f\u0631 \u0646\u0638\u0631 \u06af\u0631\u0641\u062a\u0647 \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Idempotency\u061b \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062a\u06a9\u0631\u0627\u0631\u06cc \u0646\u0628\u0627\u06cc\u062f \u062f\u0648 \u0639\u0645\u0644\u06cc\u0627\u062a \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u06a9\u0627\u0631\u0628\u0631 \u062f\u06a9\u0645\u0647 \u00ab\u062f\u0646\u0628\u0627\u0644 \u06a9\u0631\u062f\u0646 \u0645\u062d\u0635\u0648\u0644\u00bb \u0631\u0648 \u0645\u06cc\u200c\u0632\u0646\u0647\u060c \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0647 \u0633\u0631\u0648\u0631 \u0645\u06cc\u200c\u0631\u0633\u0647 \u0627\u0645\u0627 \u067e\u0627\u0633\u062e \u062f\u0631 \u0645\u0633\u06cc\u0631 \u0634\u0628\u06a9\u0647 \u06af\u0645 \u0645\u06cc\u0634\u0647. \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u062a\u0635\u0648\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0639\u0645\u0644\u06cc\u0627\u062a \u0634\u06a9\u0633\u062a \u062e\u0648\u0631\u062f\u0647 \u0648 \u062f\u0648\u0628\u0627\u0631\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0631\u0648 \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06af\u0631 Backend \u0628\u0631\u0627\u06cc \u0647\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06cc\u06a9 \u0631\u06a9\u0648\u0631\u062f \u062a\u0627\u0632\u0647 \u0628\u0633\u0627\u0632\u0647\u060c \u0645\u062d\u0635\u0648\u0644 \u062f\u0648 \u0628\u0627\u0631 \u062b\u0628\u062a \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0639\u0645\u0644\u06cc\u0627\u062a \u062d\u0633\u0627\u0633 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u06cc\u06a9 Idempotency Key \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface TrackingApi {\n\n    @POST(\"tracked-products\")\n    suspend fun trackProduct(\n        @Header(\"Idempotency-Key\")\n        idempotencyKey: String,\n\n        @Body\n        request: TrackProductRequest\n    ): TrackProductResponse\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackingApi<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@POST<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;tracked-products&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">trackProduct<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Header<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;Idempotency-Key&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        idempotencyKey: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Body<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        request: <\/span><span style=\"color: #6F42C1\">TrackProductRequest<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">TrackProductResponse<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun trackProduct(\n    productUrl: String\n): TrackProductResponse {\n\n    val requestId =\n        UUID.randomUUID().toString()\n\n    return api.trackProduct(\n        idempotencyKey = requestId,\n        request = TrackProductRequest(\n            url = productUrl\n        )\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">trackProduct<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    productUrl: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">): <\/span><span style=\"color: #6F42C1\">TrackProductResponse<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> requestId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        UUID.<\/span><span style=\"color: #6F42C1\">randomUUID<\/span><span style=\"color: #24292E\">().<\/span><span style=\"color: #6F42C1\">toString<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> api.<\/span><span style=\"color: #6F42C1\">trackProduct<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        idempotencyKey <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> requestId,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        request <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackProductRequest<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            url <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> productUrl<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u0631\u0648\u0631 \u06a9\u0644\u06cc\u062f \u0631\u0648 \u0628\u0631\u0627\u06cc \u0645\u062f\u062a\u06cc \u0630\u062e\u06cc\u0631\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06af\u0631 \u0647\u0645\u0648\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0648\u0628\u0627\u0631\u0647 \u0628\u0627 \u0647\u0645\u0648\u0646 \u06a9\u0644\u06cc\u062f \u062f\u0631\u06cc\u0627\u0641\u062a \u0628\u0634\u0647\u060c \u0639\u0645\u0644\u06cc\u0627\u062a \u062a\u0627\u0632\u0647\u200c\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u0646\u062a\u06cc\u062c\u0647 \u0642\u0628\u0644\u06cc \u0631\u0648 \u0628\u0631\u0645\u06cc\u200c\u06af\u0631\u062f\u0648\u0646\u0647. \u0627\u06cc\u0646 \u0645\u0641\u0647\u0648\u0645 \u062f\u0631 \u067e\u0631\u062f\u0627\u062e\u062a\u060c \u062b\u0628\u062a \u0633\u0641\u0627\u0631\u0634\u060c \u0627\u0631\u0633\u0627\u0644 \u06a9\u062f \u0648 \u0639\u0645\u0644\u06cc\u0627\u062a\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0646\u0628\u0627\u06cc\u062f \u062a\u06a9\u0631\u0627\u0631 \u0628\u0634\u0646 \u0627\u0647\u0645\u06cc\u062a \u0632\u06cc\u0627\u062f\u06cc \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0637\u0648\u0631 \u0628\u0641\u0647\u0645\u06cc\u0645 \u0633\u06cc\u0633\u062a\u0645 \u0648\u0627\u0642\u0639\u0627\u064b \u0638\u0631\u0641\u06cc\u062a \u0686\u0646\u062f \u06a9\u0627\u0631\u0628\u0631 \u0631\u0648 \u062f\u0627\u0631\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0627 \u062d\u062f\u0633 \u0632\u062f\u0646 \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u06af\u06cc\u0645 \u00ab\u0627\u06cc\u0646 \u0633\u0631\u0648\u0631 \u062f\u0647 \u0647\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0631\u0648 \u062c\u0648\u0627\u0628 \u0645\u06cc\u062f\u0647\u00bb. \u0628\u0627\u06cc\u062f Load Test \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647. \u062f\u0631 \u062a\u0633\u062a \u0628\u0627\u0631\u060c \u062a\u0639\u062f\u0627\u062f \u0645\u0634\u062e\u0635\u06cc Client \u0645\u062c\u0627\u0632\u06cc Endpoint\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc \u0631\u0648 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0646 \u0648 \u0645\u0639\u06cc\u0627\u0631\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 \u0627\u06cc\u0646\u200c\u0647\u0627 \u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc \u0645\u06cc\u0634\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Requests Per Second\nAverage Response Time\nP95 Latency\nP99 Latency\nError Rate\nCPU Usage\nMemory Usage\nDatabase Connections\nQueue Length\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u06cc\u0627\u0646\u06af\u06cc\u0646 \u0632\u0645\u0627\u0646 \u067e\u0627\u0633\u062e \u0628\u0647\u200c\u062a\u0646\u0647\u0627\u06cc\u06cc \u06a9\u0627\u0641\u06cc \u0646\u06cc\u0633\u062a. \u0645\u0645\u06a9\u0646\u0647 \u0645\u06cc\u0627\u0646\u06af\u06cc\u0646 \u06f2\u06f0\u06f0 \u0645\u06cc\u0644\u06cc\u200c\u062b\u0627\u0646\u06cc\u0647 \u0628\u0627\u0634\u0647\u060c \u0627\u0645\u0627 \u067e\u0646\u062c \u062f\u0631\u0635\u062f \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0628\u06cc\u0634\u062a\u0631 \u0627\u0632 \u067e\u0646\u062c \u062b\u0627\u0646\u06cc\u0647 \u0645\u0646\u062a\u0638\u0631 \u0628\u0645\u0648\u0646\u0646. <code>P95 = 5s<\/code> \u06cc\u0639\u0646\u06cc \u06f9\u06f5 \u062f\u0631\u0635\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u062f\u0631 \u06a9\u0645\u062a\u0631 \u0627\u0632 \u067e\u0646\u062c \u062b\u0627\u0646\u06cc\u0647 \u067e\u0627\u0633\u062e \u06af\u0631\u0641\u062a\u0646 \u0648 \u067e\u0646\u062c \u062f\u0631\u0635\u062f \u06a9\u0646\u062f\u062a\u0631 \u0628\u0648\u062f\u0646. \u062f\u0631 \u0633\u06cc\u0633\u062a\u0645 \u0648\u0627\u0642\u0639\u06cc \u0647\u0645\u06cc\u0646 \u067e\u0646\u062c \u062f\u0631\u0635\u062f \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u0647\u0632\u0627\u0631\u0627\u0646 \u06a9\u0627\u0631\u0628\u0631 \u0646\u0627\u0631\u0627\u0636\u06cc \u0628\u0627\u0634\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Load Test \u0628\u0627\u06cc\u062f \u0631\u0648\u06cc \u0645\u062d\u06cc\u0637\u06cc \u0634\u0628\u06cc\u0647 Production \u0648 \u0628\u0627 \u062f\u0627\u062f\u0647\u200c\u0627\u06cc \u0646\u0632\u062f\u06cc\u06a9 \u0628\u0647 \u062d\u062c\u0645 \u0648\u0627\u0642\u0639\u06cc \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647. Query\u0627\u06cc \u06a9\u0647 \u0631\u0648\u06cc \u062c\u062f\u0648\u0644 \u0647\u0632\u0627\u0631\u0631\u062f\u06cc\u0641\u06cc \u0633\u0631\u06cc\u0639 \u0627\u062c\u0631\u0627 \u0645\u06cc\u0634\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 \u0631\u0648\u06cc \u062c\u062f\u0648\u0644 \u0635\u062f \u0645\u06cc\u0644\u06cc\u0648\u0646 \u0631\u062f\u06cc\u0641\u06cc \u0631\u0641\u062a\u0627\u0631 \u06a9\u0627\u0645\u0644\u0627\u064b \u0645\u062a\u0641\u0627\u0648\u062a\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u06cc\u06a9 \u0645\u0639\u0645\u0627\u0631\u06cc \u0645\u0646\u0637\u0642\u06cc \u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 <\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0646\u0633\u062e\u0647 \u0648\u0627\u0642\u0639\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u062c\u0631\u06cc\u0627\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0648 \u0627\u06cc\u0646\u200c\u0637\u0648\u0631 \u0637\u0631\u0627\u062d\u06cc \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">Android App<br>\u2193<br>Local Room Cache<br>\u2193<br>API Gateway \/ Load Balancer<br>\u2193<br>Backend Instances<br>\u2193<br>Redis Cache<br>\u2193<br>Primary Database<br>\u2193<br>Queue and Workers<br>\u2193<br>Price Crawlers \/ Notification Service<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0627\u0628\u062a\u062f\u0627 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc Room \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u062f\u0647 \u0648 \u0641\u0642\u0637 \u062f\u0631 \u0635\u0648\u0631\u062a \u0646\u06cc\u0627\u0632 Sync \u0645\u06cc\u200c\u06a9\u0646\u0647. \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u062c\u0633\u062a\u200c\u0648\u062c\u0648 Debounce \u0645\u06cc\u0634\u0646\u060c \u0641\u0647\u0631\u0633\u062a\u200c\u0647\u0627 \u0628\u0627 Paging \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u0634\u0646 \u0648 \u0642\u06cc\u0645\u062a \u0686\u0646\u062f \u0645\u062d\u0635\u0648\u0644 \u0628\u0647\u200c\u0635\u0648\u0631\u062a Batch \u06af\u0631\u0641\u062a\u0647 \u0645\u06cc\u0634\u0647. Load Balancer \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u0631\u0648 \u0628\u06cc\u0646 \u0686\u0646\u062f Backend \u062a\u0642\u0633\u06cc\u0645 \u0645\u06cc\u200c\u06a9\u0646\u0647. Backend \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u067e\u0631\u062a\u06a9\u0631\u0627\u0631 \u0631\u0648 \u0627\u0632 Redis \u0645\u06cc\u200c\u062e\u0648\u0646\u0647 \u0648 \u0639\u0645\u0644\u06cc\u0627\u062a \u0633\u0646\u06af\u06cc\u0646 \u0631\u0648 \u0648\u0627\u0631\u062f Queue \u0645\u06cc\u200c\u06a9\u0646\u0647. \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 Index \u0645\u0646\u0627\u0633\u0628 \u0648 Connection Pool \u0645\u062d\u062f\u0648\u062f \u062f\u0627\u0631\u0647. \u0627\u0639\u0644\u0627\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u0642\u06cc\u0645\u062a \u0627\u0632 \u0637\u0631\u06cc\u0642 FCM \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u0634\u0647 \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0631\u0627\u06cc \u0641\u0647\u0645\u06cc\u062f\u0646 \u062a\u063a\u06cc\u06cc\u0631\u060c \u062f\u0627\u0626\u0645\u0627\u064b Polling \u0627\u0646\u062c\u0627\u0645 \u0646\u0645\u06cc\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0686\u0646\u06cc\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc\u200c\u0627\u06cc \u0647\u0631 \u0644\u0627\u06cc\u0647 \u0628\u062e\u0634\u06cc \u0627\u0632 \u0641\u0634\u0627\u0631 \u0631\u0648 \u06a9\u0646\u062a\u0631\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06af\u0631 \u0641\u0642\u0637 \u06cc\u06a9 VPS \u0628\u0633\u06cc\u0627\u0631 \u0642\u0648\u06cc \u0628\u062e\u0631\u06cc\u0645 \u0627\u0645\u0627 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0628\u0631\u0627\u06cc \u0647\u0631 \u0645\u062d\u0635\u0648\u0644 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062c\u062f\u0627 \u0628\u0641\u0631\u0633\u062a\u0647\u060c \u0645\u0634\u06a9\u0644 \u062f\u06cc\u0631 \u06cc\u0627 \u0632\u0648\u062f \u0628\u0631\u0645\u06cc\u200c\u06af\u0631\u062f\u0647. \u0627\u06af\u0631 \u0641\u0642\u0637 Cache \u0633\u0645\u062a \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645 \u0627\u0645\u0627 Backend \u0628\u0631\u0627\u06cc \u0647\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a Query\u0647\u0627\u06cc \u0633\u0646\u06af\u06cc\u0646 \u0627\u062c\u0631\u0627 \u06a9\u0646\u0647\u060c \u0628\u0627\u0632 \u0647\u0645 \u0633\u06cc\u0633\u062a\u0645 \u0634\u06a9\u0646\u0646\u062f\u0647 \u0645\u06cc\u200c\u0645\u0648\u0646\u0647. \u0645\u0642\u06cc\u0627\u0633\u200c\u067e\u0630\u06cc\u0631\u06cc \u0646\u062a\u06cc\u062c\u0647 \u06cc\u06a9 \u062a\u06a9\u0646\u06cc\u06a9 \u062c\u0627\u062f\u0648\u06cc\u06cc \u0646\u06cc\u0633\u062a\u061b \u062d\u0627\u0635\u0644 \u062d\u0630\u0641 \u06a9\u0627\u0631\u0647\u0627\u06cc \u062a\u06a9\u0631\u0627\u0631\u06cc\u060c \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062f\u0646 \u0645\u0635\u0631\u0641 \u0645\u0646\u0627\u0628\u0639 \u0648 \u062c\u062f\u0627 \u06a9\u0631\u062f\u0646 \u0645\u0633\u0626\u0648\u0644\u06cc\u062a\u200c\u0647\u0627 \u062f\u0631 \u062a\u0645\u0627\u0645 \u0645\u0633\u06cc\u0631 Client \u062a\u0627 Database \u0647\u0633\u062a.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u06a9\u200c\u0644\u06cc\u0633\u062a \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0647\u0645\u200c\u0632\u0645\u0627\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0642\u0628\u0644 \u0627\u0632 \u0627\u06cc\u0646\u06a9\u0647 \u0627\u062f\u0639\u0627 \u06a9\u0646\u06cc\u0645 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0628\u0631\u0627\u06cc \u062a\u0639\u062f\u0627\u062f \u0632\u06cc\u0627\u062f\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0622\u0645\u0627\u062f\u0647\u200c\u0633\u062a\u060c \u0628\u0627\u06cc\u062f \u0627\u06cc\u0646 \u0645\u0648\u0627\u0631\u062f \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u062c\u0633\u062a\u200c\u0648\u062c\u0648 \u0628\u0627 \u0647\u0631 \u062d\u0631\u0641 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u06cc\u062c\u0627\u062f \u0646\u06a9\u0646\u0647.<\/li>\n\n\n\n<li>\u0644\u0645\u0633 \u0686\u0646\u062f\u0628\u0627\u0631\u0647 \u062f\u06a9\u0645\u0647\u060c \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0645\u0648\u0627\u0632\u06cc \u062a\u06a9\u0631\u0627\u0631\u06cc \u0646\u0633\u0627\u0632\u0647.<\/li>\n\n\n\n<li>\u0641\u0647\u0631\u0633\u062a\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af Pagination \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>\u0628\u0631\u0627\u06cc \u0647\u0631 \u0622\u06cc\u062a\u0645 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062c\u062f\u0627 \u0627\u0631\u0633\u0627\u0644 \u0646\u0634\u0647.<\/li>\n\n\n\n<li>\u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0642\u0627\u0628\u0644\u200c\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062f\u0627\u062e\u0644 Room Cache \u0628\u0634\u0646.<\/li>\n\n\n\n<li>Cache \u0632\u0645\u0627\u0646 \u0627\u0639\u062a\u0628\u0627\u0631 \u0645\u0634\u062e\u0635 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>Sync\u0647\u0627\u06cc \u06cc\u06a9\u0633\u0627\u0646 \u0628\u0627 <code>Mutex<\/code> \u06cc\u0627 Unique Work \u06a9\u0646\u062a\u0631\u0644 \u0628\u0634\u0646.<\/li>\n\n\n\n<li>Retry \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u062e\u0637\u0627\u0647\u0627\u06cc \u0645\u0648\u0642\u062a \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>Retry \u0627\u0632 Exponential Backoff \u0648 Jitter \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0647.<\/li>\n\n\n\n<li>\u06a9\u0627\u0631\u0647\u0627\u06cc \u067e\u0633\u200c\u0632\u0645\u06cc\u0646\u0647 \u0647\u0645\u0647 \u062f\u0633\u062a\u06af\u0627\u0647\u200c\u0647\u0627 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0634\u0631\u0648\u0639 \u0646\u0634\u0646.<\/li>\n\n\n\n<li>\u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u06a9\u0648\u0686\u06a9 \u0628\u0627 Delta Sync \u062f\u0631\u06cc\u0627\u0641\u062a \u0628\u0634\u0646.<\/li>\n\n\n\n<li>\u0628\u0631\u0627\u06cc \u0627\u0639\u0644\u0627\u0646 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0627\u0632 Push \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0628\u0634\u0647\u060c \u0646\u0647 Polling \u0628\u06cc\u200c\u0648\u0642\u0641\u0647.<\/li>\n\n\n\n<li>Backend \u0628\u0631\u0627\u06cc Endpoint\u0647\u0627\u06cc \u062d\u0633\u0627\u0633 Rate Limit \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u067e\u0627\u0633\u062e <code>429<\/code> \u062f\u0631 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u062f\u0631\u0633\u062a \u0645\u062f\u06cc\u0631\u06cc\u062a \u0628\u0634\u0647.<\/li>\n\n\n\n<li>Timeout\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647 \u0645\u0634\u062e\u0635 \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>\u0639\u0645\u0644\u06cc\u0627\u062a \u062a\u06a9\u0631\u0627\u0631\u0646\u0627\u067e\u0630\u06cc\u0631 Idempotency Key \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>API\u0647\u0627\u06cc \u0633\u0646\u06af\u06cc\u0646 \u0648\u0627\u0631\u062f Queue \u0628\u0634\u0646.<\/li>\n\n\n\n<li>Query\u0647\u0627\u06cc \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 Index \u0645\u0646\u0627\u0633\u0628 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>Cache \u0633\u0645\u062a \u0633\u0631\u0648\u0631 \u0628\u0631\u0627\u06cc \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u067e\u0631\u062a\u06a9\u0631\u0627\u0631 \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0633\u06cc\u0633\u062a\u0645 \u0628\u0627 Load Test \u0648\u0627\u0642\u0639\u06cc \u0622\u0632\u0645\u0627\u06cc\u0634 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0632\u0645\u0627\u0646 \u067e\u0627\u0633\u062e P95 \u0648 P99 \u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc \u0628\u0634\u0647\u060c \u0646\u0647 \u0641\u0642\u0637 \u0645\u06cc\u0627\u0646\u06af\u06cc\u0646.<\/li>\n\n\n\n<li>CPU\u060c RAM\u060c \u0627\u062a\u0635\u0627\u0644\u200c\u0647\u0627\u06cc \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0648 \u0646\u0631\u062e \u062e\u0637\u0627 \u0645\u0627\u0646\u06cc\u062a\u0648\u0631 \u0628\u0634\u0646.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062f\u06cc\u0631\u06cc\u062a \u0686\u0646\u062f \u0647\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0627\u0632 \u062c\u0627\u06cc\u06cc \u0634\u0631\u0648\u0639 \u0646\u0645\u06cc\u0634\u0647 \u06a9\u0647 \u0633\u0631\u0648\u0631 \u0631\u0648 \u0628\u0632\u0631\u06af\u200c\u062a\u0631 \u06a9\u0646\u06cc\u0645\u061b \u0627\u0632 \u062c\u0627\u06cc\u06cc \u0634\u0631\u0648\u0639 \u0645\u06cc\u0634\u0647 \u06a9\u0647 \u0628\u0641\u0647\u0645\u06cc\u0645 \u0647\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0686\u0646\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u06a9\u062f\u0648\u0645 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u0627\u0635\u0644\u0627\u064b \u0644\u0627\u0632\u0645 \u0646\u06cc\u0633\u062a\u0646. \u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0628\u0627 Debounce \u062c\u0633\u062a\u200c\u0648\u062c\u0648\u060c \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u06a9\u0644\u06cc\u06a9 \u062a\u06a9\u0631\u0627\u0631\u06cc\u060c Batch Request\u060c Paging\u060c Cache \u0645\u062d\u0644\u06cc \u0648 Delta Sync \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0641\u0634\u0627\u0631 \u0627\u06cc\u062c\u0627\u062f\u0634\u062f\u0647 \u062a\u0648\u0633\u0637 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0631\u0648 \u0628\u0647\u200c\u0634\u062f\u062a \u06a9\u0627\u0647\u0634 \u0628\u062f\u06cc\u0645. \u0628\u0627 Retry \u06a9\u0646\u062a\u0631\u0644\u200c\u0634\u062f\u0647\u060c Exponential Backoff\u060c Jitter \u0648 \u0645\u062f\u06cc\u0631\u06cc\u062a \u067e\u0627\u0633\u062e <code>429<\/code> \u0647\u0645 \u0627\u062c\u0627\u0632\u0647 \u0646\u0645\u06cc\u062f\u06cc\u0645 \u0627\u062e\u062a\u0644\u0627\u0644 \u0645\u0648\u0642\u062a \u0633\u0631\u0648\u0631 \u0628\u0647 \u0645\u0648\u062c\u06cc \u0627\u0632 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u062a\u0627\u0632\u0647 \u062a\u0628\u062f\u06cc\u0644 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0633\u0645\u062a Backend \u0647\u0645 \u0645\u0642\u06cc\u0627\u0633\u200c\u067e\u0630\u06cc\u0631\u06cc \u0628\u0647 \u0645\u0639\u0646\u0627\u06cc \u0627\u0641\u0632\u0648\u062f\u0646 \u0628\u06cc\u200c\u067e\u0627\u06cc\u0627\u0646 \u0633\u0631\u0648\u0631 \u0646\u06cc\u0633\u062a. Query\u0647\u0627\u06cc \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0628\u0627\u06cc\u062f \u0628\u0647\u06cc\u0646\u0647 \u0628\u0627\u0634\u0646\u060c \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u067e\u0631\u062a\u06a9\u0631\u0627\u0631 Cache \u0628\u0634\u0646\u060c \u0639\u0645\u0644\u06cc\u0627\u062a \u0633\u0646\u06af\u06cc\u0646 \u0648\u0627\u0631\u062f Queue \u0628\u0634\u0646 \u0648 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u062f\u0631 \u0635\u0648\u0631\u062a \u0646\u06cc\u0627\u0632 \u0628\u06cc\u0646 \u0686\u0646\u062f \u0646\u0645\u0648\u0646\u0647 Backend \u062a\u0642\u0633\u06cc\u0645 \u0628\u0634\u0646. \u0628\u0639\u062f \u0627\u0632 \u0647\u0645\u0647 \u0627\u06cc\u0646 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0647\u0645 \u0628\u0627\u06cc\u062f \u0633\u06cc\u0633\u062a\u0645 \u0631\u0648 \u0632\u06cc\u0631 \u0628\u0627\u0631 \u0648\u0627\u0642\u0639\u06cc \u0622\u0632\u0645\u0627\u06cc\u0634 \u06a9\u0646\u06cc\u0645\u061b \u0686\u0648\u0646 \u0628\u062f\u0648\u0646 \u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc\u060c \u0647\u0631 \u0639\u062f\u062f\u06cc \u062f\u0631\u0628\u0627\u0631\u0647 \u0638\u0631\u0641\u06cc\u062a \u0633\u06cc\u0633\u062a\u0645 \u0641\u0642\u0637 \u062d\u062f\u0633\u0647. \u0645\u0639\u0645\u0627\u0631\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u06a9\u0627\u0631\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647 \u06a9\u0647 \u0628\u0627 \u0627\u0641\u0632\u0627\u06cc\u0634 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646\u060c \u0628\u0647\u200c\u062c\u0627\u06cc \u0641\u0631\u0648\u067e\u0627\u0634\u06cc \u0646\u0627\u06af\u0647\u0627\u0646\u06cc \u0633\u06cc\u0633\u062a\u0645\u060c \u0628\u062a\u0648\u0646\u06cc\u0645 \u06af\u0644\u0648\u06af\u0627\u0647 \u0631\u0648 \u0634\u0646\u0627\u0633\u0627\u06cc\u06cc \u06a9\u0646\u06cc\u0645 \u0648 \u0638\u0631\u0641\u06cc\u062a \u0647\u0645\u0648\u0646 \u0628\u062e\u0634 \u0631\u0648 \u0628\u0647\u200c\u0634\u06a9\u0644 \u06a9\u0646\u062a\u0631\u0644\u200c\u0634\u062f\u0647 \u0627\u0641\u0632\u0627\u06cc\u0634 \u0628\u062f\u06cc\u0645.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u200c\u0648\u0686\u0647\u0627\u0631\u0645<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">Push \u062d\u0631\u0641\u0647\u200c\u0627\u06cc\u061b \u0627\u0632 \u0627\u0631\u0633\u0627\u0644 \u06cc\u06a9 \u0627\u0639\u0644\u0627\u0646 \u0633\u0627\u062f\u0647 \u062a\u0627 \u0633\u0627\u062e\u062a \u0633\u06cc\u0633\u062a\u0645 \u0627\u0639\u0644\u0627\u0646 \u0648\u0627\u0642\u0639\u06cc<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u062f\u0631\u0633\u200c\u0647\u0627\u06cc \u0642\u0628\u0644\u06cc \u0628\u0627 Firebase Cloud Messaging \u0622\u0634\u0646\u0627 \u0634\u062f\u06cc\u0645\u060c Token \u062f\u0633\u062a\u06af\u0627\u0647 \u0631\u0648 \u06af\u0631\u0641\u062a\u06cc\u0645\u060c <code>FirebaseMessagingService<\/code> \u0633\u0627\u062e\u062a\u06cc\u0645 \u0648 \u06cc\u06a9 \u0627\u0639\u0644\u0627\u0646 \u0633\u0627\u062f\u0647 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u06cc\u0645. \u0627\u0645\u0627 \u0686\u06cc\u0632\u06cc \u06a9\u0647 \u062f\u0631 \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647 \u0622\u0632\u0645\u0627\u06cc\u0634\u06cc \u0628\u0647 \u0627\u0633\u0645 Push Notification \u0645\u06cc\u200c\u0634\u0646\u0627\u0633\u06cc\u0645\u060c \u0628\u0627 \u0686\u06cc\u0632\u06cc \u06a9\u0647 \u062f\u0631 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648\u0627\u0642\u0639\u06cc \u0645\u062b\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u06cc\u0645 \u062a\u0641\u0627\u0648\u062a \u0632\u06cc\u0627\u062f\u06cc \u062f\u0627\u0631\u0647. \u062f\u0631 \u0646\u0633\u062e\u0647 \u0633\u0627\u062f\u0647\u060c \u0633\u0631\u0648\u0631 \u06cc\u06a9 \u0639\u0646\u0648\u0627\u0646 \u0648 \u0645\u062a\u0646 \u0645\u06cc\u200c\u0641\u0631\u0633\u062a\u0647 \u0648 \u06af\u0648\u0634\u06cc \u0647\u0645 \u06cc\u06a9 \u0627\u0639\u0644\u0627\u0646 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u062f\u0647. \u062f\u0631 \u0646\u0633\u062e\u0647 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0628\u0627\u06cc\u062f \u0645\u0634\u062e\u0635 \u0628\u0627\u0634\u0647 \u0627\u0639\u0644\u0627\u0646 \u0628\u0631\u0627\u06cc \u06a9\u062f\u0648\u0645 \u06a9\u0627\u0631\u0628\u0631 \u0648 \u06a9\u062f\u0648\u0645 \u062f\u0633\u062a\u06af\u0627\u0647\u0647\u060c \u0628\u0627 \u0644\u0645\u0633 \u0627\u0639\u0644\u0627\u0646 \u0686\u0647 \u0635\u0641\u062d\u0647\u200c\u0627\u06cc \u0628\u0627\u0632 \u0645\u06cc\u0634\u0647\u060c \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0686\u0646\u062f \u062f\u0633\u062a\u06af\u0627\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647 \u0686\u0647 \u0627\u062a\u0641\u0627\u0642\u06cc \u0645\u06cc\u200c\u0627\u0641\u062a\u0647\u060c Token \u0639\u0648\u0636\u200c\u0634\u062f\u0647 \u0686\u0637\u0648\u0631 \u0628\u0647 \u0633\u0631\u0648\u0631 \u0645\u06cc\u200c\u0631\u0633\u0647\u060c \u0627\u0639\u0644\u0627\u0646 \u062a\u06a9\u0631\u0627\u0631\u06cc \u0686\u0637\u0648\u0631 \u062d\u0630\u0641 \u0645\u06cc\u0634\u0647 \u0648 \u0627\u06af\u0631 \u062f\u0633\u062a\u06af\u0627\u0647 \u0686\u0646\u062f \u0633\u0627\u0639\u062a \u0622\u0641\u0644\u0627\u06cc\u0646 \u0628\u0648\u062f\u060c \u0622\u06cc\u0627 \u0627\u0639\u0644\u0627\u0646 \u0642\u062f\u06cc\u0645\u06cc \u0647\u0646\u0648\u0632 \u0627\u0631\u0632\u0634 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0646 \u062f\u0627\u0631\u0647 \u06cc\u0627 \u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u06a9\u0627\u0631\u0628\u0631\u062f Push \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0628\u062f\u0648\u0646 \u0628\u0627\u0632 \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0632 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644 \u0628\u0627\u062e\u0628\u0631 \u0628\u0634\u0647. \u0627\u0645\u0627 \u0647\u0645\u06cc\u0646 \u0646\u06cc\u0627\u0632 \u0633\u0627\u062f\u0647 \u0686\u0646\u062f \u0633\u0624\u0627\u0644 \u0645\u0647\u0645 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0641\u0631\u0636 \u06a9\u0646 \u0642\u06cc\u0645\u062a \u06cc\u06a9 \u0644\u067e\u200c\u062a\u0627\u067e \u0637\u06cc \u062f\u0647 \u062f\u0642\u06cc\u0642\u0647 \u0633\u0647 \u0628\u0627\u0631 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f\u0647. \u0622\u06cc\u0627 \u0628\u0627\u06cc\u062f \u0633\u0647 \u0627\u0639\u0644\u0627\u0646 \u062c\u062f\u0627 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u06cc\u0645\u061f \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0648 \u062a\u0628\u0644\u062a \u0648\u0627\u0631\u062f \u062d\u0633\u0627\u0628\u0634 \u0634\u062f\u0647\u060c \u0627\u0639\u0644\u0627\u0646 \u0628\u0627\u06cc\u062f \u0628\u0647 \u0647\u0631 \u062f\u0648 \u062f\u0633\u062a\u06af\u0627\u0647 \u0628\u0631\u0633\u0647\u061f \u0627\u06af\u0631 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0627\u0648\u0644 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0628\u0627\u0632 \u06a9\u0631\u062f\u060c \u0622\u06cc\u0627 \u0627\u0639\u0644\u0627\u0646 \u062a\u0628\u0644\u062a \u0647\u0645 \u0628\u0627\u06cc\u062f \u062d\u0630\u0641 \u0628\u0634\u0647\u061f \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631\u06cc\u0627\u0641\u062a \u0627\u0639\u0644\u0627\u0646 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0631\u0648 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0647\u060c \u0622\u06cc\u0627 \u0633\u0631\u0648\u0631 \u0647\u0646\u0648\u0632 \u062d\u0642 \u062f\u0627\u0631\u0647 \u067e\u06cc\u0627\u0645 \u0631\u0648 \u0628\u0641\u0631\u0633\u062a\u0647\u061f \u0627\u06af\u0631 Token \u0642\u0628\u0644\u06cc \u062f\u0633\u062a\u06af\u0627\u0647 \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u0634\u062f\u0647\u060c \u0686\u0637\u0648\u0631 \u0628\u0627\u06cc\u062f \u0627\u0648\u0646 \u0631\u0648 \u0627\u0632 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u067e\u0627\u06a9 \u06a9\u0646\u06cc\u0645\u061f \u067e\u0627\u0633\u062e \u0627\u06cc\u0646 \u0633\u0624\u0627\u0644\u200c\u0647\u0627\u0633\u062a \u06a9\u0647 \u06cc\u06a9 Push \u0633\u0627\u062f\u0647 \u0631\u0648 \u0628\u0647 \u06cc\u06a9 \u0633\u06cc\u0633\u062a\u0645 \u0627\u0639\u0644\u0627\u0646 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u062a\u0628\u062f\u06cc\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Push \u0641\u0642\u0637 \u06cc\u06a9 \u0627\u0639\u0644\u0627\u0646 \u0646\u06cc\u0633\u062a<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0648\u0644 \u0628\u0627\u06cc\u062f \u0633\u0647 \u0645\u0641\u0647\u0648\u0645 \u0631\u0648 \u0627\u0632 \u0647\u0645 \u062c\u062f\u0627 \u06a9\u0646\u06cc\u0645: <strong>\u067e\u06cc\u0627\u0645 Push\u060c \u0627\u0639\u0644\u0627\u0646 \u0633\u06cc\u0633\u062a\u0645 \u0648 \u0631\u0648\u06cc\u062f\u0627\u062f \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647<\/strong>. \u067e\u06cc\u0627\u0645 Push \u062f\u0627\u062f\u0647\u200c\u0627\u06cc\u0647 \u06a9\u0647 \u0627\u0632 \u0633\u0631\u0648\u0631 \u0628\u0647 FCM \u0648 \u0633\u067e\u0633 \u0628\u0647 \u06cc\u06a9 \u0646\u0645\u0648\u0646\u0647 \u0646\u0635\u0628\u200c\u0634\u062f\u0647 \u0627\u0632 \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u06cc\u200c\u0631\u0633\u0647. \u0627\u0639\u0644\u0627\u0646 \u0633\u06cc\u0633\u062a\u0645 \u0647\u0645\u0648\u0646 \u0686\u06cc\u0632\u06cc\u200c\u0633\u062a \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631 Notification Shade \u0645\u06cc\u200c\u0628\u06cc\u0646\u0647. \u0631\u0648\u06cc\u062f\u0627\u062f \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645 \u062a\u063a\u06cc\u06cc\u0631\u06cc\u0647 \u06a9\u0647 \u0628\u0639\u062f \u0627\u0632 \u062f\u0631\u06cc\u0627\u0641\u062a \u067e\u06cc\u0627\u0645 \u062f\u0631 \u062f\u0627\u062f\u0647 \u06cc\u0627 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0627\u062a\u0641\u0627\u0642 \u0645\u06cc\u200c\u0627\u0641\u062a\u0647. \u0627\u06cc\u0646 \u0633\u0647 \u0645\u0648\u0631\u062f \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u0628\u0627 \u0647\u0645 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0628\u0634\u0646\u060c \u0627\u0645\u0627 \u06cc\u06a9\u06cc \u0646\u06cc\u0633\u062a\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644\u060c \u0633\u0631\u0648\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0641\u0642\u0637 \u0628\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u06af\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u062d\u0635\u0648\u0644 \u0634\u0645\u0627\u0631\u0647 \u06f8\u06f4\u06f7\u06f2 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"type\": \"PRICE_CHANGED\",\n  \"productId\": \"8472\"\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;type&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;PRICE_CHANGED&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;productId&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;8472&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0639\u062f \u0627\u0632 \u062f\u0631\u06cc\u0627\u0641\u062a \u067e\u06cc\u0627\u0645\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062a\u0627\u0632\u0647 \u0631\u0648 \u0627\u0632 API \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647 \u0648 Room \u0631\u0648 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0628\u062f\u0648\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0627\u0644\u0632\u0627\u0645\u0627\u064b \u0686\u06cc\u0632\u06cc \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647. \u062f\u0631 \u0633\u0646\u0627\u0631\u06cc\u0648\u06cc \u062f\u06cc\u06af\u0647\u060c \u0633\u0631\u0648\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0644\u0627\u0632\u0645 \u0628\u0631\u0627\u06cc \u0633\u0627\u062e\u062a \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0647\u0645 \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"type\": \"PRICE_DROP\",\n  \"eventId\": \"evt_986215\",\n  \"productId\": \"8472\",\n  \"title\": \"\u0642\u06cc\u0645\u062a \u0644\u067e\u200c\u062a\u0627\u067e \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\",\n  \"body\": \"\u0642\u06cc\u0645\u062a \u0627\u0632 \u06f4\u06f2\u066c\u06f5\u06f0\u06f0\u066c\u06f0\u06f0\u06f0 \u0628\u0647 \u06f3\u06f9\u066c\u06f9\u06f0\u06f0\u066c\u06f0\u06f0\u06f0 \u062a\u0648\u0645\u0627\u0646 \u0631\u0633\u06cc\u062f.\",\n  \"imageUrl\": \"https:\/\/cdn.gheimatban.com\/products\/8472.jpg\"\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;type&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;PRICE_DROP&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;eventId&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;evt_986215&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;productId&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;8472&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;title&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;\u0642\u06cc\u0645\u062a \u0644\u067e\u200c\u062a\u0627\u067e \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;body&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;\u0642\u06cc\u0645\u062a \u0627\u0632 \u06f4\u06f2\u066c\u06f5\u06f0\u06f0\u066c\u06f0\u06f0\u06f0 \u0628\u0647 \u06f3\u06f9\u066c\u06f9\u06f0\u06f0\u066c\u06f0\u06f0\u06f0 \u062a\u0648\u0645\u0627\u0646 \u0631\u0633\u06cc\u062f.&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;imageUrl&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;https:\/\/cdn.gheimatban.com\/products\/8472.jpg&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u062d\u0627\u0644\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0628\u0644\u0627\u0641\u0627\u0635\u0644\u0647 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0628\u0633\u0627\u0632\u0647 \u0648 \u0628\u0639\u062f \u062f\u0631 \u067e\u0633\u200c\u0632\u0645\u06cc\u0646\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u06a9\u0627\u0645\u0644 \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 Sync \u06a9\u0646\u0647. \u0627\u06cc\u0646 \u0637\u0631\u0627\u062d\u06cc \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u0632 \u0645\u062f\u0644\u06cc \u0645\u0637\u0645\u0626\u0646\u200c\u062a\u0631\u0647 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0628\u062a\u062f\u0627 \u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u062e\u0627\u0644\u06cc \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u0647\u060c \u0628\u0639\u062f \u0645\u0646\u062a\u0638\u0631 \u067e\u0627\u0633\u062e \u0633\u0631\u0648\u0631 \u0628\u0645\u0648\u0646\u0647 \u0648 \u0641\u0642\u0637 \u062f\u0631 \u0635\u0648\u0631\u062a \u0645\u0648\u0641\u0642 \u0628\u0648\u062f\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0634\u0628\u06a9\u0647 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647\u061b \u0686\u0648\u0646 onMessageReceived() \u0632\u0645\u0627\u0646 \u0645\u062d\u062f\u0648\u062f\u06cc \u0628\u0631\u0627\u06cc \u067e\u0631\u062f\u0627\u0632\u0634 \u062f\u0627\u0631\u0647 \u0648 \u0627\u0646\u062c\u0627\u0645 \u06a9\u0627\u0631 \u0637\u0648\u0644\u0627\u0646\u06cc \u06cc\u0627 \u062a\u0645\u0627\u0633 \u0634\u0628\u06a9\u0647\u200c\u0627\u06cc \u062f\u0627\u062e\u0644 \u0627\u0648\u0646 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0628\u0647 \u0627\u0639\u0644\u0627\u0646 \u0646\u0627\u0642\u0635 \u06cc\u0627 \u0627\u0632\u062f\u0633\u062a\u200c\u0631\u0641\u062a\u0647 \u0645\u0646\u062c\u0631 \u0628\u0634\u0647. \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0647\u0627\u06cc \u0637\u0648\u0644\u0627\u0646\u06cc\u200c\u062a\u0631 \u0628\u0627\u06cc\u062f \u0627\u0632 WorkManager \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Notification Message \u06cc\u0627 Data Message\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">FCM \u062f\u0648 \u0645\u062f\u0644 \u0627\u0635\u0644\u06cc \u067e\u06cc\u0627\u0645 \u062f\u0627\u0631\u0647. <strong>Notification Message<\/strong> \u062f\u0627\u0631\u0627\u06cc \u0641\u06cc\u0644\u062f\u0647\u0627\u06cc \u0627\u0633\u062a\u0627\u0646\u062f\u0627\u0631\u062f\u06cc \u0645\u062b\u0644 <code>title<\/code> \u0648 <code>body<\/code> \u0647\u0633\u062a \u0648 \u062f\u0631 \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 \u067e\u0633\u200c\u0632\u0645\u06cc\u0646\u0647 \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u0647\u060c SDK \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0627\u0648\u0646 \u0631\u0648 \u062e\u0648\u062f\u06a9\u0627\u0631 \u062f\u0631 Notification Tray \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647. <strong>Data Message<\/strong> \u0641\u0642\u0637 \u0634\u0627\u0645\u0644 \u06a9\u0644\u06cc\u062f\u0647\u0627 \u0648 \u0645\u0642\u0627\u062f\u06cc\u0631\u06cc\u0647 \u06a9\u0647 \u062e\u0648\u062f\u0645\u0648\u0646 \u062a\u0639\u0631\u06cc\u0641 \u06a9\u0631\u062f\u0647\u200c\u0627\u06cc\u0645 \u0648 \u0645\u0633\u0626\u0648\u0644\u06cc\u062a \u067e\u0631\u062f\u0627\u0632\u0634 \u06a9\u0627\u0645\u0644\u0634 \u0628\u0627 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0633\u062a. \u0647\u0631 \u062f\u0648 \u0645\u062f\u0644 \u062f\u0631 \u062d\u0627\u0644\u062a \u0645\u0639\u0645\u0648\u0644 \u062d\u062f\u0627\u06a9\u062b\u0631 \u06f4\u06f0\u06f9\u06f6 \u0628\u0627\u06cc\u062a Payload \u062f\u0627\u0631\u0646\u061b \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 Push \u062c\u0627\u06cc \u0627\u0646\u062a\u0642\u0627\u0644 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0633\u0646\u06af\u06cc\u0646 \u06cc\u0627 \u062a\u0635\u0648\u06cc\u0631 \u0646\u06cc\u0633\u062a. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9 Notification Message \u0633\u0627\u062f\u0647 \u0686\u0646\u06cc\u0646 \u0633\u0627\u062e\u062a\u0627\u0631\u06cc \u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"message\": {\n    \"token\": \"DEVICE_TOKEN\",\n    \"notification\": {\n      \"title\": \"\u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a\",\n      \"body\": \"\u06cc\u06a9\u06cc \u0627\u0632 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0634\u0645\u0627 \u0627\u0631\u0632\u0627\u0646\u200c\u062a\u0631 \u0634\u062f\u0647.\"\n    }\n  }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;message&quot;<\/span><span style=\"color: #24292E\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;token&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;DEVICE_TOKEN&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;notification&quot;<\/span><span style=\"color: #24292E\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;title&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;\u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;body&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;\u06cc\u06a9\u06cc \u0627\u0632 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0634\u0645\u0627 \u0627\u0631\u0632\u0627\u0646\u200c\u062a\u0631 \u0634\u062f\u0647.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9 Data Message \u0628\u0647 \u0627\u06cc\u0646 \u0634\u06a9\u0644 \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"message\": {\n    \"token\": \"DEVICE_TOKEN\",\n    \"data\": {\n      \"type\": \"PRICE_DROP\",\n      \"eventId\": \"evt_986215\",\n      \"productId\": \"8472\",\n      \"title\": \"\u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a\",\n      \"body\": \"\u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644 \u0628\u0647 \u06f3\u06f9\u066c\u06f9\u06f0\u06f0\u066c\u06f0\u06f0\u06f0 \u062a\u0648\u0645\u0627\u0646 \u0631\u0633\u06cc\u062f.\"\n    }\n  }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;message&quot;<\/span><span style=\"color: #24292E\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;token&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;DEVICE_TOKEN&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;data&quot;<\/span><span style=\"color: #24292E\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;type&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;PRICE_DROP&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;eventId&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;evt_986215&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;productId&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;8472&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;title&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;\u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;body&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;\u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644 \u0628\u0647 \u06f3\u06f9\u066c\u06f9\u06f0\u06f0\u066c\u06f0\u06f0\u06f0 \u062a\u0648\u0645\u0627\u0646 \u0631\u0633\u06cc\u062f.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0641\u0627\u0648\u062a \u0627\u06cc\u0646 \u062f\u0648 \u0641\u0642\u0637 \u062f\u0631 \u0638\u0627\u0647\u0631 JSON \u0646\u06cc\u0633\u062a. \u0631\u0641\u062a\u0627\u0631 \u062f\u0631\u06cc\u0627\u0641\u062a \u067e\u06cc\u0627\u0645 \u0628\u0631 \u0627\u0633\u0627\u0633 \u0648\u0636\u0639\u06cc\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0648\u0642\u062a\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 Foreground \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u0647\u060c \u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc Notification\u060c Data \u0648 \u062a\u0631\u06a9\u06cc\u0628\u06cc \u0648\u0627\u0631\u062f <code>onMessageReceived()<\/code> \u0645\u06cc\u0634\u0646. \u0627\u0645\u0627 \u0648\u0642\u062a\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 Background \u0642\u0631\u0627\u0631 \u06af\u0631\u0641\u062a\u0647\u060c Notification Message \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0628\u0647\u200c\u0635\u0648\u0631\u062a \u062e\u0648\u062f\u06a9\u0627\u0631 \u062a\u0648\u0633\u0637 \u0633\u06cc\u0633\u062a\u0645 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647 \u0648 <code>onMessageReceived()<\/code> \u0628\u0631\u0627\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0627\u0648\u0646 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0646\u0645\u06cc\u0634\u0647. \u0627\u06af\u0631 \u067e\u06cc\u0627\u0645 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0628\u062e\u0634 <code>notification<\/code> \u0648 <code>data<\/code> \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u062f\u0631 \u062d\u0627\u0644\u062a Background \u0627\u0639\u0644\u0627\u0646 \u062a\u0648\u0633\u0637 \u0633\u06cc\u0633\u062a\u0645 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647 \u0648 Data \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0648\u0642\u062a\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0644\u0645\u0633 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0627\u0632 \u0637\u0631\u06cc\u0642 Intent \u0648\u0631\u0648\u062f\u06cc Activity \u062f\u0631 \u062f\u0633\u062a\u0631\u0633 \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u06cc\u0646 \u0631\u0641\u062a\u0627\u0631 \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u0628\u0631\u0627\u06cc \u06cc\u06a9 \u0633\u06cc\u0633\u062a\u0645 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc\u060c \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0628\u06cc\u200c\u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0632 \u067e\u06cc\u0627\u0645 \u062a\u0631\u06a9\u06cc\u0628\u06cc \u062f\u0631\u062f\u0633\u0631\u0633\u0627\u0632 \u0628\u0634\u0647. \u0645\u0645\u06a9\u0646\u0647 \u062f\u0631 Foreground \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0628\u0627 \u06a9\u062f \u062e\u0648\u062f\u0645\u0648\u0646 \u0628\u0633\u0627\u0632\u06cc\u0645\u060c \u0627\u0645\u0627 \u062f\u0631 Background \u0638\u0627\u0647\u0631 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 FCM \u062a\u0639\u06cc\u06cc\u0646 \u06a9\u0646\u0647. \u062f\u0631 \u0646\u062a\u06cc\u062c\u0647 Channel\u060c \u0622\u06cc\u06a9\u0648\u0646\u060c Group\u060c \u0631\u0641\u062a\u0627\u0631 \u06a9\u0644\u06cc\u06a9 \u0648 \u0645\u0646\u0637\u0642 \u062d\u0630\u0641 \u0627\u0639\u0644\u0627\u0646 \u062f\u0631 \u062f\u0648 \u0648\u0636\u0639\u06cc\u062a \u0645\u062a\u0641\u0627\u0648\u062a \u0645\u06cc\u0634\u0647. \u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u06a9\u0647 \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc\u0645 \u0631\u0648\u06cc \u0638\u0627\u0647\u0631\u060c \u0645\u0642\u0635\u062f\u060c \u06af\u0631\u0648\u0647\u200c\u0628\u0646\u062f\u06cc\u060c \u0634\u0646\u0627\u0633\u0647 \u0627\u0639\u0644\u0627\u0646 \u0648 \u0645\u0646\u0637\u0642 \u062a\u06a9\u0631\u0627\u0631\u06cc \u0646\u0628\u0648\u062f\u0646 \u06a9\u0646\u062a\u0631\u0644 \u06a9\u0627\u0645\u0644 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645\u060c Data Message \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u0646\u0627\u0633\u0628\u200c\u062a\u0631\u06cc\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0644\u0628\u062a\u0647 Data Message \u0628\u0647 \u0645\u0639\u0646\u06cc \u062a\u0636\u0645\u06cc\u0646 \u0627\u062c\u0631\u0627\u06cc \u0646\u0627\u0645\u062d\u062f\u0648\u062f \u06a9\u062f \u062f\u0631 \u067e\u0633\u200c\u0632\u0645\u06cc\u0646\u0647 \u0646\u06cc\u0633\u062a. \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0647\u0645\u0686\u0646\u0627\u0646 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a\u200c\u0647\u0627\u06cc Background \u0648 Doze \u0631\u0648 \u0627\u0639\u0645\u0627\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0628\u0627\u06cc\u062f Payload \u0628\u0631\u0627\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0641\u0648\u0631\u06cc \u0627\u0639\u0644\u0627\u0646 \u06a9\u0627\u0641\u06cc \u0628\u0627\u0634\u0647 \u0648 \u06a9\u0627\u0631\u0647\u0627\u06cc \u0633\u0646\u06af\u06cc\u0646\u200c\u062a\u0631 \u0628\u0647 WorkManager \u0633\u067e\u0631\u062f\u0647 \u0628\u0634\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0642\u0631\u0627\u0631\u062f\u0627\u062f \u067e\u06cc\u0627\u0645 \u0631\u0648 \u0642\u0628\u0644 \u0627\u0632 \u0646\u0648\u0634\u062a\u0646 \u06a9\u062f \u0637\u0631\u0627\u062d\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u0627\u06cc\u0646\u0647 \u06a9\u0647 Backend \u0647\u0631 \u0628\u0627\u0631 \u0686\u0646\u062f \u0641\u06cc\u0644\u062f \u062a\u0635\u0627\u062f\u0641\u06cc \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u0647 \u0648 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0647\u0645 \u0628\u0627 \u0645\u062c\u0645\u0648\u0639\u0647\u200c\u0627\u06cc \u0627\u0632 <code>if<\/code>\u0647\u0627\u06cc \u067e\u0631\u0627\u06a9\u0646\u062f\u0647 \u062d\u062f\u0633 \u0628\u0632\u0646\u0647 \u0628\u0627 \u067e\u06cc\u0627\u0645 \u0686\u0647 \u06a9\u0627\u0631\u06cc \u0628\u0627\u06cc\u062f \u0627\u0646\u062c\u0627\u0645 \u0628\u062f\u0647. Push \u0647\u0645 \u0645\u062b\u0644 \u0647\u0631 API \u062f\u06cc\u06af\u0647 \u0628\u0647 \u06cc\u06a9 \u0642\u0631\u0627\u0631\u062f\u0627\u062f \u067e\u0627\u06cc\u062f\u0627\u0631 \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u0647. \u0628\u0647\u062a\u0631\u0647 \u0647\u0645\u0647 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0633\u0627\u062e\u062a\u0627\u0631 \u0645\u0634\u062a\u0631\u06a9\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"type\": \"PRICE_DROP\",\n  \"schemaVersion\": \"1\",\n  \"eventId\": \"evt_986215\",\n  \"entityId\": \"8472\",\n  \"title\": \"\u0642\u06cc\u0645\u062a \u0644\u067e\u200c\u062a\u0627\u067e \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\",\n  \"body\": \"\u0642\u06cc\u0645\u062a \u062c\u062f\u06cc\u062f \u06f3\u06f9\u066c\u06f9\u06f0\u06f0\u066c\u06f0\u06f0\u06f0 \u062a\u0648\u0645\u0627\u0646 \u0627\u0633\u062a.\",\n  \"channel\": \"price_alerts\",\n  \"route\": \"product\/8472\",\n  \"imageUrl\": \"https:\/\/cdn.gheimatban.com\/products\/8472.jpg\",\n  \"createdAt\": \"2026-07-19T18:25:00Z\"\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;type&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;PRICE_DROP&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;schemaVersion&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;1&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;eventId&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;evt_986215&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;entityId&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;8472&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;title&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;\u0642\u06cc\u0645\u062a \u0644\u067e\u200c\u062a\u0627\u067e \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;body&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;\u0642\u06cc\u0645\u062a \u062c\u062f\u06cc\u062f \u06f3\u06f9\u066c\u06f9\u06f0\u06f0\u066c\u06f0\u06f0\u06f0 \u062a\u0648\u0645\u0627\u0646 \u0627\u0633\u062a.&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;channel&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;price_alerts&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;route&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;product\/8472&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;imageUrl&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;https:\/\/cdn.gheimatban.com\/products\/8472.jpg&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;createdAt&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;2026-07-19T18:25:00Z&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><code>type<\/code> \u0645\u0634\u062e\u0635 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0686\u0647 \u0627\u062a\u0641\u0627\u0642\u06cc \u0627\u0641\u062a\u0627\u062f\u0647. <code>schemaVersion<\/code> \u0646\u0633\u062e\u0647 \u0642\u0631\u0627\u0631\u062f\u0627\u062f \u067e\u06cc\u0627\u0645 \u0631\u0648 \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u0647 \u062a\u0627 \u0627\u06af\u0631 \u0628\u0639\u062f\u0627\u064b \u0633\u0627\u062e\u062a\u0627\u0631 Payload \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f\u060c \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u0642\u062f\u06cc\u0645\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645\u0686\u0646\u0627\u0646 \u0642\u0627\u0628\u0644 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0628\u0627\u0634\u0646. <code>eventId<\/code> \u0634\u0646\u0627\u0633\u0647 \u06cc\u06a9\u062a\u0627\u06cc \u0631\u0648\u06cc\u062f\u0627\u062f\u0647 \u0648 \u0628\u0631\u0627\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u0646\u0645\u0627\u06cc\u0634 \u062a\u06a9\u0631\u0627\u0631\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647. <code>entityId<\/code> \u0634\u0646\u0627\u0633\u0647 \u0645\u0648\u062c\u0648\u062f\u06cc\u062a \u0645\u0631\u062a\u0628\u0637\u0647\u061b \u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644 \u0634\u0646\u0627\u0633\u0647 \u0645\u062d\u0635\u0648\u0644. <code>channel<\/code> \u062a\u0639\u06cc\u06cc\u0646 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0627\u0639\u0644\u0627\u0646 \u0628\u0627\u06cc\u062f \u062f\u0631 \u06a9\u062f\u0648\u0645 Notification Channel \u0642\u0631\u0627\u0631 \u0628\u06af\u06cc\u0631\u0647 \u0648 <code>route<\/code> \u0645\u0642\u0635\u062f \u062f\u0627\u062e\u0644\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0645\u0634\u062e\u0635 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u062c\u0648\u062f <code>title<\/code> \u0648 <code>body<\/code> \u062f\u0627\u062e\u0644 Push \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u0628\u0631\u0627\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0627\u0648\u0644\u06cc\u0647 \u0628\u0647 \u0634\u0628\u06a9\u0647 \u0648\u0627\u0628\u0633\u062a\u0647 \u0646\u0628\u0627\u0634\u06cc\u0645. \u062f\u0631 \u0645\u0642\u0627\u0628\u0644\u060c \u0646\u0628\u0627\u06cc\u062f \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u06cc\u0627 \u06a9\u0627\u0645\u0644 \u0631\u0648 \u062f\u0627\u062e\u0644 Payload \u0642\u0631\u0627\u0631 \u0628\u062f\u06cc\u0645. \u0627\u0631\u062a\u0628\u0627\u0637 FCM \u0631\u0645\u0632\u0646\u06af\u0627\u0631\u06cc\u200c\u0634\u062f\u0647\u200c\u0633\u062a\u060c \u0627\u0645\u0627 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627 \u0628\u0647\u200c\u0635\u0648\u0631\u062a \u067e\u06cc\u0634\u200c\u0641\u0631\u0636 End-to-End Encrypted \u0646\u06cc\u0633\u062a\u0646\u061b \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 Token \u0648\u0631\u0648\u062f\u060c \u0631\u0645\u0632\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u067e\u0631\u062f\u0627\u062e\u062a \u06cc\u0627 \u062f\u0627\u062f\u0647\u200c\u0627\u06cc \u06a9\u0647 \u0646\u0645\u0627\u06cc\u0634 \u0627\u0648\u0646 \u0631\u0648\u06cc \u0635\u0641\u062d\u0647 \u0642\u0641\u0644 \u062e\u0637\u0631\u0646\u0627\u06a9\u0647 \u0646\u0628\u0627\u06cc\u062f \u062f\u0627\u062e\u0644 Push \u0642\u0631\u0627\u0631 \u0628\u06af\u06cc\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0633\u0645\u062a \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u06cc\u06a9 \u0645\u062f\u0644 \u0645\u0634\u062e\u0635 \u0628\u0631\u0627\u06cc Payload \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class PushPayload(\n    val type: PushType,\n    val schemaVersion: Int,\n    val eventId: String,\n    val entityId: Long?,\n    val title: String,\n    val body: String,\n    val channel: String,\n    val route: String?,\n    val imageUrl: String?,\n    val createdAt: Instant?\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> type: <\/span><span style=\"color: #6F42C1\">PushType<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> schemaVersion: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> eventId: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> entityId: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">?,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> title: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> body: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> channel: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> route: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">?,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> imageUrl: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">?,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> createdAt: <\/span><span style=\"color: #6F42C1\">Instant<\/span><span style=\"color: #24292E\">?<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0648\u0639 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627 \u0631\u0648 \u0647\u0645 \u0628\u0647\u200c\u062c\u0627\u06cc String\u0647\u0627\u06cc \u067e\u0631\u0627\u06a9\u0646\u062f\u0647\u060c \u062f\u0631 \u06cc\u06a9 Enum \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>enum class PushType {\n    PRICE_DROP,\n    PRICE_TARGET_REACHED,\n    PRODUCT_UNAVAILABLE,\n    PRODUCT_AVAILABLE,\n    ACCOUNT_WARNING,\n    GENERAL_ANNOUNCEMENT,\n    UNKNOWN\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">enum<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushType<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    PRICE_DROP,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    PRICE_TARGET_REACHED,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    PRODUCT_UNAVAILABLE,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    PRODUCT_AVAILABLE,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ACCOUNT_WARNING,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    GENERAL_ANNOUNCEMENT,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    UNKNOWN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9 Parser \u0645\u0631\u06a9\u0632\u06cc \u0645\u0633\u0626\u0648\u0644 \u062a\u0628\u062f\u06cc\u0644 Map \u062f\u0631\u06cc\u0627\u0641\u062a\u06cc \u0628\u0647 \u0645\u062f\u0644 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class PushPayloadParser {\n\n    fun parse(\n        data: Map&lt;String, String>\n    ): PushPayload? {\n        val eventId =\n            data&#91;\"eventId\"&#93;\n                ?.takeIf { it.isNotBlank() }\n                ?: return null\n\n        val title =\n            data&#91;\"title\"&#93;\n                ?.takeIf { it.isNotBlank() }\n                ?: return null\n\n        val body =\n            data&#91;\"body\"&#93;\n                ?.takeIf { it.isNotBlank() }\n                ?: return null\n\n        val type = runCatching {\n            PushType.valueOf(\n                data&#91;\"type\"&#93;.orEmpty()\n            )\n        }.getOrDefault(\n            PushType.UNKNOWN\n        )\n\n        val createdAt = runCatching {\n            data&#91;\"createdAt\"&#93;\n                ?.let(Instant::parse)\n        }.getOrNull()\n\n        return PushPayload(\n            type = type,\n            schemaVersion =\n                data&#91;\"schemaVersion\"&#93;\n                    ?.toIntOrNull()\n                    ?: 1,\n            eventId = eventId,\n            entityId =\n                data&#91;\"entityId\"&#93;\n                    ?.toLongOrNull(),\n            title = title,\n            body = body,\n            channel =\n                data&#91;\"channel\"&#93;\n                    ?: NotificationChannels.GENERAL,\n            route = data&#91;\"route\"&#93;,\n            imageUrl = data&#91;\"imageUrl\"&#93;,\n            createdAt = createdAt\n        )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushPayloadParser<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">parse<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #6F42C1\">Map<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><span style=\"color: #24292E\">? {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> eventId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">&#91;<\/span><span style=\"color: #032F62\">&quot;eventId&quot;<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?.<\/span><span style=\"color: #6F42C1\">takeIf<\/span><span style=\"color: #24292E\"> { it.<\/span><span style=\"color: #6F42C1\">isNotBlank<\/span><span style=\"color: #24292E\">() }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> title <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">&#91;<\/span><span style=\"color: #032F62\">&quot;title&quot;<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?.<\/span><span style=\"color: #6F42C1\">takeIf<\/span><span style=\"color: #24292E\"> { it.<\/span><span style=\"color: #6F42C1\">isNotBlank<\/span><span style=\"color: #24292E\">() }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> body <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">&#91;<\/span><span style=\"color: #032F62\">&quot;body&quot;<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?.<\/span><span style=\"color: #6F42C1\">takeIf<\/span><span style=\"color: #24292E\"> { it.<\/span><span style=\"color: #6F42C1\">isNotBlank<\/span><span style=\"color: #24292E\">() }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> type <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">runCatching<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.<\/span><span style=\"color: #6F42C1\">valueOf<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">&#91;<\/span><span style=\"color: #032F62\">&quot;type&quot;<\/span><span style=\"color: #24292E\">&#93;.<\/span><span style=\"color: #6F42C1\">orEmpty<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }.<\/span><span style=\"color: #6F42C1\">getOrDefault<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.UNKNOWN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> createdAt <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">runCatching<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">&#91;<\/span><span style=\"color: #032F62\">&quot;createdAt&quot;<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?.<\/span><span style=\"color: #6F42C1\">let<\/span><span style=\"color: #24292E\">(Instant::<\/span><span style=\"color: #6F42C1\">parse<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }.<\/span><span style=\"color: #6F42C1\">getOrNull<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            type <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> type,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            schemaVersion <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">&#91;<\/span><span style=\"color: #032F62\">&quot;schemaVersion&quot;<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ?.<\/span><span style=\"color: #6F42C1\">toIntOrNull<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ?: <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            eventId <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> eventId,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            entityId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">&#91;<\/span><span style=\"color: #032F62\">&quot;entityId&quot;<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ?.<\/span><span style=\"color: #6F42C1\">toLongOrNull<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            title <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> title,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            body <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> body,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            channel <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">&#91;<\/span><span style=\"color: #032F62\">&quot;channel&quot;<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ?: NotificationChannels.GENERAL,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            route <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">&#91;<\/span><span style=\"color: #032F62\">&quot;route&quot;<\/span><span style=\"color: #24292E\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            imageUrl <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">&#91;<\/span><span style=\"color: #032F62\">&quot;imageUrl&quot;<\/span><span style=\"color: #24292E\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            createdAt <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> createdAt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0627 \u0627\u06cc\u0646 \u0637\u0631\u0627\u062d\u06cc\u060c <code>FirebaseMessagingService<\/code> \u0645\u0633\u0626\u0648\u0644 \u062a\u0641\u0633\u06cc\u0631 \u062c\u0632\u0626\u06cc \u062a\u0645\u0627\u0645 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627 \u0646\u06cc\u0633\u062a. \u0633\u0631\u0648\u06cc\u0633 \u0641\u0642\u0637 \u067e\u06cc\u0627\u0645 \u0631\u0648 \u062a\u062d\u0648\u06cc\u0644 Parser \u0648 Router \u0645\u06cc\u062f\u0647 \u0648 \u0647\u0631 \u0628\u062e\u0634 \u0645\u0633\u0626\u0648\u0644\u06cc\u062a \u0645\u0634\u062e\u0635 \u062e\u0648\u062f\u0634 \u0631\u0648 \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0633\u0627\u062e\u062a FirebaseMessagingService \u062d\u0631\u0641\u0647\u200c\u0627\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Service \u0627\u0635\u0644\u06cc \u0631\u0648 \u062f\u0631 Manifest \u062b\u0628\u062a \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;service\n    android:name=\".push.GheimatBanMessagingService\"\n    android:exported=\"false\">\n\n    &lt;intent-filter>\n        &lt;action\n            android:name=\"com.google.firebase.MESSAGING_EVENT\" \/>\n    &lt;\/intent-filter>\n\n&lt;\/service>\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">service<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    android:<\/span><span style=\"color: #6F42C1\">name<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #032F62\">&quot;.push.GheimatBanMessagingService&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    android:<\/span><span style=\"color: #6F42C1\">exported<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #032F62\">&quot;false&quot;<\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">intent<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">filter<\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">action<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            android:<\/span><span style=\"color: #6F42C1\">name<\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #032F62\">&quot;com.google.firebase.MESSAGING_EVENT&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">\/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">&lt;\/<\/span><span style=\"color: #24292E\">intent<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">filter<\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">&lt;\/<\/span><span style=\"color: #24292E\">service<\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 Service \u0631\u0648 \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class GheimatBanMessagingService :\n    FirebaseMessagingService() {\n\n    private val payloadParser by lazy {\n        PushPayloadParser()\n    }\n\n    private val pushHandler by lazy {\n        PushHandler(\n            context = applicationContext\n        )\n    }\n\n    override fun onMessageReceived(\n        message: RemoteMessage\n    ) {\n        super.onMessageReceived(message)\n\n        val payload =\n            payloadParser.parse(message.data)\n                ?: return\n\n        pushHandler.handle(\n            payload = payload,\n            originalPriority =\n                message.originalPriority,\n            deliveredPriority =\n                message.priority\n        )\n    }\n\n    override fun onNewToken(\n        token: String\n    ) {\n        super.onNewToken(token)\n\n        PushTokenSyncScheduler.enqueue(\n            context = applicationContext,\n            token = token\n        )\n    }\n\n    override fun onDeletedMessages() {\n        super.onDeletedMessages()\n\n        FullSyncScheduler.enqueue(\n            applicationContext\n        )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">GheimatBanMessagingService<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">FirebaseMessagingService<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> payloadParser <\/span><span style=\"color: #D73A49\">by<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">lazy<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">PushPayloadParser<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> pushHandler <\/span><span style=\"color: #D73A49\">by<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">lazy<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">PushHandler<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            context <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> applicationContext<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onMessageReceived<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        message: <\/span><span style=\"color: #6F42C1\">RemoteMessage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onMessageReceived<\/span><span style=\"color: #24292E\">(message)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> payload <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            payloadParser.<\/span><span style=\"color: #6F42C1\">parse<\/span><span style=\"color: #24292E\">(message.<\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?: <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        pushHandler.<\/span><span style=\"color: #6F42C1\">handle<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            payload <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> payload,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            originalPriority <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                message.originalPriority,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            deliveredPriority <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                message.priority<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onNewToken<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        token: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onNewToken<\/span><span style=\"color: #24292E\">(token)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        PushTokenSyncScheduler.<\/span><span style=\"color: #6F42C1\">enqueue<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            context <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> applicationContext,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            token <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> token<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onDeletedMessages<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onDeletedMessages<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        FullSyncScheduler.<\/span><span style=\"color: #6F42C1\">enqueue<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            applicationContext<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><code>onNewToken()<\/code> \u0641\u0642\u0637 \u0632\u0645\u0627\u0646 \u0646\u0635\u0628 \u0627\u0648\u0644\u06cc\u0647 \u0627\u062c\u0631\u0627 \u0646\u0645\u06cc\u0634\u0647. Token \u0645\u0645\u06a9\u0646\u0647 \u0628\u0631 \u0627\u062b\u0631 \u0628\u0627\u0632\u06cc\u0627\u0628\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648\u06cc \u062f\u0633\u062a\u06af\u0627\u0647 \u062c\u062f\u06cc\u062f\u060c \u062d\u0630\u0641 \u0648 \u0646\u0635\u0628 \u062f\u0648\u0628\u0627\u0631\u0647\u060c \u067e\u0627\u06a9 \u0634\u062f\u0646 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u06cc\u0627 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u062f\u0627\u062e\u0644\u06cc \u0633\u0631\u0648\u06cc\u0633 \u0639\u0648\u0636 \u0628\u0634\u0647. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 Token \u0631\u0648 \u06cc\u06a9 \u0645\u0642\u062f\u0627\u0631 \u062b\u0627\u0628\u062a \u0648 \u062f\u0627\u0626\u0645\u06cc \u062f\u0631 \u0646\u0638\u0631 \u0646\u0645\u06cc\u200c\u06af\u06cc\u0631\u06cc\u0645. \u0647\u0631 \u0628\u0627\u0631 Token \u062c\u062f\u06cc\u062f \u0627\u06cc\u062c\u0627\u062f \u0634\u062f \u0628\u0627\u06cc\u062f \u0627\u0648\u0646 \u0631\u0648 \u0628\u0647 Backend \u0645\u0646\u062a\u0642\u0644 \u06a9\u0646\u06cc\u0645. Firebase \u0647\u0645 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0633\u0631\u0648\u0631 \u0632\u0645\u0627\u0646 \u062b\u0628\u062a \u06cc\u0627 \u0622\u062e\u0631\u06cc\u0646 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc Registration \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0631\u0647 \u0648 Registration\u0647\u0627\u06cc \u0642\u062f\u06cc\u0645\u06cc \u06cc\u0627 \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u0631\u0648 \u067e\u0627\u06a9\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>onDeletedMessages()<\/code> \u0632\u0645\u0627\u0646\u06cc \u0627\u0647\u0645\u06cc\u062a \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u06a9\u0647 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc \u0630\u062e\u06cc\u0631\u0647\u200c\u0634\u062f\u0647 \u062f\u0633\u062a\u06af\u0627\u0647 \u0627\u0632 \u062d\u062f \u0642\u0627\u0628\u0644 \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0639\u0628\u0648\u0631 \u06a9\u0646\u0646 \u06cc\u0627 FCM \u0646\u062a\u0648\u0646\u0647 \u0647\u0645\u0647 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627 \u0631\u0648 \u062a\u062d\u0648\u06cc\u0644 \u0628\u062f\u0647. \u062a\u0631\u062a\u06cc\u0628 \u062a\u062d\u0648\u06cc\u0644 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627 \u0647\u0645 \u062a\u0636\u0645\u06cc\u0646\u200c\u0634\u062f\u0647 \u0646\u06cc\u0633\u062a. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 Push \u0646\u0628\u0627\u06cc\u062f \u062a\u0646\u0647\u0627 \u0645\u0646\u0628\u0639 \u062d\u0642\u06cc\u0642\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627\u0634\u0647\u061b \u0648\u0642\u062a\u06cc \u0627\u062d\u062a\u0645\u0627\u0644 \u0627\u0632\u062f\u0633\u062a\u200c\u0631\u0641\u062a\u0646 \u067e\u06cc\u0627\u0645 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647 \u0628\u0627\u06cc\u062f Full Sync \u0627\u0632 \u0633\u0631\u0648\u0631 \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Token \u0645\u062a\u0639\u0644\u0642 \u0628\u0647 \u062f\u0633\u062a\u06af\u0627\u0647\u0647\u060c \u0646\u0647 \u06a9\u0627\u0631\u0628\u0631<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0627\u06cc\u0645\u0627\u0646 \u0628\u0627 \u06cc\u06a9 \u062d\u0633\u0627\u0628 \u0631\u0648\u06cc \u0633\u0647 \u062f\u0633\u062a\u06af\u0627\u0647 \u0648\u0627\u0631\u062f \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0634\u062f\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>User 42\n\u251c\u2500\u2500 Phone A \u2192 Token A\n\u251c\u2500\u2500 Phone B \u2192 Token B\n\u2514\u2500\u2500 Tablet \u2192 Token C\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u0631\u0648\u0631 \u0646\u0628\u0627\u06cc\u062f \u062f\u0627\u062e\u0644 \u062c\u062f\u0648\u0644 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0641\u0642\u0637 \u06cc\u06a9 \u0633\u062a\u0648\u0646 \u0628\u0627 \u0646\u0627\u0645 <code>fcm_token<\/code> \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u061b \u0686\u0648\u0646 \u0648\u0631\u0648\u062f \u0627\u0632 \u062f\u0633\u062a\u06af\u0627\u0647 \u062c\u062f\u06cc\u062f Token \u0642\u0628\u0644\u06cc \u0631\u0648 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u0627\u0639\u0644\u0627\u0646 \u0641\u0642\u0637 \u0628\u0647 \u0622\u062e\u0631\u06cc\u0646 \u062f\u0633\u062a\u06af\u0627\u0647 \u0645\u06cc\u200c\u0631\u0633\u0647. \u0645\u062f\u0644 \u062f\u0631\u0633\u062a \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0647\u0631 \u0646\u0645\u0648\u0646\u0647 \u0646\u0635\u0628\u200c\u0634\u062f\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u06cc\u06a9 Registration \u0645\u0633\u062a\u0642\u0644 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>push_registrations\n\nid\nuser_id\ninstallation_id\nfcm_token\nplatform\napp_version\ndevice_model\nnotifications_enabled\nlast_seen_at\ncreated_at\nupdated_at\nrevoked_at\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0633\u0645\u062a \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u060c Token \u0648 \u0645\u0634\u062e\u0635\u0627\u062a \u0644\u0627\u0632\u0645 \u0631\u0648 \u0628\u0647 API \u0645\u06cc\u200c\u0641\u0631\u0633\u062a\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class RegisterPushTokenRequest(\n    val token: String,\n    val installationId: String,\n    val platform: String = \"android\",\n    val appVersion: String,\n    val deviceModel: String,\n    val notificationsEnabled: Boolean\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">RegisterPushTokenRequest<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> token: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> installationId: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> platform: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;android&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> appVersion: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> deviceModel: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> notificationsEnabled: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface PushApi {\n\n    @POST(\"push\/registrations\")\n    suspend fun register(\n        @Body request:\n            RegisterPushTokenRequest\n    )\n\n    @DELETE(\n        \"push\/registrations\/{installationId}\"\n    )\n    suspend fun unregister(\n        @Path(\"installationId\")\n        installationId: String\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushApi<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@POST<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;push\/registrations&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">register<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Body<\/span><span style=\"color: #24292E\"> request:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            RegisterPushTokenRequest<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@DELETE<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;push\/registrations\/{installationId}&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">unregister<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Path<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;installationId&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        installationId: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0639\u0645\u0644\u06cc\u0627\u062a \u062b\u0628\u062a \u0628\u0627\u06cc\u062f Upsert \u0628\u0627\u0634\u0647\u061b \u06cc\u0639\u0646\u06cc \u0627\u06af\u0631 Installation \u0642\u0628\u0644\u0627\u064b \u062b\u0628\u062a \u0634\u062f\u0647\u060c Token \u0648 \u0632\u0645\u0627\u0646 \u0622\u062e\u0631\u06cc\u0646 \u0641\u0639\u0627\u0644\u06cc\u062a \u0627\u0648\u0646 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0628\u0634\u0647 \u0648 \u0627\u06af\u0631 \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u0647\u060c \u0631\u06a9\u0648\u0631\u062f \u062a\u0627\u0632\u0647 \u0633\u0627\u062e\u062a\u0647 \u0628\u0634\u0647. Token \u0646\u0628\u0627\u06cc\u062f \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 \u0634\u0646\u0627\u0633\u0647 \u0627\u0635\u0644\u06cc \u06a9\u0627\u0631\u0628\u0631 \u06cc\u0627 \u0631\u0627\u0647 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0628\u0634\u0647. Token \u0641\u0642\u0637 \u0622\u062f\u0631\u0633 \u0627\u0631\u0633\u0627\u0644 \u067e\u06cc\u0627\u0645 \u0628\u0647 \u06cc\u06a9 \u0646\u0645\u0648\u0646\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0633\u062a \u0648 \u0645\u0645\u06a9\u0646\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc Sync \u0645\u0637\u0645\u0626\u0646 Token \u0627\u0632 WorkManager \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645\u061b \u0686\u0648\u0646 \u0645\u0645\u06a9\u0646\u0647 <code>onNewToken()<\/code> \u0632\u0645\u0627\u0646\u06cc \u0627\u062c\u0631\u0627 \u0628\u0634\u0647 \u06a9\u0647 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u062f\u0631 \u062f\u0633\u062a\u0631\u0633 \u0646\u06cc\u0633\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>object PushTokenSyncScheduler {\n\n    private const val TOKEN_KEY =\n        \"push_token\"\n\n    fun enqueue(\n        context: Context,\n        token: String\n    ) {\n        val inputData = workDataOf(\n            TOKEN_KEY to token\n        )\n\n        val constraints =\n            Constraints.Builder()\n                .setRequiredNetworkType(\n                    NetworkType.CONNECTED\n                )\n                .build()\n\n        val request =\n            OneTimeWorkRequestBuilder&lt;\n                PushTokenSyncWorker\n            >()\n                .setInputData(inputData)\n                .setConstraints(constraints)\n                .setBackoffCriteria(\n                    BackoffPolicy.EXPONENTIAL,\n                    30,\n                    TimeUnit.SECONDS\n                )\n                .build()\n\n        WorkManager\n            .getInstance(context)\n            .enqueueUniqueWork(\n                \"sync_push_token\",\n                ExistingWorkPolicy.REPLACE,\n                request\n            )\n    }\n\n    fun readToken(\n        workerParameters: WorkerParameters\n    ): String? {\n        return workerParameters\n            .inputData\n            .getString(TOKEN_KEY)\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushTokenSyncScheduler<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> TOKEN_KEY <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;push_token&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">enqueue<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        context: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        token: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> inputData <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">workDataOf<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TOKEN_KEY to token<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> constraints <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Constraints.<\/span><span style=\"color: #6F42C1\">Builder<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setRequiredNetworkType<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    NetworkType.CONNECTED<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> request <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            OneTimeWorkRequestBuilder<\/span><span style=\"color: #D73A49\">&lt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                PushTokenSyncWorker<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setInputData<\/span><span style=\"color: #24292E\">(inputData)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setConstraints<\/span><span style=\"color: #24292E\">(constraints)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setBackoffCriteria<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    BackoffPolicy.EXPONENTIAL,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #005CC5\">30<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    TimeUnit.SECONDS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        WorkManager<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">getInstance<\/span><span style=\"color: #24292E\">(context)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">enqueueUniqueWork<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;sync_push_token&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ExistingWorkPolicy.REPLACE,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                request<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">readToken<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        workerParameters: <\/span><span style=\"color: #6F42C1\">WorkerParameters<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">? {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> workerParameters<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .inputData<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">getString<\/span><span style=\"color: #24292E\">(TOKEN_KEY)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Worker:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class PushTokenSyncWorker(\n    appContext: Context,\n    workerParameters: WorkerParameters,\n    private val pushRepository:\n        PushRepository\n) : CoroutineWorker(\n    appContext,\n    workerParameters\n) {\n\n    override suspend fun doWork():\n        Result {\n\n        val token =\n            PushTokenSyncScheduler\n                .readToken(\n                    workerParameters\n                )\n                ?: return Result.failure()\n\n        return try {\n            pushRepository\n                .registerToken(token)\n\n            Result.success()\n        } catch (\n            exception: IOException\n        ) {\n            Result.retry()\n        } catch (\n            exception: HttpException\n        ) {\n            if (\n                exception.code() in\n                500..599\n            ) {\n                Result.retry()\n            } else {\n                Result.failure()\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushTokenSyncWorker<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    appContext: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    workerParameters: <\/span><span style=\"color: #6F42C1\">WorkerParameters<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> pushRepository:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        PushRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">CoroutineWorker<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    appContext,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    workerParameters<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">doWork<\/span><span style=\"color: #24292E\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">Result<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> token <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushTokenSyncScheduler<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">readToken<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    workerParameters<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> Result.<\/span><span style=\"color: #6F42C1\">failure<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            pushRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">registerToken<\/span><span style=\"color: #24292E\">(token)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Result.<\/span><span style=\"color: #6F42C1\">success<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        } <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            exception: <\/span><span style=\"color: #6F42C1\">IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Result.<\/span><span style=\"color: #6F42C1\">retry<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        } <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            exception: <\/span><span style=\"color: #6F42C1\">HttpException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                exception.<\/span><span style=\"color: #6F42C1\">code<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #005CC5\">500<\/span><span style=\"color: #D73A49\">..<\/span><span style=\"color: #005CC5\">599<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Result.<\/span><span style=\"color: #6F42C1\">retry<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Result.<\/span><span style=\"color: #6F42C1\">failure<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 Login \u0647\u0645 \u0628\u0627\u06cc\u062f Token \u0641\u0639\u0644\u06cc \u0631\u0648 \u0628\u0627 \u062d\u0633\u0627\u0628 \u06a9\u0627\u0631\u0628\u0631 \u0645\u0631\u062a\u0628\u0637 \u06a9\u0646\u06cc\u0645. \u0627\u06af\u0631 <code>onNewToken()<\/code> \u0642\u0628\u0644 \u0627\u0632 \u0648\u0631\u0648\u062f \u0627\u062c\u0631\u0627 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 Token \u0631\u0648\u06cc \u062f\u0633\u062a\u06af\u0627\u0647 \u0645\u0648\u062c\u0648\u062f \u0628\u0627\u0634\u0647 \u0627\u0645\u0627 \u0647\u0646\u0648\u0632 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0628\u0631\u0627\u06cc \u0627\u0648\u0646 \u062b\u0628\u062a \u0646\u0634\u062f\u0647 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun syncCurrentToken() {\n    val token =\n        FirebaseMessaging\n            .getInstance()\n            .token\n            .await()\n\n    registerToken(token)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">syncCurrentToken<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> token <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        FirebaseMessaging<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">getInstance<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .token<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">await<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">registerToken<\/span><span style=\"color: #24292E\">(token)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 Logout \u0647\u0645 \u0628\u0627\u06cc\u062f Registration \u0647\u0645\u0648\u0646 \u062f\u0633\u062a\u06af\u0627\u0647 \u0627\u0632 \u062d\u0633\u0627\u0628 \u0642\u0628\u0644\u06cc \u062c\u062f\u0627 \u0628\u0634\u0647. \u062d\u0630\u0641 \u0645\u062d\u0644\u06cc Token \u0628\u0647\u200c\u062a\u0646\u0647\u0627\u06cc\u06cc \u06a9\u0627\u0641\u06cc \u0646\u06cc\u0633\u062a\u061b Backend \u0647\u0645 \u0628\u0627\u06cc\u062f \u0628\u062f\u0648\u0646\u0647 \u0627\u06cc\u0646 \u062f\u0633\u062a\u06af\u0627\u0647 \u062f\u06cc\u06af\u0647 \u0645\u062a\u0639\u0644\u0642 \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0642\u0628\u0644\u06cc \u0646\u06cc\u0633\u062a\u060c \u0648\u06af\u0631\u0646\u0647 \u0645\u0645\u06a9\u0646\u0647 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u062e\u0635\u0648\u0635\u06cc \u062d\u0633\u0627\u0628 \u0642\u0628\u0644\u06cc \u0631\u0648\u06cc \u0647\u0645\u0648\u0646 \u06af\u0648\u0634\u06cc \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0628\u0634\u0646.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun logout() {\n    runCatching {\n        pushApi.unregister(\n            installationIdProvider.get()\n        )\n    }\n\n    authStorage.clear()\n    localDatabase.clearUserData()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">logout<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">runCatching<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        pushApi.<\/span><span style=\"color: #6F42C1\">unregister<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            installationIdProvider.<\/span><span style=\"color: #6F42C1\">get<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    authStorage.<\/span><span style=\"color: #6F42C1\">clear<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    localDatabase.<\/span><span style=\"color: #6F42C1\">clearUserData<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u062c\u0627\u0632\u0647 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u062f\u0631 \u0632\u0645\u0627\u0646 \u062f\u0631\u0633\u062a \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Android 13 \u0648 \u0628\u0627\u0644\u0627\u062a\u0631\u060c \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u0645\u0639\u0645\u0648\u0644\u06cc \u0628\u0647 \u0645\u062c\u0648\u0632 Runtime \u0628\u0627 \u0646\u0627\u0645 <code>POST_NOTIFICATIONS<\/code> \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u0646 \u0648 \u0627\u0639\u0644\u0627\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u0627\u0632\u0647\u200c\u0646\u0635\u0628\u200c\u0634\u062f\u0647 \u0628\u0647\u200c\u0635\u0648\u0631\u062a \u067e\u06cc\u0634\u200c\u0641\u0631\u0636 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644\u0647 \u062a\u0627 \u06a9\u0627\u0631\u0628\u0631 \u0627\u062c\u0627\u0632\u0647 \u0628\u062f\u0647. \u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 Android 13 \u06cc\u0627 \u0628\u0627\u0644\u0627\u062a\u0631 \u0631\u0648 Target \u06a9\u0646\u0647\u060c \u0632\u0645\u0627\u0646 \u0646\u0645\u0627\u06cc\u0634 \u062f\u06cc\u0627\u0644\u0648\u06af \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 \u062e\u0648\u062f \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0633\u062a\u061b \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0628\u0647\u062a\u0631\u0647 \u0645\u062c\u0648\u0632 \u0631\u0648 \u062f\u0631 \u0644\u062d\u0638\u0647\u200c\u0627\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u0646\u06cc\u0645 \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0627\u0631\u0632\u0634 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u062f\u0631\u06a9 \u06a9\u0631\u062f\u0647\u060c \u0646\u0647 \u0628\u0644\u0627\u0641\u0627\u0635\u0644\u0647 \u0628\u0639\u062f \u0627\u0632 \u0627\u0648\u0644\u06cc\u0646 \u0627\u062c\u0631\u0627.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Manifest:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;uses-permission\n    android:name=\n        \"android.permission.POST_NOTIFICATIONS\" \/>\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">uses<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\">permission<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    android:<\/span><span style=\"color: #6F42C1\">name<\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;android.permission.POST_NOTIFICATIONS&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">\/&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Compose:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nfun NotificationPermissionRequest(\n    shouldAsk: Boolean,\n    onResult: (Boolean) -> Unit\n) {\n    if (\n        Build.VERSION.SDK_INT &lt;\n        Build.VERSION_CODES.TIRAMISU\n    ) {\n        return\n    }\n\n    val permissionLauncher =\n        rememberLauncherForActivityResult(\n            contract =\n                ActivityResultContracts\n                    .RequestPermission(),\n            onResult = onResult\n        )\n\n    LaunchedEffect(shouldAsk) {\n        if (shouldAsk) {\n            permissionLauncher.launch(\n                Manifest.permission\n                    .POST_NOTIFICATIONS\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">NotificationPermissionRequest<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    shouldAsk: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onResult: (<\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\">) -&gt; <\/span><span style=\"color: #6F42C1\">Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Build.VERSION.SDK_INT <\/span><span style=\"color: #D73A49\">&lt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Build.VERSION_CODES.TIRAMISU<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> permissionLauncher <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">rememberLauncherForActivityResult<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            contract <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ActivityResultContracts<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">RequestPermission<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            onResult <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> onResult<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">LaunchedEffect<\/span><span style=\"color: #24292E\">(shouldAsk) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (shouldAsk) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            permissionLauncher.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Manifest.permission<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .POST_NOTIFICATIONS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0628\u0647\u062a\u0631\u0647 \u0642\u0628\u0644 \u0627\u0632 \u062f\u06cc\u0627\u0644\u0648\u06af \u0633\u06cc\u0633\u062a\u0645\u06cc\u060c \u06cc\u06a9 \u0635\u0641\u062d\u0647 \u062a\u0648\u0636\u06cc\u062d \u06a9\u0648\u062a\u0627\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644\u06cc \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u0647\u060c \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647\n\u0647\u0645\u0648\u0646 \u0644\u062d\u0638\u0647 \u0628\u0647\u062a \u062e\u0628\u0631 \u0628\u062f\u0647.\n\n[\u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0646 \u0627\u0639\u0644\u0627\u0646 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a]\n[\u0641\u0639\u0644\u0627\u064b \u0646\u0647]\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0635\u0641\u062d\u0647 \u0646\u0628\u0627\u06cc\u062f \u06a9\u0627\u0631\u0628\u0631 \u0631\u0648 \u0641\u0631\u06cc\u0628 \u0628\u062f\u0647 \u06cc\u0627 \u062f\u06a9\u0645\u0647 \u0631\u062f \u06a9\u0631\u062f\u0646 \u0631\u0648 \u067e\u0646\u0647\u0627\u0646 \u06a9\u0646\u0647. \u0647\u062f\u0641 \u0641\u0642\u0637 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0628\u062f\u0648\u0646\u0647 \u0686\u0631\u0627 \u0645\u062c\u0648\u0632 \u0631\u0648 \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc\u0645. \u0628\u0647\u062a\u0631\u06cc\u0646 \u0646\u0642\u0637\u0647 \u0628\u0631\u0627\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u062c\u0648\u0632 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0628\u0639\u062f \u0627\u0632 \u0633\u0627\u062e\u062a \u0627\u0648\u0644\u06cc\u0646 \u0647\u0634\u062f\u0627\u0631 \u0642\u06cc\u0645\u062a \u0628\u0627\u0634\u0647\u061b \u0686\u0648\u0646 \u062f\u0631 \u0647\u0645\u0648\u0646 \u0644\u062d\u0638\u0647\u060c \u0627\u0631\u062a\u0628\u0627\u0637 \u0627\u0639\u0644\u0627\u0646 \u0628\u0627 \u062e\u0648\u0627\u0633\u062a\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0631\u0648\u0634\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0636\u0639\u06cc\u062a Permission \u0631\u0648 \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun areNotificationsAllowed(\n    context: Context\n): Boolean {\n    val permissionGranted =\n        if (\n            Build.VERSION.SDK_INT >=\n            Build.VERSION_CODES.TIRAMISU\n        ) {\n            ContextCompat.checkSelfPermission(\n                context,\n                Manifest.permission\n                    .POST_NOTIFICATIONS\n            ) ==\n                PackageManager\n                    .PERMISSION_GRANTED\n        } else {\n            true\n        }\n\n    return permissionGranted &amp;&amp;\n        NotificationManagerCompat\n            .from(context)\n            .areNotificationsEnabled()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">areNotificationsAllowed<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    context: <\/span><span style=\"color: #6F42C1\">Context<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">): <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> permissionGranted <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Build.VERSION.SDK_INT <\/span><span style=\"color: #D73A49\">&gt;=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Build.VERSION_CODES.TIRAMISU<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ContextCompat.<\/span><span style=\"color: #6F42C1\">checkSelfPermission<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                context,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Manifest.permission<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .POST_NOTIFICATIONS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ) <\/span><span style=\"color: #D73A49\">==<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                PackageManager<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .PERMISSION_GRANTED<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> permissionGranted <\/span><span style=\"color: #D73A49\">&amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        NotificationManagerCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">from<\/span><span style=\"color: #24292E\">(context)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">areNotificationsEnabled<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627 \u0631\u0648 \u0627\u0632 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0633\u06cc\u0633\u062a\u0645 \u062e\u0627\u0645\u0648\u0634 \u06a9\u0631\u062f\u0647\u060c \u0646\u0645\u0627\u06cc\u0634 \u062f\u0648\u0628\u0627\u0631\u0647 \u062f\u06cc\u0627\u0644\u0648\u06af \u0628\u0631\u0646\u0627\u0645\u0647 \u06a9\u0645\u06a9\u06cc \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647. \u0628\u0647\u062a\u0631\u0647 \u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u062a\u0648\u0636\u06cc\u062d\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u06cc\u0645 \u0648 \u062f\u0631 \u0635\u0648\u0631\u062a \u0627\u0646\u062a\u062e\u0627\u0628 \u062e\u0648\u062f \u06a9\u0627\u0631\u0628\u0631\u060c \u0635\u0641\u062d\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0627\u0639\u0644\u0627\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0627\u0632 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun openNotificationSettings(\n    context: Context\n) {\n    val intent = Intent(\n        Settings\n            .ACTION_APP_NOTIFICATION_SETTINGS\n    ).apply {\n        putExtra(\n            Settings.EXTRA_APP_PACKAGE,\n            context.packageName\n        )\n    }\n\n    context.startActivity(intent)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">openNotificationSettings<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    context: <\/span><span style=\"color: #6F42C1\">Context<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> intent <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Intent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Settings<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .ACTION_APP_NOTIFICATION_SETTINGS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ).<\/span><span style=\"color: #6F42C1\">apply<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">putExtra<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Settings.EXTRA_APP_PACKAGE,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            context.packageName<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    context.<\/span><span style=\"color: #6F42C1\">startActivity<\/span><span style=\"color: #24292E\">(intent)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Channel\u0647\u0627 \u0631\u0648 \u0628\u0631\u0627\u0633\u0627\u0633 \u0646\u0648\u0639 \u0646\u06cc\u0627\u0632 \u06a9\u0627\u0631\u0628\u0631 \u062c\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627 \u0627\u0647\u0645\u06cc\u062a \u06cc\u06a9\u0633\u0627\u0646\u06cc \u0646\u062f\u0627\u0631\u0646. \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0647\u062f\u0641\u200c\u06af\u0630\u0627\u0631\u06cc\u200c\u0634\u062f\u0647\u060c \u0627\u0637\u0644\u0627\u0639\u06cc\u0647 \u0639\u0645\u0648\u0645\u06cc\u060c \u0647\u0634\u062f\u0627\u0631 \u0627\u0645\u0646\u06cc\u062a \u062d\u0633\u0627\u0628 \u0648 \u0648\u0636\u0639\u06cc\u062a Sync \u0646\u0628\u0627\u06cc\u062f \u062f\u0627\u062e\u0644 \u06cc\u06a9 Channel \u0642\u0631\u0627\u0631 \u0628\u06af\u06cc\u0631\u0646. \u06a9\u0627\u0631\u0628\u0631 \u0628\u0627\u06cc\u062f \u0628\u062a\u0648\u0646\u0647 \u0628\u0639\u0636\u06cc \u0646\u0648\u0639\u200c\u0647\u0627 \u0631\u0648 \u062e\u0627\u0645\u0648\u0634 \u0648 \u0628\u0639\u0636\u06cc \u0631\u0648 \u0631\u0648\u0634\u0646 \u0646\u06af\u0647 \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>object NotificationChannels {\n\n    const val PRICE_ALERTS =\n        \"price_alerts\"\n\n    const val ACCOUNT_SECURITY =\n        \"account_security\"\n\n    const val GENERAL =\n        \"general\"\n\n    const val BACKGROUND_SYNC =\n        \"background_sync\"\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">NotificationChannels<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> PRICE_ALERTS <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;price_alerts&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> ACCOUNT_SECURITY <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;account_security&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> GENERAL <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;general&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> BACKGROUND_SYNC <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;background_sync&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u0627\u062e\u062a Channel\u0647\u0627:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class NotificationChannelFactory(\n    private val context: Context\n) {\n\n    fun createAll() {\n        if (\n            Build.VERSION.SDK_INT &lt;\n            Build.VERSION_CODES.O\n        ) {\n            return\n        }\n\n        val manager =\n            context.getSystemService(\n                NotificationManager::class.java\n            )\n\n        val priceAlerts =\n            NotificationChannel(\n                NotificationChannels\n                    .PRICE_ALERTS,\n                \"\u0647\u0634\u062f\u0627\u0631\u0647\u0627\u06cc \u0642\u06cc\u0645\u062a\",\n                NotificationManager\n                    .IMPORTANCE_HIGH\n            ).apply {\n                description =\n                    \"\u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0648 \u0631\u0633\u06cc\u062f\u0646 \u0645\u062d\u0635\u0648\u0644 \u0628\u0647 \u0642\u06cc\u0645\u062a \u0647\u062f\u0641\"\n\n                enableVibration(true)\n            }\n\n        val accountSecurity =\n            NotificationChannel(\n                NotificationChannels\n                    .ACCOUNT_SECURITY,\n                \"\u0627\u0645\u0646\u06cc\u062a \u062d\u0633\u0627\u0628\",\n                NotificationManager\n                    .IMPORTANCE_HIGH\n            ).apply {\n                description =\n                    \"\u0648\u0631\u0648\u062f \u062c\u062f\u06cc\u062f \u0648 \u0647\u0634\u062f\u0627\u0631\u0647\u0627\u06cc \u0645\u0647\u0645 \u0627\u0645\u0646\u06cc\u062a\u06cc\"\n            }\n\n        val general =\n            NotificationChannel(\n                NotificationChannels.GENERAL,\n                \"\u0627\u0637\u0644\u0627\u0639\u06cc\u0647\u200c\u0647\u0627\u06cc \u0639\u0645\u0648\u0645\u06cc\",\n                NotificationManager\n                    .IMPORTANCE_DEFAULT\n            ).apply {\n                description =\n                    \"\u062e\u0628\u0631\u0647\u0627 \u0648 \u0627\u0637\u0644\u0627\u0639\u06cc\u0647\u200c\u0647\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646\"\n            }\n\n        val backgroundSync =\n            NotificationChannel(\n                NotificationChannels\n                    .BACKGROUND_SYNC,\n                \"\u0647\u0645\u06af\u0627\u0645\u200c\u0633\u0627\u0632\u06cc\",\n                NotificationManager\n                    .IMPORTANCE_LOW\n            ).apply {\n                description =\n                    \"\u0648\u0636\u0639\u06cc\u062a \u0639\u0645\u0644\u06cc\u0627\u062a \u067e\u0633\u200c\u0632\u0645\u06cc\u0646\u0647\"\n            }\n\n        manager.createNotificationChannels(\n            listOf(\n                priceAlerts,\n                accountSecurity,\n                general,\n                backgroundSync\n            )\n        )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">NotificationChannelFactory<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> context: <\/span><span style=\"color: #6F42C1\">Context<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">createAll<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Build.VERSION.SDK_INT <\/span><span style=\"color: #D73A49\">&lt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Build.VERSION_CODES.O<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> manager <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            context.<\/span><span style=\"color: #6F42C1\">getSystemService<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationManager::<\/span><span style=\"color: #6F42C1\">class<\/span><span style=\"color: #24292E\">.java<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> priceAlerts <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">NotificationChannel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationChannels<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .PRICE_ALERTS,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;\u0647\u0634\u062f\u0627\u0631\u0647\u0627\u06cc \u0642\u06cc\u0645\u062a&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationManager<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .IMPORTANCE_HIGH<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ).<\/span><span style=\"color: #6F42C1\">apply<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                description <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;\u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0648 \u0631\u0633\u06cc\u062f\u0646 \u0645\u062d\u0635\u0648\u0644 \u0628\u0647 \u0642\u06cc\u0645\u062a \u0647\u062f\u0641&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">enableVibration<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> accountSecurity <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">NotificationChannel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationChannels<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .ACCOUNT_SECURITY,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;\u0627\u0645\u0646\u06cc\u062a \u062d\u0633\u0627\u0628&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationManager<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .IMPORTANCE_HIGH<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ).<\/span><span style=\"color: #6F42C1\">apply<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                description <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;\u0648\u0631\u0648\u062f \u062c\u062f\u06cc\u062f \u0648 \u0647\u0634\u062f\u0627\u0631\u0647\u0627\u06cc \u0645\u0647\u0645 \u0627\u0645\u0646\u06cc\u062a\u06cc&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> general <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">NotificationChannel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationChannels.GENERAL,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;\u0627\u0637\u0644\u0627\u0639\u06cc\u0647\u200c\u0647\u0627\u06cc \u0639\u0645\u0648\u0645\u06cc&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationManager<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .IMPORTANCE_DEFAULT<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ).<\/span><span style=\"color: #6F42C1\">apply<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                description <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;\u062e\u0628\u0631\u0647\u0627 \u0648 \u0627\u0637\u0644\u0627\u0639\u06cc\u0647\u200c\u0647\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> backgroundSync <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">NotificationChannel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationChannels<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .BACKGROUND_SYNC,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;\u0647\u0645\u06af\u0627\u0645\u200c\u0633\u0627\u0632\u06cc&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationManager<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .IMPORTANCE_LOW<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ).<\/span><span style=\"color: #6F42C1\">apply<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                description <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;\u0648\u0636\u0639\u06cc\u062a \u0639\u0645\u0644\u06cc\u0627\u062a \u067e\u0633\u200c\u0632\u0645\u06cc\u0646\u0647&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        manager.<\/span><span style=\"color: #6F42C1\">createNotificationChannels<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">listOf<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                priceAlerts,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                accountSecurity,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                general,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                backgroundSync<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Channel \u0631\u0648 \u0628\u0627\u06cc\u062f \u0632\u0648\u062f\u060c \u0645\u062b\u0644\u0627\u064b \u062f\u0627\u062e\u0644 <code>Application<\/code> \u0628\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class GheimatBanApplication :\n    Application() {\n\n    override fun onCreate() {\n        super.onCreate()\n\n        NotificationChannelFactory(\n            this\n        ).createAll()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">GheimatBanApplication<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">Application<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">NotificationChannelFactory<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #005CC5\">this<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ).<\/span><span style=\"color: #6F42C1\">createAll<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0646 Channel\u060c \u06a9\u0627\u0631\u0628\u0631 \u0631\u0648\u06cc \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0635\u062f\u0627\u060c \u0644\u0631\u0632\u0634 \u0648 \u0627\u0647\u0645\u06cc\u062a \u0627\u0648\u0646 \u06a9\u0646\u062a\u0631\u0644 \u062f\u0627\u0631\u0647. \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0628\u0627\u06cc\u062f \u062a\u0635\u0648\u0631 \u06a9\u0646\u0647 \u0647\u0631 \u0632\u0645\u0627\u0646 \u062e\u0648\u0627\u0633\u062a \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 Importance \u06cc\u06a9 Channel \u0645\u0648\u062c\u0648\u062f \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u0647. \u0627\u06af\u0631 \u0628\u0639\u062f\u0627\u064b \u0646\u0648\u0639 \u0627\u0639\u0644\u0627\u0646 \u0648\u0627\u0642\u0639\u0627\u064b \u0645\u062a\u0641\u0627\u0648\u062a\u06cc \u062f\u0627\u0631\u06cc\u0645\u060c \u0628\u0647\u062a\u0631\u0647 Channel \u062a\u0627\u0632\u0647\u200c\u0627\u06cc \u0628\u0627 \u0634\u0646\u0627\u0633\u0647 \u062c\u062f\u06cc\u062f \u0628\u0633\u0627\u0632\u06cc\u0645\u060c \u0646\u0647 \u0627\u06cc\u0646\u06a9\u0647 \u0645\u0639\u0646\u0627\u06cc Channel \u0642\u062f\u06cc\u0645\u06cc \u0631\u0648 \u0639\u0648\u0636 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Push Handler\u061b \u0645\u0631\u06a9\u0632 \u062a\u0635\u0645\u06cc\u0645\u200c\u06af\u06cc\u0631\u06cc \u0627\u0639\u0644\u0627\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u06cc\u06a9 Handler \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645 \u06a9\u0647 \u0642\u0628\u0644 \u0627\u0632 \u0646\u0645\u0627\u06cc\u0634 \u0627\u0639\u0644\u0627\u0646 \u0686\u0646\u062f \u062a\u0635\u0645\u06cc\u0645 \u0628\u06af\u06cc\u0631\u0647: \u0622\u06cc\u0627 \u0646\u0648\u0639 \u067e\u06cc\u0627\u0645 \u0634\u0646\u0627\u062e\u062a\u0647\u200c\u0634\u062f\u0647\u200c\u0633\u062a\u061f \u0622\u06cc\u0627 \u0627\u0639\u0644\u0627\u0646 \u0642\u0628\u0644\u0627\u064b \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0634\u062f\u0647\u061f \u0622\u06cc\u0627 \u06a9\u0627\u0631\u0628\u0631 \u0627\u06cc\u0646 \u0646\u0648\u0639 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0647\u061f \u0622\u06cc\u0627 \u067e\u06cc\u0627\u0645 \u0647\u0646\u0648\u0632 \u062a\u0627\u0632\u0647\u200c\u0633\u062a\u061f \u0622\u06cc\u0627 \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 Foreground \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u0647\u061f \u0622\u06cc\u0627 \u0628\u0627\u06cc\u062f Notification \u0633\u0627\u062e\u062a\u0647 \u0628\u0634\u0647 \u06cc\u0627 \u0641\u0642\u0637 Sync \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647\u061f<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class PushHandler(\n    private val context: Context,\n    private val deduplicator:\n        PushDeduplicator =\n            PushDeduplicator(context),\n    private val preferences:\n        PushPreferenceStore =\n            PushPreferenceStore(context),\n    private val notificationFactory:\n        AppNotificationFactory =\n            AppNotificationFactory(context)\n) {\n\n    fun handle(\n        payload: PushPayload,\n        originalPriority: Int,\n        deliveredPriority: Int\n    ) {\n        if (\n            payload.schemaVersion >\n            SUPPORTED_SCHEMA_VERSION\n        ) {\n            FullSyncScheduler.enqueue(\n                context\n            )\n            return\n        }\n\n        if (\n            deduplicator\n                .wasAlreadyHandled(\n                    payload.eventId\n                )\n        ) {\n            return\n        }\n\n        if (isExpired(payload)) {\n            deduplicator.markHandled(\n                payload.eventId\n            )\n            return\n        }\n\n        if (\n            !preferences.isEnabled(\n                payload.type\n            )\n        ) {\n            deduplicator.markHandled(\n                payload.eventId\n            )\n            return\n        }\n\n        notificationFactory.show(\n            payload\n        )\n\n        deduplicator.markHandled(\n            payload.eventId\n        )\n\n        PushAnalytics.logReceived(\n            payload = payload,\n            originalPriority =\n                originalPriority,\n            deliveredPriority =\n                deliveredPriority\n        )\n\n        scheduleRelatedSync(payload)\n    }\n\n    private fun isExpired(\n        payload: PushPayload\n    ): Boolean {\n        val createdAt =\n            payload.createdAt\n                ?: return false\n\n        val maxAge =\n            when (payload.type) {\n                PushType.PRICE_DROP,\n                PushType.PRICE_TARGET_REACHED ->\n                    Duration.ofHours(12)\n\n                PushType.ACCOUNT_WARNING ->\n                    Duration.ofDays(2)\n\n                else ->\n                    Duration.ofDays(1)\n            }\n\n        return createdAt\n            .plus(maxAge)\n            .isBefore(Instant.now())\n    }\n\n    private fun scheduleRelatedSync(\n        payload: PushPayload\n    ) {\n        when (payload.type) {\n            PushType.PRICE_DROP,\n            PushType.PRICE_TARGET_REACHED,\n            PushType.PRODUCT_AVAILABLE,\n            PushType.PRODUCT_UNAVAILABLE -> {\n                payload.entityId?.let {\n                    ProductSyncScheduler\n                        .enqueue(\n                            context = context,\n                            productId = it\n                        )\n                }\n            }\n\n            else -> Unit\n        }\n    }\n\n    private companion object {\n        const val SUPPORTED_SCHEMA_VERSION =\n            1\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushHandler<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> context: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> deduplicator:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        PushDeduplicator <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">PushDeduplicator<\/span><span style=\"color: #24292E\">(context),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> preferences:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        PushPreferenceStore <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">PushPreferenceStore<\/span><span style=\"color: #24292E\">(context),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> notificationFactory:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        AppNotificationFactory <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">AppNotificationFactory<\/span><span style=\"color: #24292E\">(context)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">handle<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        originalPriority: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        deliveredPriority: <\/span><span style=\"color: #6F42C1\">Int<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            payload.schemaVersion <\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            SUPPORTED_SCHEMA_VERSION<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            FullSyncScheduler.<\/span><span style=\"color: #6F42C1\">enqueue<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                context<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            deduplicator<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">wasAlreadyHandled<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    payload.eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><span style=\"color: #6F42C1\">isExpired<\/span><span style=\"color: #24292E\">(payload)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            deduplicator.<\/span><span style=\"color: #6F42C1\">markHandled<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">!<\/span><span style=\"color: #24292E\">preferences.<\/span><span style=\"color: #6F42C1\">isEnabled<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.type<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            deduplicator.<\/span><span style=\"color: #6F42C1\">markHandled<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        notificationFactory.<\/span><span style=\"color: #6F42C1\">show<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            payload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        deduplicator.<\/span><span style=\"color: #6F42C1\">markHandled<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            payload.eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        PushAnalytics.<\/span><span style=\"color: #6F42C1\">logReceived<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            payload <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> payload,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            originalPriority <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                originalPriority,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            deliveredPriority <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                deliveredPriority<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">scheduleRelatedSync<\/span><span style=\"color: #24292E\">(payload)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">isExpired<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> createdAt <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            payload.createdAt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> maxAge <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (payload.type) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                PushType.PRICE_DROP,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                PushType.PRICE_TARGET_REACHED <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    Duration.<\/span><span style=\"color: #6F42C1\">ofHours<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">12<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                PushType.ACCOUNT_WARNING <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    Duration.<\/span><span style=\"color: #6F42C1\">ofDays<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">2<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    Duration.<\/span><span style=\"color: #6F42C1\">ofDays<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> createdAt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">plus<\/span><span style=\"color: #24292E\">(maxAge)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">isBefore<\/span><span style=\"color: #24292E\">(Instant.<\/span><span style=\"color: #6F42C1\">now<\/span><span style=\"color: #24292E\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">scheduleRelatedSync<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (payload.type) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRICE_DROP,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRICE_TARGET_REACHED,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRODUCT_AVAILABLE,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRODUCT_UNAVAILABLE <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.entityId?.<\/span><span style=\"color: #6F42C1\">let<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ProductSyncScheduler<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">enqueue<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            context <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> context,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            productId <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> it<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">companion<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">object<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> SUPPORTED_SCHEMA_VERSION <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0637\u0631\u0627\u062d\u06cc\u060c \u0646\u0645\u0627\u06cc\u0634 \u0627\u0639\u0644\u0627\u0646 \u0641\u0642\u0637 \u06cc\u06a9\u06cc \u0627\u0632 \u062e\u0631\u0648\u062c\u06cc\u200c\u0647\u0627\u06cc Push \u0647\u0633\u062a. \u0628\u0639\u062f \u0627\u0632 \u0646\u0645\u0627\u06cc\u0634 \u0641\u0648\u0631\u06cc\u060c WorkManager \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 \u062a\u0627\u0632\u0647 \u06a9\u0646\u0647 \u062a\u0627 \u0648\u0642\u062a\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0648\u0627\u0631\u062f \u0635\u0641\u062d\u0647 \u0634\u062f\u060c \u062f\u0627\u062f\u0647 \u062c\u062f\u06cc\u062f \u0627\u0632 \u0642\u0628\u0644 \u062f\u0631 Room \u0645\u0648\u062c\u0648\u062f \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u0627\u0639\u0644\u0627\u0646 \u062a\u06a9\u0631\u0627\u0631\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">FCM \u062a\u0636\u0645\u06cc\u0646 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647 \u06a9\u0647 \u0645\u0646\u0637\u0642 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0631\u06af\u0632 \u06cc\u06a9 \u0631\u0648\u06cc\u062f\u0627\u062f \u0631\u0648 \u062f\u0648\u0628\u0627\u0631 \u062f\u0631\u06cc\u0627\u0641\u062a \u0646\u06a9\u0646\u0647. Backend \u0647\u0645 \u0645\u0645\u06a9\u0646\u0647 \u0628\u0647\u200c\u062f\u0644\u06cc\u0644 Retry \u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u0631\u0648 \u062f\u0648\u0628\u0627\u0631\u0647 \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u0647. \u0627\u06af\u0631 \u0641\u0642\u0637 \u0627\u0632 <code>productId<\/code> \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 \u0634\u0646\u0627\u0633\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645\u060c \u062f\u0648 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0645\u062a\u0641\u0627\u0648\u062a \u0628\u0631\u0627\u06cc \u06cc\u06a9 \u0645\u062d\u0635\u0648\u0644 \u0627\u0634\u062a\u0628\u0627\u0647\u0627\u064b \u06cc\u06a9\u06cc \u0634\u0646\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0646. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0647\u0631 \u0631\u0648\u06cc\u062f\u0627\u062f \u0628\u0627\u06cc\u062f <code>eventId<\/code> \u06cc\u06a9\u062a\u0627 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0646\u0645\u0648\u0646\u0647 \u0633\u0627\u062f\u0647\u060c \u0634\u0646\u0627\u0633\u0647\u200c\u0647\u0627\u06cc \u067e\u0631\u062f\u0627\u0632\u0634\u200c\u0634\u062f\u0647 \u0631\u0648 \u062f\u0631 DataStore \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class PushDeduplicator(\n    context: Context\n) {\n\n    private val preferences =\n        context.getSharedPreferences(\n            \"push_deduplication\",\n            Context.MODE_PRIVATE\n        )\n\n    fun wasAlreadyHandled(\n        eventId: String\n    ): Boolean {\n        return preferences.contains(\n            eventId\n        )\n    }\n\n    fun markHandled(\n        eventId: String\n    ) {\n        preferences\n            .edit()\n            .putLong(\n                eventId,\n                System.currentTimeMillis()\n            )\n            .apply()\n\n        removeExpiredEntries()\n    }\n\n    private fun removeExpiredEntries() {\n        val expirationTime =\n            System.currentTimeMillis() -\n                TimeUnit.DAYS\n                    .toMillis(7)\n\n        val editor =\n            preferences.edit()\n\n        preferences.all\n            .filterValues { value ->\n                value is Long &amp;&amp;\n                    value &lt; expirationTime\n            }\n            .keys\n            .forEach(editor::remove)\n\n        editor.apply()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushDeduplicator<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    context: <\/span><span style=\"color: #6F42C1\">Context<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> preferences <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        context.<\/span><span style=\"color: #6F42C1\">getSharedPreferences<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;push_deduplication&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Context.MODE_PRIVATE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">wasAlreadyHandled<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        eventId: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> preferences.<\/span><span style=\"color: #6F42C1\">contains<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">markHandled<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        eventId: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        preferences<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">edit<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">putLong<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                eventId,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                System.<\/span><span style=\"color: #6F42C1\">currentTimeMillis<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">apply<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">removeExpiredEntries<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">removeExpiredEntries<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> expirationTime <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            System.<\/span><span style=\"color: #6F42C1\">currentTimeMillis<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">-<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                TimeUnit.DAYS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">toMillis<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">7<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> editor <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            preferences.<\/span><span style=\"color: #6F42C1\">edit<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        preferences.all<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">filterValues<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> Long <\/span><span style=\"color: #D73A49\">&amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\"> expirationTime<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .keys<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">forEach<\/span><span style=\"color: #24292E\">(editor::<\/span><span style=\"color: #6F42C1\">remove<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        editor.<\/span><span style=\"color: #6F42C1\">apply<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u062d\u062c\u0645 \u0628\u0627\u0644\u0627\u062a\u0631 \u0628\u0647\u062a\u0631\u0647 \u06cc\u06a9 \u062c\u062f\u0648\u0644 Room \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Entity(\n    tableName = \"handled_push_events\"\n)\ndata class HandledPushEventEntity(\n    @PrimaryKey\n    val eventId: String,\n    val handledAt: Long\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Entity<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    tableName <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;handled_push_events&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HandledPushEventEntity<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@PrimaryKey<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> eventId: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> handledAt: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Dao\ninterface HandledPushEventDao {\n\n    @Query(\n        \"\"\"\n        SELECT EXISTS(\n            SELECT 1\n            FROM handled_push_events\n            WHERE eventId = :eventId\n        )\n        \"\"\"\n    )\n    suspend fun exists(\n        eventId: String\n    ): Boolean\n\n    @Insert(\n        onConflict = OnConflictStrategy.IGNORE\n    )\n    suspend fun insert(\n        event:\n            HandledPushEventEntity\n    )\n\n    @Query(\n        \"\"\"\n        DELETE FROM handled_push_events\n        WHERE handledAt &lt; :before\n        \"\"\"\n    )\n    suspend fun deleteOlderThan(\n        before: Long\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Dao<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HandledPushEventDao<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        SELECT EXISTS(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">            SELECT 1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">            FROM handled_push_events<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">            WHERE eventId = :eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        &quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">exists<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        eventId: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">Boolean<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@Insert<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        onConflict <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> OnConflictStrategy.IGNORE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">insert<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        event:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            HandledPushEventEntity<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        DELETE FROM handled_push_events<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        WHERE handledAt &lt; :before<\/span><\/span>\n<span class=\"line\"><span style=\"color: #032F62\">        &quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">deleteOlderThan<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        before: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0639\u0644\u0627\u0646 \u062a\u06a9\u0631\u0627\u0631\u06cc \u0631\u0648 \u0628\u0627\u06cc\u062f \u062f\u0631 \u0647\u0631 \u062f\u0648 \u0637\u0631\u0641 \u06a9\u0646\u062a\u0631\u0644 \u06a9\u0646\u06cc\u0645. Backend \u0628\u0627\u06cc\u062f \u0628\u0631\u0627\u06cc \u06cc\u06a9 \u0631\u0648\u06cc\u062f\u0627\u062f \u06a9\u0633\u0628\u200c\u0648\u06a9\u0627\u0631\u06cc\u060c \u0641\u0642\u0637 \u06cc\u06a9 Event \u0628\u0633\u0627\u0632\u0647 \u0648 Client \u0647\u0645 \u062f\u0631 \u0628\u0631\u0627\u0628\u0631 \u0627\u0631\u0633\u0627\u0644 \u06cc\u0627 \u062a\u062d\u0648\u06cc\u0644 \u062a\u06a9\u0631\u0627\u0631\u06cc \u0645\u0642\u0627\u0648\u0645 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0633\u0627\u062e\u062a \u0627\u0639\u0644\u0627\u0646 \u0628\u0627 \u0645\u0642\u0635\u062f \u062f\u0642\u06cc\u0642<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0647\u0631 Push \u0628\u0627\u06cc\u062f \u0645\u0634\u062e\u0635 \u0628\u0627\u0634\u0647 \u0644\u0645\u0633 \u0627\u0639\u0644\u0627\u0646 \u06a9\u062c\u0627 \u0645\u06cc\u0631\u0647. \u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646\u060c \u0627\u0639\u0644\u0627\u0646 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0628\u0627\u06cc\u062f \u0635\u0641\u062d\u0647 \u0647\u0645\u0648\u0646 \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 \u0628\u0627\u0632 \u06a9\u0646\u0647\u060c \u0646\u0647 \u0627\u06cc\u0646\u06a9\u0647 \u0641\u0642\u0637 \u0635\u0641\u062d\u0647 \u0627\u0635\u0644\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9 Route \u062f\u0627\u062e\u0644\u06cc \u0627\u0633\u062a\u0627\u0646\u062f\u0627\u0631\u062f \u062a\u0639\u0631\u06cc\u0641 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gheimatban:\/\/product\/8472\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u0627\u062e\u062a PendingIntent:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class PushPendingIntentFactory(\n    private val context: Context\n) {\n\n    fun create(\n        payload: PushPayload\n    ): PendingIntent {\n        val destination =\n            payload.route\n                ?.let {\n                    Uri.parse(\n                        \"gheimatban:\/\/$it\"\n                    )\n                }\n                ?: Uri.parse(\n                    \"gheimatban:\/\/home\"\n                )\n\n        val intent = Intent(\n            Intent.ACTION_VIEW,\n            destination,\n            context,\n            MainActivity::class.java\n        ).apply {\n            putExtra(\n                EXTRA_EVENT_ID,\n                payload.eventId\n            )\n\n            flags =\n                Intent.FLAG_ACTIVITY_CLEAR_TOP or\n                Intent.FLAG_ACTIVITY_SINGLE_TOP\n        }\n\n        return PendingIntent.getActivity(\n            context,\n            stableRequestCode(\n                payload.eventId\n            ),\n            intent,\n            PendingIntent.FLAG_UPDATE_CURRENT or\n                PendingIntent.FLAG_IMMUTABLE\n        )\n    }\n\n    private fun stableRequestCode(\n        value: String\n    ): Int {\n        return value.hashCode()\n            .and(0x7fffffff)\n    }\n\n    private companion object {\n        const val EXTRA_EVENT_ID =\n            \"push_event_id\"\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushPendingIntentFactory<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> context: <\/span><span style=\"color: #6F42C1\">Context<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">PendingIntent<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> destination <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            payload.route<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?.<\/span><span style=\"color: #6F42C1\">let<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    Uri.<\/span><span style=\"color: #6F42C1\">parse<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        <\/span><span style=\"color: #032F62\">&quot;gheimatban:\/\/<\/span><span style=\"color: #005CC5\">$it<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ?: Uri.<\/span><span style=\"color: #6F42C1\">parse<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;gheimatban:\/\/home&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> intent <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Intent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Intent.ACTION_VIEW,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            destination,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            context,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            MainActivity::<\/span><span style=\"color: #6F42C1\">class<\/span><span style=\"color: #24292E\">.java<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ).<\/span><span style=\"color: #6F42C1\">apply<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">putExtra<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                EXTRA_EVENT_ID,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            flags <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Intent.FLAG_ACTIVITY_CLEAR_TOP or<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Intent.FLAG_ACTIVITY_SINGLE_TOP<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> PendingIntent.<\/span><span style=\"color: #6F42C1\">getActivity<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            context,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">stableRequestCode<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            intent,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PendingIntent.FLAG_UPDATE_CURRENT or<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                PendingIntent.FLAG_IMMUTABLE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">stableRequestCode<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">hashCode<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">and<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">0x7fffffff<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">companion<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">object<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> EXTRA_EVENT_ID <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;push_event_id&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u06cc\u06a9 Request Code \u062b\u0627\u0628\u062a \u0628\u0631\u0627\u06cc \u0647\u0645\u0647 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627 \u0645\u0645\u06a9\u0646\u0647 \u0628\u0627\u0639\u062b \u0628\u0634\u0647 PendingIntent \u0627\u0639\u0644\u0627\u0646 \u062c\u062f\u06cc\u062f\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0627\u0639\u0644\u0627\u0646 \u0642\u0628\u0644\u06cc \u0631\u0648 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u06a9\u0646\u0647. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0627\u0632 Hash \u0634\u0646\u0627\u0633\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f\u06cc\u0645. <code>FLAG_IMMUTABLE<\/code> \u0647\u0645 \u0627\u0639\u0644\u0627\u0645 \u0645\u06cc\u200c\u06a9\u0646\u0647 PendingIntent \u0628\u0639\u062f \u0627\u0632 \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0646 \u0646\u0628\u0627\u06cc\u062f \u062a\u0648\u0633\u0637 \u0628\u062e\u0634 \u062f\u06cc\u06af\u0631\u06cc \u062a\u063a\u06cc\u06cc\u0631 \u062f\u0627\u062f\u0647 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Navigation Compose:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>composable(\n    route = \"product\/{productId}\",\n    arguments = listOf(\n        navArgument(\"productId\") {\n            type = NavType.LongType\n        }\n    ),\n    deepLinks = listOf(\n        navDeepLink {\n            uriPattern =\n                \"gheimatban:\/\/product\/{productId}\"\n        }\n    )\n) { backStackEntry ->\n    val productId =\n        backStackEntry\n            .arguments\n            ?.getLong(\"productId\")\n            ?: return@composable\n\n    ProductDetailsScreen(\n        productId = productId\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">composable<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    route <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;product\/{productId}&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    arguments <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">listOf<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">navArgument<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;productId&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            type <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> NavType.LongType<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    deepLinks <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">listOf<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">navDeepLink<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            uriPattern <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;gheimatban:\/\/product\/{productId}&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) { backStackEntry <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        backStackEntry<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .arguments<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ?.<\/span><span style=\"color: #6F42C1\">getLong<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;productId&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\">@composable<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">ProductDetailsScreen<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productId <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> productId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0642\u0635\u062f Push \u0646\u0628\u0627\u06cc\u062f \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0628\u0647 \u0648\u062c\u0648\u062f \u062f\u0627\u062f\u0647 \u0645\u062d\u0644\u06cc \u0648\u0627\u0628\u0633\u062a\u0647 \u0628\u0627\u0634\u0647. \u0627\u06af\u0631 \u0645\u062d\u0635\u0648\u0644 \u0647\u0646\u0648\u0632 \u062f\u0627\u062e\u0644 Room \u0646\u06cc\u0633\u062a\u060c \u0635\u0641\u062d\u0647 \u0628\u0627\u06cc\u062f Loading \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647 \u0648 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0648 \u0627\u0632 Repository \u0628\u06af\u06cc\u0631\u0647. \u0647\u0645\u0686\u0646\u06cc\u0646 \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0627\u0632 \u062d\u0633\u0627\u0628 \u062e\u0627\u0631\u062c \u0634\u062f\u0647\u060c \u0645\u0642\u0635\u062f \u062e\u0635\u0648\u0635\u06cc \u0628\u0627\u06cc\u062f \u0627\u0628\u062a\u062f\u0627 Login \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647 \u0648 \u0628\u0639\u062f \u0627\u0632 \u0648\u0631\u0648\u062f\u060c \u0645\u0633\u06cc\u0631 \u0627\u0648\u0644\u06cc\u0647 \u0631\u0648 \u0627\u062f\u0627\u0645\u0647 \u0628\u062f\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0633\u0627\u062e\u062a Notification Factory<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0633\u0627\u062e\u062a \u0638\u0627\u0647\u0631\u06cc \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0627\u0632 Service \u062c\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class AppNotificationFactory(\n    private val context: Context\n) {\n\n    private val notificationManager =\n        NotificationManagerCompat\n            .from(context)\n\n    private val pendingIntentFactory =\n        PushPendingIntentFactory(context)\n\n    fun show(\n        payload: PushPayload\n    ) {\n        if (\n            !areNotificationsAllowed(\n                context\n            )\n        ) {\n            return\n        }\n\n        val notification =\n            NotificationCompat.Builder(\n                context,\n                resolveChannel(payload)\n            )\n                .setSmallIcon(\n                    R.drawable.ic_notification\n                )\n                .setContentTitle(\n                    payload.title\n                )\n                .setContentText(\n                    payload.body\n                )\n                .setStyle(\n                    NotificationCompat\n                        .BigTextStyle()\n                        .bigText(\n                            payload.body\n                        )\n                )\n                .setContentIntent(\n                    pendingIntentFactory\n                        .create(payload)\n                )\n                .setAutoCancel(true)\n                .setCategory(\n                    resolveCategory(payload)\n                )\n                .setPriority(\n                    resolveCompatPriority(\n                        payload\n                    )\n                )\n                .setGroup(\n                    resolveGroup(payload)\n                )\n                .setOnlyAlertOnce(true)\n                .build()\n\n        notificationManager.notify(\n            notificationId(payload),\n            notification\n        )\n    }\n\n    private fun resolveChannel(\n        payload: PushPayload\n    ): String {\n        return when (payload.type) {\n            PushType.PRICE_DROP,\n            PushType.PRICE_TARGET_REACHED,\n            PushType.PRODUCT_AVAILABLE,\n            PushType.PRODUCT_UNAVAILABLE ->\n                NotificationChannels\n                    .PRICE_ALERTS\n\n            PushType.ACCOUNT_WARNING ->\n                NotificationChannels\n                    .ACCOUNT_SECURITY\n\n            else ->\n                NotificationChannels.GENERAL\n        }\n    }\n\n    private fun resolveCategory(\n        payload: PushPayload\n    ): String {\n        return when (payload.type) {\n            PushType.ACCOUNT_WARNING ->\n                NotificationCompat\n                    .CATEGORY_WARNING\n\n            else ->\n                NotificationCompat\n                    .CATEGORY_STATUS\n        }\n    }\n\n    private fun resolveCompatPriority(\n        payload: PushPayload\n    ): Int {\n        return when (payload.type) {\n            PushType.PRICE_TARGET_REACHED,\n            PushType.ACCOUNT_WARNING ->\n                NotificationCompat\n                    .PRIORITY_HIGH\n\n            else ->\n                NotificationCompat\n                    .PRIORITY_DEFAULT\n        }\n    }\n\n    private fun resolveGroup(\n        payload: PushPayload\n    ): String {\n        return when (payload.type) {\n            PushType.PRICE_DROP,\n            PushType.PRICE_TARGET_REACHED,\n            PushType.PRODUCT_AVAILABLE,\n            PushType.PRODUCT_UNAVAILABLE ->\n                GROUP_PRICE_ALERTS\n\n            else ->\n                GROUP_GENERAL\n        }\n    }\n\n    private fun notificationId(\n        payload: PushPayload\n    ): Int {\n        return when {\n            payload.entityId != null -> {\n                payload.entityId\n                    .hashCode()\n            }\n\n            else -> {\n                payload.eventId\n                    .hashCode()\n            }\n        }\n    }\n\n    private companion object {\n        const val GROUP_PRICE_ALERTS =\n            \"group_price_alerts\"\n\n        const val GROUP_GENERAL =\n            \"group_general\"\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AppNotificationFactory<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> context: <\/span><span style=\"color: #6F42C1\">Context<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> notificationManager <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        NotificationManagerCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">from<\/span><span style=\"color: #24292E\">(context)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> pendingIntentFactory <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">PushPendingIntentFactory<\/span><span style=\"color: #24292E\">(context)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">show<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">!<\/span><span style=\"color: #6F42C1\">areNotificationsAllowed<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                context<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> notification <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            NotificationCompat.<\/span><span style=\"color: #6F42C1\">Builder<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                context,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">resolveChannel<\/span><span style=\"color: #24292E\">(payload)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setSmallIcon<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    R.drawable.ic_notification<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setContentTitle<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    payload.title<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setContentText<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    payload.body<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setStyle<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    NotificationCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">BigTextStyle<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">bigText<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            payload.body<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setContentIntent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    pendingIntentFactory<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">create<\/span><span style=\"color: #24292E\">(payload)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setAutoCancel<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setCategory<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #6F42C1\">resolveCategory<\/span><span style=\"color: #24292E\">(payload)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setPriority<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #6F42C1\">resolveCompatPriority<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        payload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setGroup<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #6F42C1\">resolveGroup<\/span><span style=\"color: #24292E\">(payload)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setOnlyAlertOnce<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        notificationManager.<\/span><span style=\"color: #6F42C1\">notify<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">notificationId<\/span><span style=\"color: #24292E\">(payload),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            notification<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">resolveChannel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (payload.type) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRICE_DROP,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRICE_TARGET_REACHED,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRODUCT_AVAILABLE,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRODUCT_UNAVAILABLE <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationChannels<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .PRICE_ALERTS<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.ACCOUNT_WARNING <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationChannels<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .ACCOUNT_SECURITY<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationChannels.GENERAL<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">resolveCategory<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (payload.type) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.ACCOUNT_WARNING <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .CATEGORY_WARNING<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .CATEGORY_STATUS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">resolveCompatPriority<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (payload.type) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRICE_TARGET_REACHED,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.ACCOUNT_WARNING <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .PRIORITY_HIGH<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .PRIORITY_DEFAULT<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">resolveGroup<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (payload.type) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRICE_DROP,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRICE_TARGET_REACHED,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRODUCT_AVAILABLE,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            PushType.PRODUCT_UNAVAILABLE <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                GROUP_PRICE_ALERTS<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                GROUP_GENERAL<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">notificationId<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            payload.entityId <\/span><span style=\"color: #D73A49\">!=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.entityId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">hashCode<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">hashCode<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">companion<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">object<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> GROUP_PRICE_ALERTS <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;group_price_alerts&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> GROUP_GENERAL <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;group_general&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646\u062c\u0627 \u0628\u0631\u0627\u06cc \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 \u06cc\u06a9 \u0645\u062d\u0635\u0648\u0644 \u0627\u0632 <code>entityId<\/code> \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 Notification ID \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f\u06cc\u0645. \u0646\u062a\u06cc\u062c\u0647 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0627\u06af\u0631 \u0642\u06cc\u0645\u062a \u0647\u0645\u0648\u0646 \u0645\u062d\u0635\u0648\u0644 \u0686\u0646\u062f \u0628\u0627\u0631 \u062f\u0631 \u0641\u0627\u0635\u0644\u0647 \u06a9\u0648\u062a\u0627\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647\u060c \u0627\u0639\u0644\u0627\u0646 \u0642\u0628\u0644\u06cc \u0628\u0627 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062a\u0627\u0632\u0647 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u0645\u06cc\u0634\u0647 \u0648 Notification Shade \u067e\u0631 \u0627\u0632 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u062a\u06a9\u0631\u0627\u0631\u06cc \u06cc\u06a9 \u0645\u062d\u0635\u0648\u0644 \u0646\u0645\u06cc\u0634\u0647. \u0627\u0645\u0627 \u0627\u06af\u0631 \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc\u0645 \u0647\u0631 \u062a\u063a\u06cc\u06cc\u0631 \u0642\u06cc\u0645\u062a \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0645\u0633\u062a\u0642\u0644\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647\u060c \u0628\u0627\u06cc\u062f \u0627\u0632 <code>eventId<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645. \u0627\u0646\u062a\u062e\u0627\u0628 \u0634\u0646\u0627\u0633\u0647 \u0627\u0639\u0644\u0627\u0646 \u0628\u062e\u0634\u06cc \u0627\u0632 \u0637\u0631\u0627\u062d\u06cc \u0645\u062d\u0635\u0648\u0644\u0647\u060c \u0646\u0647 \u0635\u0631\u0641\u0627\u064b \u06cc\u06a9 \u062a\u0635\u0645\u06cc\u0645 \u0641\u0646\u06cc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>setOnlyAlertOnce(true)<\/code> \u0647\u0645 \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u0648\u0642\u062a\u06cc \u0647\u0645\u0648\u0646 Notification ID \u0628\u0627 \u0645\u062d\u062a\u0648\u0627\u06cc \u062a\u0627\u0632\u0647 Update \u0645\u06cc\u0634\u0647\u060c \u06a9\u0627\u0631\u0628\u0631 \u062f\u0648\u0628\u0627\u0631\u0647 \u0635\u062f\u0627 \u0648 \u0644\u0631\u0632\u0634 \u062f\u0631\u06cc\u0627\u0641\u062a \u0646\u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u06af\u0631\u0648\u0647\u200c\u0628\u0646\u062f\u06cc \u0686\u0646\u062f \u0627\u0639\u0644\u0627\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u067e\u0646\u062c \u0645\u062d\u0635\u0648\u0644 \u06a9\u0627\u0631\u0628\u0631 \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u067e\u06cc\u062f\u0627 \u06a9\u0646\u0646\u060c \u0646\u0645\u0627\u06cc\u0634 \u067e\u0646\u062c \u0627\u0639\u0644\u0627\u0646 \u0645\u0633\u062a\u0642\u0644 \u0628\u062f\u0648\u0646 Summary \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0634\u0644\u0648\u063a \u0628\u0627\u0634\u0647. \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0647\u0645\u0647 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u0642\u06cc\u0645\u062a \u0631\u0648 \u062f\u0627\u062e\u0644 \u06cc\u06a9 Group \u0642\u0631\u0627\u0631 \u0628\u062f\u06cc\u0645 \u0648 \u06cc\u06a9 \u0627\u0639\u0644\u0627\u0646 \u062e\u0644\u0627\u0635\u0647 \u0628\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun showPriceSummary(\n    count: Int\n) {\n    val summary =\n        NotificationCompat.Builder(\n            context,\n            NotificationChannels\n                .PRICE_ALERTS\n        )\n            .setSmallIcon(\n                R.drawable.ic_notification\n            )\n            .setContentTitle(\n                \"$count \u062a\u063a\u06cc\u06cc\u0631 \u0642\u06cc\u0645\u062a \u062c\u062f\u06cc\u062f\"\n            )\n            .setContentText(\n                \"\u0645\u062d\u0635\u0648\u0644\u0627\u062a \u062f\u0646\u0628\u0627\u0644\u200c\u0634\u062f\u0647 \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646.\"\n            )\n            .setStyle(\n                NotificationCompat\n                    .InboxStyle()\n                    .setSummaryText(\n                        \"$count \u0627\u0639\u0644\u0627\u0646 \u0642\u06cc\u0645\u062a\"\n                    )\n            )\n            .setGroup(\n                GROUP_PRICE_ALERTS\n            )\n            .setGroupSummary(true)\n            .setAutoCancel(true)\n            .setContentIntent(\n                createPriceListPendingIntent()\n            )\n            .build()\n\n    notificationManager.notify(\n        PRICE_SUMMARY_ID,\n        summary\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">showPriceSummary<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    count: <\/span><span style=\"color: #6F42C1\">Int<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> summary <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        NotificationCompat.<\/span><span style=\"color: #6F42C1\">Builder<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            context,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            NotificationChannels<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .PRICE_ALERTS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setSmallIcon<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                R.drawable.ic_notification<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setContentTitle<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;<\/span><span style=\"color: #005CC5\">$count<\/span><span style=\"color: #032F62\"> \u062a\u063a\u06cc\u06cc\u0631 \u0642\u06cc\u0645\u062a \u062c\u062f\u06cc\u062f&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setContentText<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;\u0645\u062d\u0635\u0648\u0644\u0627\u062a \u062f\u0646\u0628\u0627\u0644\u200c\u0634\u062f\u0647 \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setStyle<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">InboxStyle<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">setSummaryText<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        <\/span><span style=\"color: #032F62\">&quot;<\/span><span style=\"color: #005CC5\">$count<\/span><span style=\"color: #032F62\"> \u0627\u0639\u0644\u0627\u0646 \u0642\u06cc\u0645\u062a&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setGroup<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                GROUP_PRICE_ALERTS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setGroupSummary<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setAutoCancel<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setContentIntent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">createPriceListPendingIntent<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    notificationManager.<\/span><span style=\"color: #6F42C1\">notify<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        PRICE_SUMMARY_ID,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        summary<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0633\u0627\u062e\u062a Summary \u062f\u0642\u06cc\u0642 \u0628\u0627\u06cc\u062f \u062a\u0639\u062f\u0627\u062f \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u0641\u0639\u0627\u0644 \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u0645 \u06cc\u0627 \u0627\u0632 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u062e\u0648\u0646\u06cc\u0645. \u0641\u0642\u0637 \u0627\u0641\u0632\u0627\u06cc\u0634 \u06cc\u06a9 \u0634\u0645\u0627\u0631\u0646\u062f\u0647 \u0645\u062d\u0644\u06cc \u0645\u0645\u06a9\u0646\u0647 \u0628\u0639\u062f \u0627\u0632 \u062d\u0630\u0641 \u0627\u0639\u0644\u0627\u0646 \u062a\u0648\u0633\u0637 \u06a9\u0627\u0631\u0628\u0631 \u0646\u0627\u062f\u0631\u0633\u062a \u0628\u0634\u0647. \u062f\u0631 \u067e\u0631\u0648\u0698\u0647 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0628\u0647\u062a\u0631\u0647 \u0647\u0631 Push \u062f\u0631 \u062c\u062f\u0648\u0644 Inbox \u0628\u0631\u0646\u0627\u0645\u0647 \u062b\u0628\u062a \u0628\u0634\u0647 \u0648 Summary \u0628\u0631\u0627\u0633\u0627\u0633 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u062e\u0648\u0627\u0646\u062f\u0647\u200c\u0646\u0634\u062f\u0647 \u0633\u0627\u062e\u062a\u0647 \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Notification Inbox \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0639\u0644\u0627\u0646 \u0633\u06cc\u0633\u062a\u0645 \u062f\u0627\u0626\u0645\u06cc \u0646\u06cc\u0633\u062a. \u06a9\u0627\u0631\u0628\u0631 \u0645\u0645\u06a9\u0646\u0647 \u0627\u0648\u0646 \u0631\u0648 \u06a9\u0646\u0627\u0631 \u0628\u0632\u0646\u0647\u060c \u06af\u0648\u0634\u06cc \u0631\u0648 \u0639\u0648\u0636 \u06a9\u0646\u0647 \u06cc\u0627 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627 \u0631\u0648 \u0627\u0632 \u0633\u06cc\u0633\u062a\u0645 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u0647. \u0627\u06af\u0631 \u0631\u0648\u06cc\u062f\u0627\u062f\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0627\u0631\u0632\u0634 \u062a\u0627\u0631\u06cc\u062e\u06cc \u062f\u0627\u0631\u0646\u060c \u0628\u0627\u06cc\u062f \u0639\u0644\u0627\u0648\u0647 \u0628\u0631 Push \u062f\u0631 Backend \u0630\u062e\u06cc\u0631\u0647 \u0628\u0634\u0646 \u0648 \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u06cc\u06a9 Inbox \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>notifications\n\nid\nuser_id\ntype\nentity_id\ntitle\nbody\ncreated_at\nread_at\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc Push \u0641\u0642\u0637 \u062e\u0628\u0631 \u0645\u06cc\u062f\u0647 \u06a9\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u062c\u062f\u06cc\u062f\u06cc \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647\u061b \u0645\u0646\u0628\u0639 \u0627\u0635\u0644\u06cc \u062f\u0627\u062f\u0647 API \u0648 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0633\u0631\u0648\u0631\u0647:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">Price changed<br>\u2193<br>Create notification record<br>\u2193<br>Send FCM push<br>\u2193<br>Device displays system notification<br>\u2193<br>App syncs notification inbox<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">API:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface NotificationApi {\n\n    @GET(\"notifications\")\n    suspend fun getNotifications(\n        @Query(\"cursor\")\n        cursor: String?,\n\n        @Query(\"limit\")\n        limit: Int = 30\n    ): NotificationPageDto\n\n    @PATCH(\n        \"notifications\/{id}\/read\"\n    )\n    suspend fun markAsRead(\n        @Path(\"id\")\n        notificationId: Long\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">NotificationApi<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@GET<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;notifications&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getNotifications<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;cursor&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        cursor: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">?,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Query<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;limit&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        limit: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">30<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">NotificationPageDto<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@PATCH<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;notifications\/{id}\/read&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">markAsRead<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Path<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;id&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        notificationId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0627 \u0627\u06cc\u0646 \u0637\u0631\u0627\u062d\u06cc\u060c \u0627\u06af\u0631 Push \u0628\u0647 \u0647\u0631 \u062f\u0644\u06cc\u0644\u06cc \u0646\u0631\u0633\u0647\u060c \u0627\u0639\u0644\u0627\u0646 \u062f\u0627\u062e\u0644 Inbox \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627\u0642\u06cc \u0645\u06cc\u200c\u0645\u0648\u0646\u0647. Push \u06cc\u06a9 \u06a9\u0627\u0646\u0627\u0644 \u062a\u062d\u0648\u06cc\u0644 Best Effort \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0647 \u0648 \u0646\u0628\u0627\u06cc\u062f \u062c\u0627\u06cc \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u06a9\u0633\u0628\u200c\u0648\u06a9\u0627\u0631 \u0631\u0648 \u0628\u06af\u06cc\u0631\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0648\u0644\u0648\u06cc\u062a Normal \u0648 High<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Android \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc FCM \u062f\u0648 \u0627\u0648\u0644\u0648\u06cc\u062a \u0627\u0635\u0644\u06cc \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647: <code>normal<\/code> \u0648 <code>high<\/code>. \u067e\u06cc\u0627\u0645 Normal \u062f\u0631 \u062d\u0627\u0644\u062a \u0645\u0639\u0645\u0648\u0644 \u062a\u062d\u0648\u06cc\u0644 \u062f\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647\u060c \u0627\u0645\u0627 \u0647\u0646\u06af\u0627\u0645 Doze \u0645\u0645\u06a9\u0646\u0647 \u0628\u0631\u0627\u06cc \u062d\u0641\u0638 \u0628\u0627\u062a\u0631\u06cc \u0628\u0647 \u062a\u0623\u062e\u06cc\u0631 \u0628\u06cc\u0641\u062a\u0647. \u067e\u06cc\u0627\u0645 High \u0628\u0631\u0627\u06cc \u0645\u062d\u062a\u0648\u0627\u06cc \u0632\u0645\u0627\u0646\u200c\u062d\u0633\u0627\u0633 \u0648 \u0642\u0627\u0628\u0644\u200c\u0645\u0634\u0627\u0647\u062f\u0647 \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631\u0647 \u0648 FCM \u062a\u0644\u0627\u0634 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0627\u0648\u0646 \u0631\u0648 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u062a\u062d\u0648\u06cc\u0644 \u0628\u062f\u0647 \u0648 \u062f\u0631 \u0635\u0648\u0631\u062a \u0646\u06cc\u0627\u0632 \u062f\u0633\u062a\u06af\u0627\u0647 \u062e\u0648\u0627\u0628\u06cc\u062f\u0647 \u0631\u0648 \u0628\u0631\u0627\u06cc \u067e\u0631\u062f\u0627\u0632\u0634 \u0645\u062d\u062f\u0648\u062f \u0628\u06cc\u062f\u0627\u0631 \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0686\u0646\u06cc\u0646 \u0633\u06cc\u0627\u0633\u062a\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u0631\u0633\u06cc\u062f\u0646 \u0645\u062d\u0635\u0648\u0644 \u0628\u0647 \u0642\u06cc\u0645\u062a \u0647\u062f\u0641:\nHigh\n\n\u0647\u0634\u062f\u0627\u0631 \u0648\u0631\u0648\u062f \u0645\u0634\u06a9\u0648\u06a9:\nHigh\n\n\u06a9\u0627\u0647\u0634 \u0645\u0639\u0645\u0648\u0644\u06cc \u0642\u06cc\u0645\u062a:\nHigh \u06cc\u0627 Normal \u0628\u0631\u0627\u0633\u0627\u0633 \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0627\u0631\u0628\u0631\n\nSync \u06a9\u0631\u062f\u0646 \u062a\u0639\u062f\u0627\u062f \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u062e\u0648\u0627\u0646\u062f\u0647\u200c\u0646\u0634\u062f\u0647:\nNormal\n\n\u062e\u0628\u0631\u0646\u0627\u0645\u0647 \u0648 \u0627\u0637\u0644\u0627\u0639\u06cc\u0647 \u0639\u0645\u0648\u0645\u06cc:\nNormal\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0628\u0627\u06cc\u062f \u0647\u0645\u0647 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627 \u0631\u0648 High \u0628\u0641\u0631\u0633\u062a\u06cc\u0645. \u0627\u06af\u0631 FCM \u062a\u0634\u062e\u06cc\u0635 \u0628\u062f\u0647 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc High \u0628\u0647 \u0627\u0639\u0644\u0627\u0646 \u0642\u0627\u0628\u0644\u200c\u0645\u0634\u0627\u0647\u062f\u0647 \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0645\u0646\u062c\u0631 \u0646\u0645\u06cc\u0634\u0646\u060c \u0645\u0645\u06a9\u0646\u0647 \u0627\u0631\u0633\u0627\u0644\u200c\u0647\u0627\u06cc \u0628\u0639\u062f\u06cc \u0627\u0648\u0646 \u0646\u0645\u0648\u0646\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u0628\u0647 Normal \u062a\u0646\u0632\u0644 \u0628\u062f\u0647. \u062a\u0635\u0645\u06cc\u0645 FCM \u0628\u0627 \u0646\u06af\u0627\u0647 \u0628\u0647 \u0631\u0641\u062a\u0627\u0631 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc \u0686\u0646\u062f \u0631\u0648\u0632 \u0627\u062e\u06cc\u0631 \u0628\u0631\u0627\u06cc \u0647\u0631 App Instance \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0645\u0648\u0646\u0647 \u0627\u0631\u0633\u0627\u0644 \u0628\u0627 Admin SDK \u062f\u0631 Node.js:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>import {\n  getMessaging\n} from \"firebase-admin\/messaging\";\n\nexport async function sendPriceDrop({\n  token,\n  eventId,\n  productId,\n  title,\n  body\n}) {\n  const message = {\n    token,\n\n    data: {\n      type: \"PRICE_DROP\",\n      schemaVersion: \"1\",\n      eventId,\n      entityId: String(productId),\n      title,\n      body,\n      channel: \"price_alerts\",\n      route: `product\/${productId}`,\n      createdAt: new Date().toISOString()\n    },\n\n    android: {\n      priority: \"high\",\n      ttl: 12 * 60 * 60 * 1000,\n      collapseKey: `price_${productId}`\n    }\n  };\n\n  return getMessaging().send(message);\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">import<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  getMessaging<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">} from <\/span><span style=\"color: #032F62\">&quot;firebase-admin\/messaging&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">export async function <\/span><span style=\"color: #6F42C1\">sendPriceDrop<\/span><span style=\"color: #24292E\">({<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  token,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  eventId,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  productId,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  title,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  body<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> message <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    token,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      type: <\/span><span style=\"color: #032F62\">&quot;PRICE_DROP&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      schemaVersion: <\/span><span style=\"color: #032F62\">&quot;1&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      eventId,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      entityId: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #6F42C1\">productId<\/span><span style=\"color: #24292E\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      title,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      body,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      channel: <\/span><span style=\"color: #032F62\">&quot;price_alerts&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      route: `product<\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #24292E\">${productId}`,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      createdAt: <\/span><span style=\"color: #6F42C1\">new<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Date<\/span><span style=\"color: #24292E\">().<\/span><span style=\"color: #6F42C1\">toISOString<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    android: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      priority: <\/span><span style=\"color: #032F62\">&quot;high&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      ttl: <\/span><span style=\"color: #6F42C1\">12<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">60<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">60<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1000<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      collapseKey: `price_${productId}`<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  };<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getMessaging<\/span><span style=\"color: #24292E\">().<\/span><span style=\"color: #6F42C1\">send<\/span><span style=\"color: #24292E\">(message);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u06a9\u062a\u0647 \u0645\u0647\u0645 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u062a\u0645\u0627\u0645 \u0645\u0642\u0627\u062f\u06cc\u0631 \u062f\u0627\u062e\u0644 <code>data<\/code> \u0628\u0627\u06cc\u062f String \u0628\u0627\u0634\u0646. \u0628\u0631\u0627\u06cc \u0647\u0645\u06cc\u0646 <code>productId<\/code> \u0648 <code>schemaVersion<\/code> \u0631\u0648 \u0628\u0647 String \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u062f\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">TTL\u061b \u0627\u0639\u0644\u0627\u0646 \u0642\u062f\u06cc\u0645\u06cc \u062a\u0627 \u0686\u0647 \u0632\u0645\u0627\u0646\u06cc \u0627\u0631\u0632\u0634 \u062f\u0627\u0631\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">TTL \u06cc\u0627 Time To Live \u0645\u0634\u062e\u0635 \u0645\u06cc\u200c\u06a9\u0646\u0647 FCM \u062a\u0627 \u0686\u0647 \u0645\u062f\u062a \u062a\u0644\u0627\u0634 \u06a9\u0646\u0647 \u067e\u06cc\u0627\u0645 \u062a\u062d\u0648\u06cc\u0644\u200c\u0646\u0634\u062f\u0647 \u0631\u0648 \u0646\u06af\u0647 \u062f\u0627\u0631\u0647. \u0641\u0631\u0636 \u06a9\u0646 \u06af\u0648\u0634\u06cc \u06a9\u0627\u0631\u0628\u0631 \u062f\u0648 \u0631\u0648\u0632 \u062e\u0627\u0645\u0648\u0634 \u0628\u0648\u062f\u0647 \u0648 \u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644 \u062f\u06cc\u0631\u0648\u0632 \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0647\u060c \u0627\u0645\u0627 \u0627\u0645\u0631\u0648\u0632 \u062f\u0648\u0628\u0627\u0631\u0647 \u0627\u0641\u0632\u0627\u06cc\u0634 \u06cc\u0627\u0641\u062a\u0647. \u0646\u0645\u0627\u06cc\u0634 \u0627\u0639\u0644\u0627\u0646 \u0642\u062f\u06cc\u0645\u06cc \u00ab\u0642\u06cc\u0645\u062a \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u00bb \u0628\u0639\u062f \u0627\u0632 \u0631\u0648\u0634\u0646 \u0634\u062f\u0646 \u06af\u0648\u0634\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u06af\u0645\u0631\u0627\u0647\u200c\u06a9\u0646\u0646\u062f\u0647 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0647\u0631 \u0646\u0648\u0639 \u0631\u0648\u06cc\u062f\u0627\u062f \u0628\u0627\u06cc\u062f TTL \u0645\u062a\u0646\u0627\u0633\u0628 \u062a\u0639\u06cc\u06cc\u0646 \u06a9\u0646\u06cc\u0645:<br>\u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0633\u0631\u06cc\u0639:<br>\u06f6 \u062a\u0627 \u06f1\u06f2 \u0633\u0627\u0639\u062a<br><br>\u0631\u0633\u06cc\u062f\u0646 \u0628\u0647 \u0642\u06cc\u0645\u062a \u0647\u062f\u0641:<br>\u06f1\u06f2 \u062a\u0627 \u06f2\u06f4 \u0633\u0627\u0639\u062a<br><br>\u0647\u0634\u062f\u0627\u0631 \u0627\u0645\u0646\u06cc\u062a\u06cc \u062d\u0633\u0627\u0628:<br>\u0686\u0646\u062f \u0631\u0648\u0632<br><br>\u062e\u0628\u0631\u0646\u0627\u0645\u0647:<br>\u06cc\u06a9 \u062a\u0627 \u0633\u0647 \u0631\u0648\u0632<br><br>\u062f\u0631\u062e\u0648\u0627\u0633\u062a Sync:<br>\u06a9\u0648\u062a\u0627\u0647 \u0648 Collapsible<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">TTL \u06a9\u0648\u062a\u0627\u0647 \u0628\u0647 \u0627\u06cc\u0646 \u0645\u0639\u0646\u06cc \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0627\u0632 Inbox \u0628\u0631\u0646\u0627\u0645\u0647 \u062d\u0630\u0641 \u0628\u0634\u0647. \u0641\u0642\u0637 \u0645\u06cc\u06af\u0647 \u0627\u0639\u0644\u0627\u0646 Push \u0642\u062f\u06cc\u0645\u06cc \u062f\u06cc\u06af\u0647 \u0646\u0628\u0627\u06cc\u062f \u0628\u0647 \u062f\u0633\u062a\u06af\u0627\u0647 \u062a\u062d\u0648\u06cc\u0644 \u062f\u0627\u062f\u0647 \u0628\u0634\u0647. \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0648\u0627\u0642\u0639\u06cc \u0647\u0645\u0686\u0646\u0627\u0646 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0627\u0632 API \u062f\u0631\u06cc\u0627\u0641\u062a \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Collapsible \u0648 Non-collapsible<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u067e\u06cc\u0627\u0645 <strong>Non-collapsible<\/strong> \u0647\u0631 \u067e\u06cc\u0627\u0645 \u0627\u0647\u0645\u06cc\u062a \u0645\u0633\u062a\u0642\u0644 \u062f\u0627\u0631\u0647 \u0648 \u0628\u0627\u06cc\u062f \u062c\u062f\u0627\u06af\u0627\u0646\u0647 \u062a\u062d\u0648\u06cc\u0644 \u062f\u0627\u062f\u0647 \u0628\u0634\u0647\u061b \u0645\u062b\u0644\u0627\u064b \u062f\u0648 \u067e\u06cc\u0627\u0645 \u0686\u062a \u06cc\u0627 \u062f\u0648 \u0647\u0634\u062f\u0627\u0631 \u0627\u0645\u0646\u06cc\u062a\u06cc \u0645\u0633\u062a\u0642\u0644. \u062f\u0631 \u067e\u06cc\u0627\u0645 <strong>Collapsible<\/strong>\u060c \u067e\u06cc\u0627\u0645 \u062c\u062f\u06cc\u062f\u062a\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u067e\u06cc\u0627\u0645 \u062a\u062d\u0648\u06cc\u0644\u200c\u0646\u0634\u062f\u0647 \u0642\u062f\u06cc\u0645\u06cc \u0631\u0648 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u06a9\u0646\u0647\u061b \u0645\u062b\u0644\u0627\u064b \u0686\u0646\u062f \u067e\u06cc\u0627\u0645 \u067e\u0634\u062a \u0633\u0631 \u0647\u0645 \u06a9\u0647 \u0641\u0642\u0637 \u0645\u06cc\u06af\u0646 \u00ab\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0648 Sync \u06a9\u0646\u00bb. FCM \u062a\u0631\u062a\u06cc\u0628 \u062a\u062d\u0648\u06cc\u0644 \u0631\u0648 \u062a\u0636\u0645\u06cc\u0646 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc Collapsible \u0647\u0631 Registration \u062f\u0631 \u06cc\u06a9 \u0632\u0645\u0627\u0646 \u0641\u0642\u0637 \u062a\u0639\u062f\u0627\u062f \u0645\u062d\u062f\u0648\u062f\u06cc Collapse Key \u0645\u062a\u0641\u0627\u0648\u062a \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc Sync \u0639\u0645\u0648\u0645\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>const message = {\n  token,\n\n  data: {\n    type: \"SYNC_PRODUCTS\",\n    schemaVersion: \"1\",\n    eventId\n  },\n\n  android: {\n    priority: \"normal\",\n    collapseKey: \"sync_products\",\n    ttl: 15 * 60 * 1000\n  }\n};\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> message <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  token,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    type: <\/span><span style=\"color: #032F62\">&quot;SYNC_PRODUCTS&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    schemaVersion: <\/span><span style=\"color: #032F62\">&quot;1&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  android: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    priority: <\/span><span style=\"color: #032F62\">&quot;normal&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    collapseKey: <\/span><span style=\"color: #032F62\">&quot;sync_products&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ttl: <\/span><span style=\"color: #6F42C1\">15<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">60<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">};<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0633\u0647 \u067e\u06cc\u0627\u0645 <code>sync_products<\/code> \u062f\u0631 \u0645\u062f\u062a \u0622\u0641\u0644\u0627\u06cc\u0646 \u0628\u0648\u062f\u0646 \u062f\u0633\u062a\u06af\u0627\u0647 \u0627\u06cc\u062c\u0627\u062f \u0628\u0634\u0647\u060c \u0641\u0642\u0637 \u062a\u0627\u0632\u0647\u200c\u062a\u0631\u06cc\u0646 \u067e\u06cc\u0627\u0645 \u0627\u0647\u0645\u06cc\u062a \u062f\u0627\u0631\u0647\u061b \u0686\u0648\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0639\u062f \u0627\u0632 \u062f\u0631\u06cc\u0627\u0641\u062a \u0627\u0648\u0646\u060c \u0648\u0636\u0639\u06cc\u062a \u0646\u0647\u0627\u06cc\u06cc \u0631\u0648 \u0627\u0632 API \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0628\u0631\u0627\u06cc \u0647\u0634\u062f\u0627\u0631 \u0627\u0645\u0646\u06cc\u062a\u06cc \u0645\u0633\u062a\u0642\u0644 \u0627\u0632 Collapse Key \u0645\u0634\u062a\u0631\u06a9 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>const message = {\n  token,\n\n  data: {\n    type: \"ACCOUNT_WARNING\",\n    schemaVersion: \"1\",\n    eventId,\n    title: \"\u0648\u0631\u0648\u062f \u062c\u062f\u06cc\u062f \u0628\u0647 \u062d\u0633\u0627\u0628\",\n    body: \"\u0648\u0631\u0648\u062f \u062a\u0627\u0632\u0647\u200c\u0627\u06cc \u0627\u0632 \u06cc\u06a9 \u062f\u0633\u062a\u06af\u0627\u0647 \u0646\u0627\u0634\u0646\u0627\u0633 \u062b\u0628\u062a \u0634\u062f.\",\n    route: \"security\/sessions\",\n    createdAt: new Date().toISOString()\n  },\n\n  android: {\n    priority: \"high\",\n    ttl: 3 * 24 * 60 * 60 * 1000\n  }\n};\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> message <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  token,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    type: <\/span><span style=\"color: #032F62\">&quot;ACCOUNT_WARNING&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    schemaVersion: <\/span><span style=\"color: #032F62\">&quot;1&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    eventId,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    title: <\/span><span style=\"color: #032F62\">&quot;\u0648\u0631\u0648\u062f \u062c\u062f\u06cc\u062f \u0628\u0647 \u062d\u0633\u0627\u0628&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    body: <\/span><span style=\"color: #032F62\">&quot;\u0648\u0631\u0648\u062f \u062a\u0627\u0632\u0647\u200c\u0627\u06cc \u0627\u0632 \u06cc\u06a9 \u062f\u0633\u062a\u06af\u0627\u0647 \u0646\u0627\u0634\u0646\u0627\u0633 \u062b\u0628\u062a \u0634\u062f.&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    route: <\/span><span style=\"color: #032F62\">&quot;security\/sessions&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    createdAt: <\/span><span style=\"color: #6F42C1\">new<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Date<\/span><span style=\"color: #24292E\">().<\/span><span style=\"color: #6F42C1\">toISOString<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  android: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    priority: <\/span><span style=\"color: #032F62\">&quot;high&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ttl: <\/span><span style=\"color: #6F42C1\">3<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">24<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">60<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">60<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">};<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0635\u0648\u06cc\u0631 \u0628\u0632\u0631\u06af \u0631\u0648 \u062f\u0627\u062e\u0644 Service \u062f\u0627\u0646\u0644\u0648\u062f \u0646\u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0646\u0645\u0627\u06cc\u0634 <code>BigPictureStyle<\/code> \u0645\u0645\u06a9\u0646\u0647 \u0628\u062e\u0648\u0627\u06cc\u0645 \u062a\u0635\u0648\u06cc\u0631 \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 \u062f\u0627\u0646\u0644\u0648\u062f \u06a9\u0646\u06cc\u0645. \u0627\u0645\u0627 <code>onMessageReceived()<\/code> \u0628\u0631\u0627\u06cc \u067e\u0631\u062f\u0627\u0632\u0634 \u06a9\u0648\u062a\u0627\u0647 \u0637\u0631\u0627\u062d\u06cc \u0634\u062f\u0647 \u0648 \u062a\u0645\u0627\u0633 \u0634\u0628\u06a9\u0647\u200c\u0627\u06cc \u0637\u0648\u0644\u0627\u0646\u06cc \u062f\u0627\u062e\u0644 \u0627\u0648\u0646 \u0642\u0627\u0628\u0644\u200c\u0627\u0639\u062a\u0645\u0627\u062f \u0646\u06cc\u0633\u062a. \u062a\u0648\u0635\u06cc\u0647 \u0631\u0633\u0645\u06cc \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0627\u0639\u0644\u0627\u0646 \u0627\u0635\u0644\u06cc \u0631\u0648 \u0633\u0631\u06cc\u0639 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u06cc\u0645 \u0648 \u0627\u06af\u0631 \u067e\u0631\u062f\u0627\u0632\u0634 \u0637\u0648\u0644\u0627\u0646\u06cc\u200c\u062a\u0631\u06cc \u0645\u062b\u0644 \u062f\u0631\u06cc\u0627\u0641\u062a \u062a\u0635\u0648\u06cc\u0631 \u0644\u0627\u0632\u0645\u0647\u060c WorkManager \u0631\u0648 \u0627\u062c\u0631\u0627 \u06a9\u0646\u06cc\u0645. \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u0645 High \u0645\u06cc\u0634\u0647 \u0628\u0644\u0627\u0641\u0627\u0635\u0644\u0647 \u06cc\u06a9 Expedited Work \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u0631\u062f \u0648 \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u0645 Normal \u0627\u0632 Work \u0645\u0639\u0645\u0648\u0644\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0648\u0644 \u0627\u0639\u0644\u0627\u0646 \u0645\u062a\u0646\u06cc \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u200c\u062f\u06cc\u0645\u060c \u0633\u067e\u0633 Worker \u062a\u0635\u0648\u06cc\u0631 \u0631\u0648 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647 \u0648 \u0647\u0645\u0648\u0646 Notification ID \u0631\u0648 Update \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun enqueueImageWorker(\n    context: Context,\n    payload: PushPayload\n) {\n    val imageUrl =\n        payload.imageUrl ?: return\n\n    val inputData = workDataOf(\n        \"event_id\" to payload.eventId,\n        \"entity_id\" to payload.entityId,\n        \"title\" to payload.title,\n        \"body\" to payload.body,\n        \"image_url\" to imageUrl\n    )\n\n    val request =\n        OneTimeWorkRequestBuilder&lt;\n            NotificationImageWorker\n        >()\n            .setInputData(inputData)\n            .setExpedited(\n                OutOfQuotaPolicy\n                    .RUN_AS_NON_EXPEDITED_WORK_REQUEST\n            )\n            .build()\n\n    WorkManager\n        .getInstance(context)\n        .enqueueUniqueWork(\n            \"push_image_${payload.eventId}\",\n            ExistingWorkPolicy.KEEP,\n            request\n        )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">enqueueImageWorker<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    context: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> imageUrl <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload.imageUrl ?: <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> inputData <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">workDataOf<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;event_id&quot;<\/span><span style=\"color: #24292E\"> to payload.eventId,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;entity_id&quot;<\/span><span style=\"color: #24292E\"> to payload.entityId,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;title&quot;<\/span><span style=\"color: #24292E\"> to payload.title,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;body&quot;<\/span><span style=\"color: #24292E\"> to payload.body,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;image_url&quot;<\/span><span style=\"color: #24292E\"> to imageUrl<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> request <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        OneTimeWorkRequestBuilder<\/span><span style=\"color: #D73A49\">&lt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            NotificationImageWorker<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setInputData<\/span><span style=\"color: #24292E\">(inputData)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">setExpedited<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                OutOfQuotaPolicy<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .RUN_AS_NON_EXPEDITED_WORK_REQUEST<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    WorkManager<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">getInstance<\/span><span style=\"color: #24292E\">(context)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">enqueueUniqueWork<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;push_image_${payload.eventId}&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ExistingWorkPolicy.KEEP,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            request<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Worker:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class NotificationImageWorker(\n    appContext: Context,\n    workerParameters: WorkerParameters,\n    private val imageLoader:\n        PushImageLoader\n) : CoroutineWorker(\n    appContext,\n    workerParameters\n) {\n\n    override suspend fun doWork():\n        Result {\n\n        val imageUrl =\n            inputData.getString(\n                \"image_url\"\n            ) ?: return Result.failure()\n\n        val title =\n            inputData.getString(\n                \"title\"\n            ).orEmpty()\n\n        val body =\n            inputData.getString(\n                \"body\"\n            ).orEmpty()\n\n        val eventId =\n            inputData.getString(\n                \"event_id\"\n            ) ?: return Result.failure()\n\n        val bitmap = try {\n            imageLoader.load(imageUrl)\n        } catch (\n            exception: IOException\n        ) {\n            return Result.retry()\n        }\n\n        val notification =\n            NotificationCompat.Builder(\n                applicationContext,\n                NotificationChannels\n                    .PRICE_ALERTS\n            )\n                .setSmallIcon(\n                    R.drawable.ic_notification\n                )\n                .setContentTitle(title)\n                .setContentText(body)\n                .setStyle(\n                    NotificationCompat\n                        .BigPictureStyle()\n                        .bigPicture(bitmap)\n                        .bigLargeIcon(null as Bitmap?)\n                        .setSummaryText(body)\n                )\n                .setOnlyAlertOnce(true)\n                .setAutoCancel(true)\n                .build()\n\n        NotificationManagerCompat\n            .from(applicationContext)\n            .notify(\n                eventId.hashCode(),\n                notification\n            )\n\n        return Result.success()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">NotificationImageWorker<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    appContext: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    workerParameters: <\/span><span style=\"color: #6F42C1\">WorkerParameters<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> imageLoader:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        PushImageLoader<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">CoroutineWorker<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    appContext,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    workerParameters<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">doWork<\/span><span style=\"color: #24292E\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">Result<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> imageUrl <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            inputData.<\/span><span style=\"color: #6F42C1\">getString<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;image_url&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ) ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> Result.<\/span><span style=\"color: #6F42C1\">failure<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> title <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            inputData.<\/span><span style=\"color: #6F42C1\">getString<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;title&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ).<\/span><span style=\"color: #6F42C1\">orEmpty<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> body <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            inputData.<\/span><span style=\"color: #6F42C1\">getString<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;body&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ).<\/span><span style=\"color: #6F42C1\">orEmpty<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> eventId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            inputData.<\/span><span style=\"color: #6F42C1\">getString<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;event_id&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ) ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> Result.<\/span><span style=\"color: #6F42C1\">failure<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> bitmap <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            imageLoader.<\/span><span style=\"color: #6F42C1\">load<\/span><span style=\"color: #24292E\">(imageUrl)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        } <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            exception: <\/span><span style=\"color: #6F42C1\">IOException<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> Result.<\/span><span style=\"color: #6F42C1\">retry<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> notification <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            NotificationCompat.<\/span><span style=\"color: #6F42C1\">Builder<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                applicationContext,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                NotificationChannels<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .PRICE_ALERTS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setSmallIcon<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    R.drawable.ic_notification<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setContentTitle<\/span><span style=\"color: #24292E\">(title)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setContentText<\/span><span style=\"color: #24292E\">(body)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setStyle<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    NotificationCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">BigPictureStyle<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">bigPicture<\/span><span style=\"color: #24292E\">(bitmap)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">bigLargeIcon<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">as<\/span><span style=\"color: #24292E\"> Bitmap?)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">setSummaryText<\/span><span style=\"color: #24292E\">(body)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setOnlyAlertOnce<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">setAutoCancel<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">build<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        NotificationManagerCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">from<\/span><span style=\"color: #24292E\">(applicationContext)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">notify<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                eventId.<\/span><span style=\"color: #6F42C1\">hashCode<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                notification<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> Result.<\/span><span style=\"color: #6F42C1\">success<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0646\u0633\u062e\u0647 \u06a9\u0627\u0645\u0644 \u0628\u0627\u06cc\u062f \u0647\u0645\u0648\u0646 Channel\u060c PendingIntent\u060c Group \u0648 Notification ID \u0627\u0639\u0644\u0627\u0646 \u0627\u0648\u0644\u06cc\u0647 \u0631\u0648 \u062f\u0648\u0628\u0627\u0631\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645 \u062a\u0627 \u0627\u0639\u0644\u0627\u0646 \u062a\u0627\u0632\u0647\u200c\u0627\u06cc \u0633\u0627\u062e\u062a\u0647 \u0646\u0634\u0647 \u0648 \u0641\u0642\u0637 \u0638\u0627\u0647\u0631 \u0642\u0628\u0644\u06cc Update \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0627\u0639\u0644\u0627\u0646 \u062f\u0631 \u062f\u0648 \u0633\u0637\u062d<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0627\u0639\u0644\u0627\u0646 \u062f\u0648 \u0633\u0637\u062d \u062f\u0627\u0631\u0646. \u0633\u0637\u062d \u0627\u0648\u0644 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u062f\u0627\u062e\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0647\u0633\u062a:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0634\u062f\u0627\u0631 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a: \u0631\u0648\u0634\u0646\n\u0631\u0633\u06cc\u062f\u0646 \u0628\u0647 \u0642\u06cc\u0645\u062a \u0647\u062f\u0641: \u0631\u0648\u0634\u0646\n\u0645\u0648\u062c\u0648\u062f \u0634\u062f\u0646 \u0645\u062d\u0635\u0648\u0644: \u062e\u0627\u0645\u0648\u0634\n\u0627\u0637\u0644\u0627\u0639\u06cc\u0647\u200c\u0647\u0627\u06cc \u0639\u0645\u0648\u0645\u06cc: \u062e\u0627\u0645\u0648\u0634\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u0637\u062d \u062f\u0648\u0645 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0633\u06cc\u0633\u062a\u0645 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u0647\u061b \u06cc\u0639\u0646\u06cc Permission \u06a9\u0644\u06cc \u0648 Channel\u0647\u0627. \u0641\u0639\u0627\u0644 \u0628\u0648\u062f\u0646 \u06af\u0632\u06cc\u0646\u0647 \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u0636\u0645\u06cc\u0646 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647 Channel \u06cc\u0627 Permission \u0633\u06cc\u0633\u062a\u0645 \u0647\u0645 \u0641\u0639\u0627\u0644 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062f\u0644 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class PushPreferences(\n    val priceDropsEnabled: Boolean,\n    val targetReachedEnabled: Boolean,\n    val availabilityEnabled: Boolean,\n    val generalEnabled: Boolean\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushPreferences<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> priceDropsEnabled: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> targetReachedEnabled: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> availabilityEnabled: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> generalEnabled: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">API:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface PushPreferenceApi {\n\n    @GET(\"push\/preferences\")\n    suspend fun getPreferences():\n        PushPreferencesDto\n\n    @PUT(\"push\/preferences\")\n    suspend fun updatePreferences(\n        @Body preferences:\n            UpdatePushPreferencesRequest\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushPreferenceApi<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@GET<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;push\/preferences&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getPreferences<\/span><span style=\"color: #24292E\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        PushPreferencesDto<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@PUT<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;push\/preferences&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">updatePreferences<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@Body<\/span><span style=\"color: #24292E\"> preferences:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            UpdatePushPreferencesRequest<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0628\u0627\u06cc\u062f \u0631\u0648\u06cc Backend \u0647\u0645 \u0630\u062e\u06cc\u0631\u0647 \u0628\u0634\u0646\u060c \u0646\u0647 \u0641\u0642\u0637 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc. \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u00ab\u0627\u0637\u0644\u0627\u0639\u06cc\u0647\u200c\u0647\u0627\u06cc \u0639\u0645\u0648\u0645\u06cc\u00bb \u0631\u0648 \u062e\u0627\u0645\u0648\u0634 \u06a9\u0631\u062f\u0647\u060c \u0628\u0647\u062a\u0631\u0647 \u0633\u0631\u0648\u0631 \u0627\u0635\u0644\u0627\u064b \u0627\u06cc\u0646 \u0646\u0648\u0639 Push \u0631\u0648 \u062a\u0648\u0644\u06cc\u062f \u0646\u06a9\u0646\u0647\u061b \u0646\u0647 \u0627\u06cc\u0646\u06a9\u0647 \u067e\u06cc\u0627\u0645 \u0631\u0648 \u0628\u0641\u0631\u0633\u062a\u0647 \u0648 Client \u0628\u0639\u062f \u0627\u0632 \u0645\u0635\u0631\u0641 \u0634\u0628\u06a9\u0647 \u0627\u0648\u0646 \u0631\u0648 \u062f\u0648\u0631 \u0628\u0646\u062f\u0627\u0632\u0647. Client \u0647\u0645\u0686\u0646\u0627\u0646 \u0628\u0627\u06cc\u062f \u0628\u0631\u0627\u06cc \u062f\u0641\u0627\u0639 \u0646\u0647\u0627\u06cc\u06cc \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0645\u062d\u0644\u06cc \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u0647\u060c \u0627\u0645\u0627 \u0641\u06cc\u0644\u062a\u0631 \u0627\u0635\u0644\u06cc \u0628\u0627\u06cc\u062f \u0633\u0645\u062a Backend \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Topic \u0628\u0631\u0627\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0639\u0645\u0648\u0645\u06cc\u060c \u0646\u0647 \u067e\u06cc\u0627\u0645 \u062e\u0635\u0648\u0635\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Topic Messaging \u0628\u0631\u0627\u06cc \u0627\u0631\u0633\u0627\u0644 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0639\u0645\u0648\u0645\u06cc \u0628\u0647 \u062a\u0639\u062f\u0627\u062f \u0632\u06cc\u0627\u062f\u06cc \u062f\u0633\u062a\u06af\u0627\u0647 \u0645\u0646\u0627\u0633\u0628\u0647\u061b \u0645\u062b\u0644\u0627\u064b \u0627\u0637\u0644\u0627\u0639\u06cc\u0647 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u06cc\u0627 \u062e\u0628\u0631 \u0639\u0645\u0648\u0645\u06cc. Topic\u0647\u0627 \u0628\u0631\u0627\u06cc Throughput \u0628\u0647\u06cc\u0646\u0647 \u0634\u062f\u0646\u060c \u0646\u0647 \u062a\u062d\u0648\u06cc\u0644 \u06a9\u0645\u200c\u062a\u0623\u062e\u06cc\u0631 \u0628\u0647 \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 \u06cc\u0627 \u06af\u0631\u0648\u0647 \u06a9\u0648\u0686\u06a9. \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u0645 \u062e\u0635\u0648\u0635\u06cc \u0648 \u0633\u0631\u06cc\u0639 \u0628\u0647\u062a\u0631\u0647 Registration\u0647\u0627\u06cc \u0645\u0634\u062e\u0635 \u06a9\u0627\u0631\u0628\u0631 \u0647\u062f\u0641 \u0642\u0631\u0627\u0631 \u0628\u06af\u06cc\u0631\u0646. \u0647\u0631 \u0646\u0645\u0648\u0646\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645 \u062d\u062f\u0627\u06a9\u062b\u0631 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062f\u0631 \u06f2\u06f0\u06f0\u06f0 Topic \u0639\u0636\u0648 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0639\u0636\u0648\u06cc\u062a \u062f\u0631 Topic:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun subscribeToGeneralNews() {\n    FirebaseMessaging\n        .getInstance()\n        .subscribeToTopic(\n            \"general_news_fa\"\n        )\n        .await()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">subscribeToGeneralNews<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    FirebaseMessaging<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">getInstance<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">subscribeToTopic<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;general_news_fa&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">await<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0644\u063a\u0648 \u0639\u0636\u0648\u06cc\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun unsubscribeFromGeneralNews() {\n    FirebaseMessaging\n        .getInstance()\n        .unsubscribeFromTopic(\n            \"general_news_fa\"\n        )\n        .await()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">unsubscribeFromGeneralNews<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    FirebaseMessaging<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">getInstance<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">unsubscribeFromTopic<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;general_news_fa&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">await<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0631\u0633\u0627\u0644 \u0627\u0632 Backend:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>const message = {\n  topic: \"general_news_fa\",\n\n  notification: {\n    title: \"\u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646\",\n    body: \"\u0627\u0645\u06a9\u0627\u0646 \u0645\u0642\u0627\u06cc\u0633\u0647 \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0642\u06cc\u0645\u062a \u0627\u0636\u0627\u0641\u0647 \u0634\u062f.\"\n  },\n\n  data: {\n    type: \"GENERAL_ANNOUNCEMENT\",\n    route: \"updates\/42\"\n  },\n\n  android: {\n    priority: \"normal\"\n  }\n};\n\nawait getMessaging().send(message);\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> message <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  topic: <\/span><span style=\"color: #032F62\">&quot;general_news_fa&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  notification: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    title: <\/span><span style=\"color: #032F62\">&quot;\u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    body: <\/span><span style=\"color: #032F62\">&quot;\u0627\u0645\u06a9\u0627\u0646 \u0645\u0642\u0627\u06cc\u0633\u0647 \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0642\u06cc\u0645\u062a \u0627\u0636\u0627\u0641\u0647 \u0634\u062f.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    type: <\/span><span style=\"color: #032F62\">&quot;GENERAL_ANNOUNCEMENT&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    route: <\/span><span style=\"color: #032F62\">&quot;updates\/42&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  android: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    priority: <\/span><span style=\"color: #032F62\">&quot;normal&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">};<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">await <\/span><span style=\"color: #6F42C1\">getMessaging<\/span><span style=\"color: #24292E\">().<\/span><span style=\"color: #6F42C1\">send<\/span><span style=\"color: #24292E\">(message);<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0646\u0628\u0627\u06cc\u062f Topic\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 \u0627\u06cc\u0646 \u0628\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>user_42\nuser_583\naccount_1024\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Topic \u0633\u0627\u0632\u0648\u06a9\u0627\u0631 \u06a9\u0646\u062a\u0631\u0644 \u062f\u0633\u062a\u0631\u0633\u06cc \u0628\u0631\u0627\u06cc \u062f\u0627\u062f\u0647 \u062e\u0635\u0648\u0635\u06cc \u0646\u06cc\u0633\u062a. \u0628\u0631\u0646\u0627\u0645\u0647 Client \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0639\u0636\u0648\u06cc\u062a Topic \u0631\u0648 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u0646\u0647 \u0648 \u0646\u0627\u0645 Topic \u0647\u0645 \u0646\u0628\u0627\u06cc\u062f \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 \u0645\u0631\u0632 \u0627\u0645\u0646\u06cc\u062a\u06cc \u062f\u0631 \u0646\u0638\u0631 \u06af\u0631\u0641\u062a\u0647 \u0628\u0634\u0647. \u067e\u06cc\u0627\u0645 \u0634\u062e\u0635\u06cc \u0628\u0627\u06cc\u062f \u0628\u0631\u0627\u0633\u0627\u0633 Registration\u0647\u0627\u06cc \u062b\u0628\u062a\u200c\u0634\u062f\u0647 \u0648 \u0645\u062c\u0627\u0632 \u0647\u0645\u0648\u0646 \u062d\u0633\u0627\u0628 \u0627\u0632 Backend \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u067e\u0627\u06a9\u200c\u0633\u0627\u0632\u06cc Token\u0647\u0627\u06cc \u0646\u0627\u0645\u0639\u062a\u0628\u0631<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc Backend \u0628\u0631\u0627\u06cc Token \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u067e\u06cc\u0627\u0645 \u0645\u06cc\u200c\u0641\u0631\u0633\u062a\u0647\u060c Admin SDK \u062e\u0637\u0627\u06cc\u06cc \u0628\u0631\u0645\u06cc\u200c\u06af\u0631\u062f\u0648\u0646\u0647. Token\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0628\u0647\u200c\u0635\u0648\u0631\u062a \u0642\u0637\u0639\u06cc \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u06cc\u0627 \u062b\u0628\u062a\u200c\u0646\u0634\u062f\u0647 \u0647\u0633\u062a\u0646 \u0628\u0627\u06cc\u062f \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u06cc\u0627 \u062d\u0630\u0641 \u0628\u0634\u0646\u061b \u0648\u06af\u0631\u0646\u0647 \u0628\u0627 \u0631\u0634\u062f \u06a9\u0627\u0631\u0628\u0631\u0627\u0646\u060c \u0633\u0631\u0648\u0631 \u0628\u062e\u0634 \u0628\u0632\u0631\u06af\u06cc \u0627\u0632 \u0645\u0646\u0627\u0628\u0639 \u0627\u0631\u0633\u0627\u0644 \u0631\u0648 \u0635\u0631\u0641 \u062f\u0633\u062a\u06af\u0627\u0647\u200c\u0647\u0627\u06cc\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647 \u06a9\u0647 \u062f\u06cc\u06af\u0647 \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u0646. Firebase \u0647\u0645 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647 Registration\u0647\u0627 \u0647\u0645\u0631\u0627\u0647 Timestamp \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0648 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0642\u062f\u06cc\u0645\u06cc \u0628\u0647\u200c\u0634\u06a9\u0644 \u0641\u0639\u0627\u0644 \u067e\u0627\u06a9\u200c\u0633\u0627\u0632\u06cc \u0628\u0634\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0645\u0648\u0646\u0647 \u0627\u0631\u0633\u0627\u0644 \u0648 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644\u200c\u0633\u0627\u0632\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>import {\n  getMessaging\n} from \"firebase-admin\/messaging\";\n\nexport async function sendToRegistration(\n  registration,\n  messageData,\n  registrationRepository\n) {\n  try {\n    const response =\n      await getMessaging().send({\n        token: registration.fcmToken,\n        data: messageData,\n        android: {\n          priority: \"high\",\n          ttl: 12 * 60 * 60 * 1000\n        }\n      });\n\n    await registrationRepository\n      .markSuccessful(\n        registration.id,\n        new Date()\n      );\n\n    return response;\n  } catch (error) {\n    const invalidTokenCodes = new Set(&#91;\n      \"messaging\/registration-token-not-registered\",\n      \"messaging\/invalid-registration-token\"\n    &#93;);\n\n    if (invalidTokenCodes.has(error.code)) {\n      await registrationRepository\n        .revoke(\n          registration.id,\n          new Date()\n        );\n\n      return null;\n    }\n\n    throw error;\n  }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">import<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  getMessaging<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">} from <\/span><span style=\"color: #032F62\">&quot;firebase-admin\/messaging&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">export async function <\/span><span style=\"color: #6F42C1\">sendToRegistration<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  registration,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  messageData,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  registrationRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> response <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      await <\/span><span style=\"color: #6F42C1\">getMessaging<\/span><span style=\"color: #24292E\">().<\/span><span style=\"color: #6F42C1\">send<\/span><span style=\"color: #24292E\">({<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        token: <\/span><span style=\"color: #6F42C1\">registration<\/span><span style=\"color: #24292E\">.fcmToken,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #6F42C1\">messageData<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        android: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">          priority: <\/span><span style=\"color: #032F62\">&quot;high&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">          ttl: <\/span><span style=\"color: #6F42C1\">12<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">60<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">60<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">*<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      });<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    await registrationRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      .<\/span><span style=\"color: #6F42C1\">markSuccessful<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        registration.id,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        new <\/span><span style=\"color: #6F42C1\">Date<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      );<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> response;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  } <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (error) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> invalidTokenCodes <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> new <\/span><span style=\"color: #6F42C1\">Set<\/span><span style=\"color: #24292E\">(&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;messaging\/registration-token-not-registered&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #032F62\">&quot;messaging\/invalid-registration-token&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    &#93;);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (invalidTokenCodes.<\/span><span style=\"color: #6F42C1\">has<\/span><span style=\"color: #24292E\">(error.code)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      await registrationRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">revoke<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">          registration.id,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">          new <\/span><span style=\"color: #6F42C1\">Date<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        );<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">      <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">throw<\/span><span style=\"color: #24292E\"> error;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u0637\u0627\u0647\u0627\u06cc \u0645\u0648\u0642\u062a \u0645\u062b\u0644 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0638\u0631\u0641\u06cc\u062a \u06cc\u0627 \u062e\u0637\u0627\u06cc \u062f\u0627\u062e\u0644\u06cc \u0631\u0648 \u0646\u0628\u0627\u06cc\u062f \u0628\u0647 \u062d\u0630\u0641 Token \u062a\u0639\u0628\u06cc\u0631 \u06a9\u0646\u06cc\u0645. \u0628\u0631\u0627\u06cc \u0627\u06cc\u0646 \u0645\u0648\u0627\u0631\u062f Retry \u0647\u0645\u0631\u0627\u0647 Exponential Backoff \u0648 Jitter \u0644\u0627\u0632\u0645\u0647. \u062f\u0631 \u0627\u0631\u0633\u0627\u0644\u200c\u0647\u0627\u06cc \u062d\u062c\u06cc\u0645 \u0647\u0645 \u0646\u0628\u0627\u06cc\u062f \u0646\u0627\u06af\u0647\u0627\u0646 \u0635\u062f\u0647\u0627 \u0647\u0632\u0627\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0631\u0648 \u062f\u0631 \u06cc\u06a9 \u062b\u0627\u0646\u06cc\u0647 \u0628\u0647 FCM \u0634\u0644\u06cc\u06a9 \u06a9\u0646\u06cc\u0645. FCM \u0628\u0631\u0627\u06cc HTTP v1 \u0633\u0647\u0645\u06cc\u0647 \u0648 \u0645\u062f\u0644 Token Bucket \u062f\u0627\u0631\u0647 \u0648 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u062a\u0631\u0627\u0641\u06cc\u06a9 \u0627\u0631\u0633\u0627\u0644 \u0628\u0647\u200c\u062a\u062f\u0631\u06cc\u062c \u067e\u062e\u0634 \u0628\u0634\u0647 \u0648 \u062f\u0631 \u0645\u0648\u0627\u062c\u0647\u0647 \u0628\u0627 \u062e\u0637\u0627\u0647\u0627\u06cc \u0642\u0627\u0628\u0644\u200c\u062a\u0644\u0627\u0634\u060c Backoff \u0631\u0639\u0627\u06cc\u062a \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Push \u0631\u0648 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0627\u0632 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0627\u0631\u0633\u0627\u0644 \u0646\u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06a9\u0644\u06cc\u062f Service Account \u06cc\u0627 \u0627\u0639\u062a\u0628\u0627\u0631\u0646\u0627\u0645\u0647 \u0627\u0631\u0633\u0627\u0644 FCM \u0646\u0628\u0627\u06cc\u062f \u062f\u0627\u062e\u0644 APK \u0642\u0631\u0627\u0631 \u0628\u06af\u06cc\u0631\u0647. \u0647\u0631 \u0686\u06cc\u0632\u06cc \u06a9\u0647 \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0642\u0631\u0627\u0631 \u0628\u06af\u06cc\u0631\u0647\u060c \u062f\u06cc\u0631 \u06cc\u0627 \u0632\u0648\u062f \u0642\u0627\u0628\u0644 \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u06cc\u0627 \u0633\u0648\u0621\u0627\u0633\u062a\u0641\u0627\u062f\u0647\u200c\u0633\u062a. \u0645\u0639\u0645\u0627\u0631\u06cc \u062f\u0631\u0633\u062a \u0627\u06cc\u0646\u0647:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">Android App<br>\u2193<br>Authenticated API Request<br>\u2193<br>GheimatBan Backend<br>\u2193<br>Business Rules<br>\u2193<br>Firebase Admin SDK \/ HTTP v1<br>\u2193<br>FCM<br>\u2193<br>Target Devices<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644 \u06a9\u0627\u0631\u0628\u0631 \u0646\u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0628\u06af\u0647 \u00ab\u0628\u0647 Token \u0641\u0644\u0627\u0646 \u062f\u0633\u062a\u06af\u0627\u0647 \u0627\u06cc\u0646 \u0645\u062a\u0646 \u0631\u0648 \u0628\u0641\u0631\u0633\u062a\u00bb. Backend \u0627\u0628\u062a\u062f\u0627 \u0645\u062c\u0648\u0632 \u0648 \u0631\u0648\u06cc\u062f\u0627\u062f \u06a9\u0633\u0628\u200c\u0648\u06a9\u0627\u0631\u06cc \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0633\u067e\u0633 \u062e\u0648\u062f\u0634 Payload \u0645\u0639\u062a\u0628\u0631 \u0645\u06cc\u200c\u0633\u0627\u0632\u0647. \u0645\u062d\u06cc\u0637 \u0627\u0631\u0633\u0627\u0644 \u0628\u0627\u06cc\u062f \u0642\u0627\u0628\u0644\u200c\u0627\u0639\u062a\u0645\u0627\u062f \u0628\u0627\u0634\u0647\u061b \u0645\u062b\u0644 Backend \u06cc\u0627 Cloud Functions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u062a\u06cc \u0639\u0646\u0648\u0627\u0646 \u0648 \u0645\u062a\u0646 Push\u0647\u0627\u06cc \u062d\u0633\u0627\u0633 \u0647\u0645 \u0628\u0647\u062a\u0631\u0647 \u062a\u0648\u0633\u0637 Backend \u0627\u0632 Template\u0647\u0627\u06cc \u06a9\u0646\u062a\u0631\u0644\u200c\u0634\u062f\u0647 \u0633\u0627\u062e\u062a\u0647 \u0628\u0634\u0646. \u0642\u0628\u0648\u0644 \u06a9\u0631\u062f\u0646 \u0645\u062a\u0646 \u0622\u0632\u0627\u062f \u0627\u0632 Client \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0633\u06cc\u0633\u062a\u0645 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0628\u0647 \u0627\u0628\u0632\u0627\u0631 Spam \u06cc\u0627 \u0641\u06cc\u0634\u06cc\u0646\u06af \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0648\u0636\u0639\u06cc\u062a Foreground \u0631\u0648 \u0645\u062a\u0641\u0627\u0648\u062a \u0645\u062f\u06cc\u0631\u06cc\u062a \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0647\u0645\u06cc\u0646 \u062d\u0627\u0644\u0627 \u062f\u0627\u062e\u0644 \u0635\u0641\u062d\u0647 \u0645\u062d\u0635\u0648\u0644 \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u0647\u060c \u0646\u0645\u0627\u06cc\u0634 \u06cc\u06a9 \u0627\u0639\u0644\u0627\u0646 \u0633\u06cc\u0633\u062a\u0645\u06cc \u0628\u0631\u0627\u06cc \u0647\u0645\u0648\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u0645\u06a9\u0646\u0647 \u0622\u0632\u0627\u0631\u062f\u0647\u0646\u062f\u0647 \u0628\u0627\u0634\u0647. \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u062f\u0631 Foreground \u0628\u0647\u200c\u062c\u0627\u06cc Notification\u060c Room \u0631\u0648 Sync \u06a9\u0646\u06cc\u0645 \u0648 Snackbar \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u06cc\u0645. \u0627\u0645\u0627 \u062a\u0634\u062e\u06cc\u0635 Foreground \u0628\u0627\u06cc\u062f \u0645\u0631\u06a9\u0632\u06cc \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class AppVisibilityTracker :\n    DefaultLifecycleObserver {\n\n    @Volatile\n    var isForeground: Boolean = false\n        private set\n\n    override fun onStart(\n        owner: LifecycleOwner\n    ) {\n        isForeground = true\n    }\n\n    override fun onStop(\n        owner: LifecycleOwner\n    ) {\n        isForeground = false\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AppVisibilityTracker<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">DefaultLifecycleObserver<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">@Volatile<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> isForeground: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">set<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onStart<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        owner: <\/span><span style=\"color: #6F42C1\">LifecycleOwner<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        isForeground <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onStop<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        owner: <\/span><span style=\"color: #6F42C1\">LifecycleOwner<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        isForeground <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062b\u0628\u062a \u062f\u0631 Application:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class GheimatBanApplication :\n    Application() {\n\n    val visibilityTracker =\n        AppVisibilityTracker()\n\n    override fun onCreate() {\n        super.onCreate()\n\n        ProcessLifecycleOwner\n            .get()\n            .lifecycle\n            .addObserver(\n                visibilityTracker\n            )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">GheimatBanApplication<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">Application<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> visibilityTracker <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">AppVisibilityTracker<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #005CC5\">super<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">onCreate<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ProcessLifecycleOwner<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">get<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .lifecycle<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">addObserver<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                visibilityTracker<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u062f\u0631 Handler:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>if (\n    appVisibilityTracker.isForeground\n) {\n    inAppEventBus.emit(payload)\n} else {\n    notificationFactory.show(payload)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    appVisibilityTracker.isForeground<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    inAppEventBus.<\/span><span style=\"color: #6F42C1\">emit<\/span><span style=\"color: #24292E\">(payload)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">} <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    notificationFactory.<\/span><span style=\"color: #6F42C1\">show<\/span><span style=\"color: #24292E\">(payload)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c Foreground \u0628\u0648\u062f\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647\u200c\u062a\u0646\u0647\u0627\u06cc\u06cc \u06a9\u0627\u0641\u06cc \u0646\u06cc\u0633\u062a. \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631 \u0635\u0641\u062d\u0647\u200c\u0627\u06cc \u0646\u0627\u0645\u0631\u062a\u0628\u0637\u0647\u060c \u0645\u0645\u06a9\u0646\u0647 \u0646\u0645\u0627\u06cc\u0634 Notification \u0647\u0645\u0686\u0646\u0627\u0646 \u0645\u0646\u0627\u0633\u0628 \u0628\u0627\u0634\u0647. \u062a\u0635\u0645\u06cc\u0645 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0628\u0627\u06cc\u062f \u0628\u0631\u0627\u0633\u0627\u0633 \u0646\u0648\u0639 \u0631\u0648\u06cc\u062f\u0627\u062f\u060c \u0635\u0641\u062d\u0647 \u0641\u0639\u0644\u06cc \u0648 \u062a\u0631\u062c\u06cc\u062d \u06a9\u0627\u0631\u0628\u0631 \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0648\u0636\u0639\u06cc\u062a \u062e\u0648\u0627\u0646\u062f\u0647 \u0634\u062f\u0646 \u0648 \u0647\u0645\u0627\u0647\u0646\u06af\u06cc \u0686\u0646\u062f \u062f\u0633\u062a\u06af\u0627\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0627\u0639\u0644\u0627\u0646 \u0628\u0647 \u06af\u0648\u0634\u06cc \u0648 \u062a\u0628\u0644\u062a \u06a9\u0627\u0631\u0628\u0631 \u0631\u0633\u06cc\u062f\u0647. \u06a9\u0627\u0631\u0628\u0631 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0628\u0627\u0632 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0628\u0647\u062a\u0631\u0647 Backend \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 Read \u062b\u0628\u062a \u06a9\u0646\u0647\u060c \u0627\u0645\u0627 \u062d\u0630\u0641 \u0627\u0639\u0644\u0627\u0646 \u062a\u0628\u0644\u062a \u0628\u0647\u200c\u0635\u0648\u0631\u062a \u062e\u0648\u062f\u06a9\u0627\u0631 \u0633\u0627\u062f\u0647 \u0646\u06cc\u0633\u062a. \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u06cc\u06a9 \u067e\u06cc\u0627\u0645 Sync \u06a9\u0645\u200c\u0627\u0648\u0644\u0648\u06cc\u062a \u0628\u0647 \u062f\u0633\u062a\u06af\u0627\u0647\u200c\u0647\u0627\u06cc \u062f\u06cc\u06af\u0647 \u0628\u0641\u0631\u0633\u062a\u06cc\u0645 \u06cc\u0627 \u0647\u0646\u06af\u0627\u0645 \u0628\u0627\u0632 \u0634\u062f\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648\u0636\u0639\u06cc\u062a Inbox \u0631\u0648 Sync \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u0648\u06cc\u062f\u0627\u062f \u0644\u0645\u0633 \u0627\u0639\u0644\u0627\u0646:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>suspend fun handlePushOpen(\n    eventId: String\n) {\n    notificationRepository\n        .markEventAsRead(eventId)\n\n    analyticsRepository\n        .trackPushOpened(eventId)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">handlePushOpen<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    eventId: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    notificationRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">markEventAsRead<\/span><span style=\"color: #24292E\">(eventId)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    analyticsRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">trackPushOpened<\/span><span style=\"color: #24292E\">(eventId)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u0645\u062a Backend:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PATCH \/notifications\/events\/evt_986215\/read\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f Backend \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u06cc\u06a9 Data Message \u0628\u0627 \u0646\u0648\u0639 <code>NOTIFICATION_STATE_CHANGED<\/code> \u0628\u0631\u0627\u06cc Registration\u0647\u0627\u06cc \u062f\u06cc\u06af\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0641\u0631\u0633\u062a\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"type\": \"NOTIFICATION_STATE_CHANGED\",\n  \"eventId\": \"evt_986215\",\n  \"state\": \"READ\"\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;type&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;NOTIFICATION_STATE_CHANGED&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;eventId&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;evt_986215&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">  <\/span><span style=\"color: #032F62\">&quot;state&quot;<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #032F62\">&quot;READ&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0633\u062a\u06af\u0627\u0647 \u062f\u0648\u0645 \u0628\u0627 \u062f\u0631\u06cc\u0627\u0641\u062a \u0627\u0648\u0646 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0627\u0639\u0644\u0627\u0646 \u0645\u0631\u0628\u0648\u0637 \u0631\u0648 Cancel \u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun cancelNotification(\n    context: Context,\n    eventId: String\n) {\n    NotificationManagerCompat\n        .from(context)\n        .cancel(\n            eventId.hashCode()\n        )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">cancelNotification<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    context: <\/span><span style=\"color: #6F42C1\">Context<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    eventId: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    NotificationManagerCompat<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">from<\/span><span style=\"color: #24292E\">(context)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">cancel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            eventId.<\/span><span style=\"color: #6F42C1\">hashCode<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0647\u0645\u0627\u0647\u0646\u06af\u06cc \u0647\u0645\u06cc\u0634\u0647 \u0644\u062d\u0638\u0647\u200c\u0627\u06cc \u0648 \u062a\u0636\u0645\u06cc\u0646\u06cc \u0646\u06cc\u0633\u062a\u060c \u0627\u0645\u0627 \u062a\u062c\u0631\u0628\u0647 \u0686\u0646\u062f\u062f\u0633\u062a\u06af\u0627\u0647\u06cc \u0631\u0648 \u0645\u0646\u0638\u0645\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062b\u0628\u062a \u0631\u0648\u06cc\u062f\u0627\u062f\u0647\u0627\u06cc \u062f\u0631\u06cc\u0627\u0641\u062a\u060c \u0646\u0645\u0627\u06cc\u0634 \u0648 \u0628\u0627\u0632 \u0634\u062f\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0642\u0637 \u0627\u06cc\u0646\u06a9\u0647 <code>send()<\/code> \u062f\u0631 Backend \u0645\u0648\u0641\u0642 \u0628\u0648\u062f\u0647 \u0628\u0647 \u0645\u0639\u0646\u06cc \u062f\u06cc\u062f\u0647 \u0634\u062f\u0646 \u0627\u0639\u0644\u0627\u0646 \u0646\u06cc\u0633\u062a. \u0632\u0646\u062c\u06cc\u0631\u0647 Push \u0686\u0646\u062f \u0645\u0631\u062d\u0644\u0647 \u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Event Created\nMessage Requested\nFCM Accepted\nDevice Received\nNotification Displayed\nUser Opened\nTarget Screen Viewed\nBusiness Action Completed\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0647\u0631 \u0645\u0631\u062d\u0644\u0647 \u06cc\u06a9 \u0631\u0648\u06cc\u062f\u0627\u062f \u0642\u0627\u0628\u0644\u200c\u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc \u062a\u0639\u0631\u06cc\u0641 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>push_created\npush_send_accepted\npush_send_failed\npush_received\npush_displayed\npush_opened\npush_destination_viewed\nprice_alert_converted\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Client:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>object PushAnalytics {\n\n    fun logReceived(\n        payload: PushPayload,\n        originalPriority: Int,\n        deliveredPriority: Int\n    ) {\n        Firebase.analytics.logEvent(\n            \"push_received\"\n        ) {\n            param(\n                \"event_id\",\n                payload.eventId\n            )\n\n            param(\n                \"push_type\",\n                payload.type.name\n            )\n\n            param(\n                \"original_priority\",\n                originalPriority.toLong()\n            )\n\n            param(\n                \"delivered_priority\",\n                deliveredPriority.toLong()\n            )\n        }\n    }\n\n    fun logOpened(\n        payload: PushPayload\n    ) {\n        Firebase.analytics.logEvent(\n            \"push_opened\"\n        ) {\n            param(\n                \"event_id\",\n                payload.eventId\n            )\n\n            param(\n                \"push_type\",\n                payload.type.name\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PushAnalytics<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">logReceived<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        originalPriority: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        deliveredPriority: <\/span><span style=\"color: #6F42C1\">Int<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Firebase.analytics.<\/span><span style=\"color: #6F42C1\">logEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;push_received&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">param<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;event_id&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">param<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;push_type&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.type.name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">param<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;original_priority&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                originalPriority.<\/span><span style=\"color: #6F42C1\">toLong<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">param<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;delivered_priority&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                deliveredPriority.<\/span><span style=\"color: #6F42C1\">toLong<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">logOpened<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        payload: <\/span><span style=\"color: #6F42C1\">PushPayload<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Firebase.analytics.<\/span><span style=\"color: #6F42C1\">logEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;push_opened&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">param<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;event_id&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.eventId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">param<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #032F62\">&quot;push_type&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                payload.type.name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0628\u0627\u06cc\u062f \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u06cc\u0627 \u0645\u062a\u0646 \u06a9\u0627\u0645\u0644 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u0628\u06cc\u200c\u062f\u0644\u06cc\u0644 \u0648\u0627\u0631\u062f Analytics \u06a9\u0646\u06cc\u0645. <code>eventId<\/code>\u060c \u0646\u0648\u0639 Push\u060c \u0646\u0633\u062e\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648 \u0646\u062a\u06cc\u062c\u0647 \u067e\u0631\u062f\u0627\u0632\u0634 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0628\u0631\u0627\u06cc \u062a\u062d\u0644\u06cc\u0644 \u0641\u0646\u06cc \u06a9\u0627\u0641\u06cc \u0647\u0633\u062a\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0633\u062a Push \u062f\u0631 \u0648\u0636\u0639\u06cc\u062a\u200c\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0639\u0644\u0627\u0646 \u0641\u0642\u0637 \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 Android Studio \u0628\u0627\u0632\u0647 \u0648 \u06af\u0648\u0634\u06cc \u0628\u0647 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u067e\u0631\u0633\u0631\u0639\u062a \u0648\u0635\u0644\u0647 \u062a\u0633\u062a \u0646\u0645\u06cc\u0634\u0647. \u0628\u0631\u0627\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0628\u0627\u06cc\u062f \u062d\u062f\u0627\u0642\u0644 \u0627\u06cc\u0646 \u0648\u0636\u0639\u06cc\u062a\u200c\u0647\u0627 \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 Foreground \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 Background \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0632 Recent Apps \u0628\u0633\u062a\u0647 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u062f\u0633\u062a\u06af\u0627\u0647 \u062f\u0631 Doze \u0642\u0631\u0627\u0631 \u06af\u0631\u0641\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0647\u0646\u06af\u0627\u0645 \u0627\u0631\u0633\u0627\u0644 \u0642\u0637\u0639 \u0648 \u0628\u0639\u062f\u0627\u064b \u0648\u0635\u0644 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>Permission \u0627\u0639\u0644\u0627\u0646 \u0631\u062f \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>Channel \u0647\u0634\u062f\u0627\u0631 \u0642\u06cc\u0645\u062a \u062e\u0627\u0645\u0648\u0634 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u06a9\u0627\u0631\u0628\u0631 \u0627\u0632 \u062d\u0633\u0627\u0628 \u062e\u0627\u0631\u062c \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>Token \u0647\u0646\u06af\u0627\u0645 \u0622\u0641\u0644\u0627\u06cc\u0646 \u0628\u0648\u062f\u0646 \u0639\u0648\u0636 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u06cc\u06a9 Event \u062f\u0648\u0628\u0627\u0631 \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u0686\u0646\u062f \u0631\u0648\u06cc\u062f\u0627\u062f \u0628\u0631\u0627\u06cc \u06cc\u06a9 \u0645\u062d\u0635\u0648\u0644 \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>Payload \u0646\u0627\u0642\u0635 \u06cc\u0627 \u062f\u0627\u0631\u0627\u06cc \u0646\u0633\u062e\u0647 \u0646\u0627\u0634\u0646\u0627\u062e\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u06a9\u0627\u0631\u0628\u0631 \u0627\u0632 Notification \u0648\u0627\u0631\u062f \u0635\u0641\u062d\u0647 \u0645\u062d\u0635\u0648\u0644 \u062d\u0630\u0641\u200c\u0634\u062f\u0647 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u0686\u0646\u062f \u062d\u0633\u0627\u0628 \u0628\u0647\u200c\u062a\u0631\u062a\u06cc\u0628 \u0631\u0648\u06cc \u06cc\u06a9 \u062f\u0633\u062a\u06af\u0627\u0647 Login \u0648 Logout \u06a9\u0646\u0646.<\/li>\n\n\n\n<li>\u06cc\u06a9 \u062d\u0633\u0627\u0628 \u0631\u0648\u06cc \u0686\u0646\u062f \u062f\u0633\u062a\u06af\u0627\u0647 \u0641\u0639\u0627\u0644 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0646\u0633\u062e\u0647 \u0642\u062f\u06cc\u0645\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 Payload \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u0647.<\/li>\n\n\n\n<li>\u0627\u0639\u0644\u0627\u0646 \u062a\u0635\u0648\u06cc\u0631 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647 \u0627\u0645\u0627 \u062f\u0627\u0646\u0644\u0648\u062f \u062a\u0635\u0648\u06cc\u0631 \u0634\u06a9\u0633\u062a \u0628\u062e\u0648\u0631\u0647.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0648\u0631\u0648\u062f \u0628\u0647 Doze \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0631\u0648\u06cc \u062f\u0633\u062a\u06af\u0627\u0647 \u062a\u0633\u062a \u0627\u0632 ADB \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>adb shell dumpsys deviceidle force-idle\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u0631\u0648\u062c \u0627\u0632 Doze:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>adb shell dumpsys deviceidle unforce\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0639\u0627\u0644 \u06a9\u0631\u062f\u0646 \u062f\u0648\u0628\u0627\u0631\u0647 \u062f\u0633\u062a\u06af\u0627\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>adb shell dumpsys battery reset\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u062a\u0633\u062a \u067e\u06cc\u0627\u0645 High \u0628\u0627\u06cc\u062f \u0645\u0637\u0645\u0626\u0646 \u0628\u0634\u06cc\u0645 \u0627\u0639\u0644\u0627\u0646 \u0648\u0627\u0642\u0639\u0627\u064b \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647\u061b \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u062f\u0627\u0648\u0645 \u0627\u0632 High \u0628\u0631\u0627\u06cc \u06a9\u0627\u0631\u0647\u0627\u06cc \u067e\u0646\u0647\u0627\u0646 \u06cc\u0627 Sync \u062e\u0627\u0645 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0628\u0627\u0639\u062b \u06a9\u0627\u0647\u0634 \u0627\u0648\u0644\u0648\u06cc\u062a \u062a\u062d\u0648\u06cc\u0644 \u0628\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0645\u0639\u0645\u0627\u0631\u06cc \u0646\u0647\u0627\u06cc\u06cc Push \u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0646\u0633\u062e\u0647 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc\u060c \u062c\u0631\u06cc\u0627\u0646 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0628\u0647 \u0627\u06cc\u0646 \u0634\u06a9\u0644 \u062f\u0631\u0645\u06cc\u0627\u062f:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">Price Worker detects a price drop<br>\u2193<br>Backend validates the event<br>\u2193<br>Notification record is created<br>\u2193<br>User preferences are checked<br>\u2193<br>Active registrations are selected<br>\u2193<br>FCM data messages are created<br>\u2193<br>Invalid registrations are removed<br>\u2193<br>Android receives the payload<br>\u2193<br>Payload schema is validated<br>\u2193<br>Duplicate and expired events are rejected<br>\u2193<br>Notification is displayed immediately<br>\u2193<br>WorkManager refreshes product data<br>\u2193<br>User taps the notification<br>\u2193<br>Product screen opens<br>\u2193<br>Notification is marked as read<br>\u2193<br>Analytics records the result<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc\u060c FCM \u0641\u0642\u0637 \u06cc\u06a9\u06cc \u0627\u0632 \u0627\u062c\u0632\u0627\u06cc \u0633\u06cc\u0633\u062a\u0645 \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0647. \u0645\u0646\u0628\u0639 \u0627\u0635\u0644\u06cc \u0631\u0648\u06cc\u062f\u0627\u062f Backend\u0647\u060c \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0627\u0639\u0644\u0627\u0646 \u0631\u0648\u06cc \u0633\u0631\u0648\u0631 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u0634\u0646\u060c \u0647\u0631 \u062f\u0633\u062a\u06af\u0627\u0647 Registration \u0645\u0633\u062a\u0642\u0644 \u062f\u0627\u0631\u0647\u060c Push \u0642\u0631\u0627\u0631\u062f\u0627\u062f \u0646\u0633\u062e\u0647\u200c\u062f\u0627\u0631 \u062f\u0627\u0631\u0647\u060c \u067e\u06cc\u0627\u0645 \u062a\u06a9\u0631\u0627\u0631\u06cc \u0631\u0648\u06cc Client \u062d\u0630\u0641 \u0645\u06cc\u0634\u0647 \u0648 Inbox \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u062c\u0627\u0632\u0647 \u0645\u06cc\u062f\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f\u0647\u0627\u06cc \u0645\u0647\u0645 \u0641\u0642\u0637 \u0628\u0647 Notification Shade \u0648\u0627\u0628\u0633\u062a\u0647 \u0646\u0628\u0627\u0634\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u06a9\u200c\u0644\u06cc\u0633\u062a Push \u062d\u0631\u0641\u0647\u200c\u0627\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u067e\u06cc\u0634 \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646\u060c \u0633\u06cc\u0633\u062a\u0645 Push \u0628\u0627\u06cc\u062f \u0627\u06cc\u0646 \u0634\u0631\u0627\u06cc\u0637 \u0631\u0648 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Payload \u0642\u0631\u0627\u0631\u062f\u0627\u062f \u0645\u0634\u062e\u0635 \u0648 schemaVersion \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0647\u0631 \u0631\u0648\u06cc\u062f\u0627\u062f <code>eventId<\/code> \u06cc\u06a9\u062a\u0627 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u062f\u0627\u062e\u0644 Push \u0642\u0631\u0627\u0631 \u0646\u06af\u06cc\u0631\u0647.<\/li>\n\n\n\n<li>\u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc \u0646\u06cc\u0627\u0632\u0645\u0646\u062f \u06a9\u0646\u062a\u0631\u0644 \u06a9\u0627\u0645\u0644 \u0628\u0647\u200c\u0635\u0648\u0631\u062a Data Message \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0646.<\/li>\n\n\n\n<li>Token \u0647\u0631 \u0646\u0635\u0628 \u062c\u062f\u0627 \u0627\u0632 \u062d\u0633\u0627\u0628 \u06a9\u0627\u0631\u0628\u0631 \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 \u0628\u062a\u0648\u0646\u0647 \u0686\u0646\u062f Registration \u0641\u0639\u0627\u0644 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>onNewToken \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062a\u0627\u0632\u0647 \u0631\u0648 \u0628\u0627 WorkManager \u0628\u0647 \u0633\u0631\u0648\u0631 \u0628\u0641\u0631\u0633\u062a\u0647.<\/li>\n\n\n\n<li>Login \u0648 Logout \u0627\u0631\u062a\u0628\u0627\u0637 Registration \u0628\u0627 \u062d\u0633\u0627\u0628 \u0631\u0648 \u062f\u0631\u0633\u062a \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u0646.<\/li>\n\n\n\n<li>Token\u0647\u0627\u06cc \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u0627\u0632 Backend \u067e\u0627\u06a9 \u06cc\u0627 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u0628\u0634\u0646.<\/li>\n\n\n\n<li>Permission \u0627\u0639\u0644\u0627\u0646 \u062f\u0631 \u0632\u0645\u0627\u0646 \u0645\u0639\u0646\u0627\u062f\u0627\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u0648\u0636\u0639\u06cc\u062a Permission \u0648 Channel\u0647\u0627\u06cc \u0633\u06cc\u0633\u062a\u0645 \u0628\u0631\u0631\u0633\u06cc \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0627\u0639\u0644\u0627\u0646 \u0631\u0648\u06cc Backend \u0648 Client \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>\u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 Channel\u0647\u0627\u06cc \u062c\u062f\u0627 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>\u0644\u0645\u0633 \u0627\u0639\u0644\u0627\u0646 \u0645\u0642\u0635\u062f \u062f\u0642\u06cc\u0642 \u0648 \u0642\u0627\u0628\u0644\u200c\u0627\u0639\u062a\u0645\u0627\u062f \u0628\u0627\u0632 \u06a9\u0646\u0647.<\/li>\n\n\n\n<li>PendingIntent \u0647\u0631 \u0627\u0639\u0644\u0627\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062f\u0631\u0633\u062a \u062e\u0648\u062f\u0634 \u0631\u0648 \u062d\u0641\u0638 \u06a9\u0646\u0647.<\/li>\n\n\n\n<li>\u0631\u0648\u06cc\u062f\u0627\u062f \u062a\u06a9\u0631\u0627\u0631\u06cc \u062f\u0648\u0628\u0627\u0631\u0647 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0646\u0634\u0647.<\/li>\n\n\n\n<li>\u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u06cc\u06a9 \u0645\u062d\u0635\u0648\u0644 \u062f\u0631 \u0635\u0648\u0631\u062a \u0646\u06cc\u0627\u0632 Update \u0628\u0634\u0646.<\/li>\n\n\n\n<li>\u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u0645\u062a\u0639\u062f\u062f Group \u0648 Summary \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>\u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc \u0632\u0645\u0627\u0646\u200c\u062d\u0633\u0627\u0633 High \u0648 \u0628\u0642\u06cc\u0647 Normal \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>High Priority \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0645\u062d\u062a\u0648\u0627\u06cc \u0642\u0627\u0628\u0644\u200c\u0645\u0634\u0627\u0647\u062f\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>TTL \u0645\u062a\u0646\u0627\u0633\u0628 \u0628\u0627 \u0639\u0645\u0631 \u0648\u0627\u0642\u0639\u06cc \u0631\u0648\u06cc\u062f\u0627\u062f \u062a\u0639\u06cc\u06cc\u0646 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc Sync \u062f\u0631 \u0635\u0648\u0631\u062a \u0645\u0646\u0627\u0633\u0628 \u0628\u0648\u062f\u0646 Collapsible \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>\u06a9\u0627\u0631 \u0637\u0648\u0644\u0627\u0646\u06cc \u062f\u0627\u062e\u0644 onMessageReceived \u0627\u0646\u062c\u0627\u0645 \u0646\u0634\u0647.<\/li>\n\n\n\n<li>\u062f\u0627\u0646\u0644\u0648\u062f \u062a\u0635\u0648\u06cc\u0631 \u0648 Sync \u0633\u0646\u06af\u06cc\u0646 \u0628\u0647 WorkManager \u0633\u067e\u0631\u062f\u0647 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>Topic \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0639\u0645\u0648\u0645\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>Push \u062c\u0627\u06cc \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627 \u0631\u0648 \u0646\u06af\u06cc\u0631\u0647.<\/li>\n\n\n\n<li>\u062f\u0631\u06cc\u0627\u0641\u062a\u060c \u0646\u0645\u0627\u06cc\u0634\u060c \u0628\u0627\u0632 \u0634\u062f\u0646 \u0648 \u0646\u062a\u06cc\u062c\u0647 Push \u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u0633\u06cc\u0633\u062a\u0645 \u062f\u0631 Foreground\u060c Background\u060c Doze \u0648 \u062d\u0627\u0644\u062a \u0622\u0641\u0644\u0627\u06cc\u0646 \u062a\u0633\u062a \u0628\u0634\u0647.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Push \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u06cc\u0639\u0646\u06cc \u0633\u0631\u0648\u0631 \u0641\u0642\u0637 \u06cc\u06a9 \u0645\u062a\u0646 \u0628\u0647 \u06af\u0648\u0634\u06cc \u0646\u0641\u0631\u0633\u062a\u0647\u060c \u0628\u0644\u06a9\u0647 \u06cc\u06a9 \u0631\u0648\u06cc\u062f\u0627\u062f \u0646\u0633\u062e\u0647\u200c\u062f\u0627\u0631\u060c \u0642\u0627\u0628\u0644\u200c\u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc \u0648 \u062f\u0627\u0631\u0627\u06cc \u0645\u0642\u0635\u062f \u0645\u0634\u062e\u0635 \u062a\u0648\u0644\u06cc\u062f \u06a9\u0646\u0647. \u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0647\u0631 \u06a9\u0627\u0647\u0634 \u0642\u06cc\u0645\u062a \u0628\u0627\u06cc\u062f \u0627\u0628\u062a\u062f\u0627 \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9 \u0631\u0648\u06cc\u062f\u0627\u062f \u0648\u0627\u0642\u0639\u06cc \u062f\u0631 Backend \u062b\u0628\u062a \u0628\u0634\u0647\u060c \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u06a9\u0627\u0631\u0628\u0631 \u0628\u0631\u0631\u0633\u06cc \u0628\u0634\u0647 \u0648 \u0628\u0639\u062f \u067e\u06cc\u0627\u0645 \u0628\u0647 \u062a\u0645\u0627\u0645 Registration\u0647\u0627\u06cc \u0641\u0639\u0627\u0644 \u0647\u0645\u0648\u0646 \u062d\u0633\u0627\u0628 \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0647. Client \u0647\u0645 \u0646\u0628\u0627\u06cc\u062f \u0647\u0631 Payload\u06cc \u0631\u0648 \u0628\u062f\u0648\u0646 \u0628\u0631\u0631\u0633\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647\u061b \u0628\u0627\u06cc\u062f \u0646\u0633\u062e\u0647 \u0642\u0631\u0627\u0631\u062f\u0627\u062f\u060c \u062a\u0627\u0632\u06af\u06cc \u067e\u06cc\u0627\u0645\u060c \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u06a9\u0627\u0631\u0628\u0631 \u0648 \u062a\u06a9\u0631\u0627\u0631\u06cc \u0646\u0628\u0648\u062f\u0646 <code>eventId<\/code> \u0631\u0648 \u06a9\u0646\u062a\u0631\u0644 \u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Notification Message \u0628\u0631\u0627\u06cc \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u0633\u0627\u062f\u0647 \u0645\u0641\u06cc\u062f\u0647\u060c \u0627\u0645\u0627 Data Message \u06a9\u0646\u062a\u0631\u0644 \u0628\u06cc\u0634\u062a\u0631\u06cc \u0631\u0648\u06cc \u0638\u0627\u0647\u0631\u060c Channel\u060c \u06af\u0631\u0648\u0647\u200c\u0628\u0646\u062f\u06cc\u060c Deep Link \u0648 \u0631\u0641\u062a\u0627\u0631 Foreground \u0648 Background \u0645\u06cc\u062f\u0647. Token \u0647\u0645 \u0645\u062a\u0639\u0644\u0642 \u0628\u0647 \u0646\u0645\u0648\u0646\u0647 \u0646\u0635\u0628\u200c\u0634\u062f\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0633\u062a\u060c \u0646\u0647 \u062e\u0648\u062f \u06a9\u0627\u0631\u0628\u0631\u061b \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u06cc\u06a9 \u062d\u0633\u0627\u0628 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0686\u0646\u062f Token \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647 \u0648 \u0647\u0631 Token \u0645\u0645\u06a9\u0646\u0647 \u062f\u0631 \u0637\u0648\u0644 \u0632\u0645\u0627\u0646 \u0639\u0648\u0636 \u06cc\u0627 \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u0628\u0634\u0647. \u062f\u0631 \u06a9\u0646\u0627\u0631 \u0627\u06cc\u0646\u200c\u0647\u0627\u060c Priority\u060c TTL \u0648 Collapse Key \u0628\u0627\u06cc\u062f \u0628\u0631\u0627\u0633\u0627\u0633 \u0645\u0627\u0647\u06cc\u062a \u0631\u0648\u06cc\u062f\u0627\u062f \u0627\u0646\u062a\u062e\u0627\u0628 \u0628\u0634\u0646\u060c \u0646\u0647 \u0627\u06cc\u0646\u06a9\u0647 \u0647\u0645\u0647 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627 \u0628\u0627 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u06cc\u06a9\u0633\u0627\u0646 \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0646\u0647\u0627\u06cc\u062a Push \u0646\u0628\u0627\u06cc\u062f \u062a\u0646\u0647\u0627 \u0645\u0646\u0628\u0639 \u062d\u0642\u06cc\u0642\u062a \u0628\u0627\u0634\u0647. \u0645\u0645\u06a9\u0646\u0647 \u067e\u06cc\u0627\u0645 \u062f\u06cc\u0631 \u0628\u0631\u0633\u0647\u060c \u062a\u06a9\u0631\u0627\u0631 \u0628\u0634\u0647\u060c \u0628\u0647\u200c\u062f\u0644\u06cc\u0644 \u062e\u0627\u0645\u0648\u0634 \u0628\u0648\u062f\u0646 \u0627\u0639\u0644\u0627\u0646 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0646\u0634\u0647 \u06cc\u0627 \u0627\u0635\u0644\u0627\u064b \u062a\u062d\u0648\u06cc\u0644 \u062f\u0627\u062f\u0647 \u0646\u0634\u0647. \u062f\u0627\u062f\u0647 \u0627\u0635\u0644\u06cc \u0628\u0627\u06cc\u062f \u0631\u0648\u06cc Backend \u0648 \u062f\u0627\u062e\u0644 Notification Inbox \u0628\u0627\u0642\u06cc \u0628\u0645\u0648\u0646\u0647 \u0648 Push \u0641\u0642\u0637 \u06a9\u0627\u0631\u0628\u0631 \u0631\u0648 \u0627\u0632 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u0627\u062e\u0628\u0631 \u06a9\u0646\u0647. \u0648\u0642\u062a\u06cc \u0627\u06cc\u0646 \u0645\u0631\u0632\u0647\u0627 \u062f\u0631\u0633\u062a \u0637\u0631\u0627\u062d\u06cc \u0628\u0634\u0646\u060c \u0633\u06cc\u0633\u062a\u0645 \u0627\u0639\u0644\u0627\u0646 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0627\u0632 \u06cc\u06a9 \u0642\u0627\u0628\u0644\u06cc\u062a \u062a\u0632\u0626\u06cc\u0646\u06cc \u0628\u0647 \u0628\u062e\u0634\u06cc \u0642\u0627\u0628\u0644\u200c\u0627\u0639\u062a\u0645\u0627\u062f \u0627\u0632 \u0645\u0639\u0645\u0627\u0631\u06cc \u0645\u062d\u0635\u0648\u0644 \u062a\u0628\u062f\u06cc\u0644 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u200c\u0648\u067e\u0646\u062c\u0645<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">Event-Driven UI\u061b \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0631\u0648\u06cc\u062f\u0627\u062f\u0645\u062d\u0648\u0631<\/h1>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"819\" height=\"1024\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-11-1-819x1024.avif\" alt=\"\" class=\"wp-image-6166\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-11-1-819x1024.avif 819w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-11-1-240x300.avif 240w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-11-1-768x960.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-11-1.avif 1122w\" sizes=\"(max-width: 819px) 100vw, 819px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u0633\u0627\u062f\u0647 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u062c\u0631\u06cc\u0627\u0646 \u06a9\u0627\u0631 \u0645\u0633\u062a\u0642\u06cc\u0645\u0647. \u06a9\u0627\u0631\u0628\u0631 \u062f\u06a9\u0645\u0647\u200c\u0627\u06cc \u0631\u0648 \u0644\u0645\u0633 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645\u0648\u0646\u200c\u062c\u0627 \u06cc\u06a9 API \u0631\u0648 \u0635\u062f\u0627 \u0645\u06cc\u200c\u0632\u0646\u0647\u060c \u0646\u062a\u06cc\u062c\u0647 \u0631\u0648 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647 \u0648 \u0686\u0646\u062f \u0645\u062a\u063a\u06cc\u0631 \u062f\u0627\u062e\u0644 \u0635\u0641\u062d\u0647 \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u062f\u0647. \u062a\u0627 \u0648\u0642\u062a\u06cc \u0635\u0641\u062d\u0647 \u06a9\u0648\u0686\u06cc\u06a9\u0647 \u0648 \u0641\u0642\u0637 \u062f\u0648 \u06cc\u0627 \u0633\u0647 \u0639\u0645\u0644\u06cc\u0627\u062a \u062f\u0627\u0631\u0647\u060c \u0627\u06cc\u0646 \u0631\u0648\u0634 \u0638\u0627\u0647\u0631\u0627\u064b \u0645\u0634\u06a9\u0644\u06cc \u0627\u06cc\u062c\u0627\u062f \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u0645\u0627 \u0628\u0627 \u0628\u0632\u0631\u06af\u200c\u062a\u0631 \u0634\u062f\u0646 \u067e\u0631\u0648\u0698\u0647\u060c \u0647\u0631 \u0628\u062e\u0634 \u0635\u0641\u062d\u0647 \u0634\u0631\u0648\u0639 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0628\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u062f\u0627\u062f\u0646 \u0628\u062e\u0634\u200c\u0647\u0627\u06cc \u062f\u06cc\u06af\u0647. \u062f\u06a9\u0645\u0647 Refresh \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b Loading \u0631\u0648 \u0631\u0648\u0634\u0646 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c Repository \u0646\u062a\u06cc\u062c\u0647 \u0631\u0648 \u062f\u0627\u062e\u0644 \u06cc\u06a9 \u0645\u062a\u063a\u06cc\u0631 \u0645\u06cc\u200c\u0631\u06cc\u0632\u0647\u060c \u06cc\u06a9 Callback \u062c\u062f\u0627 Snackbar \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u062f\u0647 \u0648 \u06cc\u06a9 \u0634\u0631\u0637 \u062f\u06cc\u06af\u0647 \u0647\u0645 Navigation \u0631\u0648 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0628\u0639\u062f \u0627\u0632 \u0645\u062f\u062a\u06cc \u062f\u06cc\u06af\u0647 \u0645\u0634\u062e\u0635 \u0646\u06cc\u0633\u062a \u0686\u0647 \u06a9\u0633\u06cc \u0648\u0636\u0639\u06cc\u062a \u0635\u0641\u062d\u0647 \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u062f\u0627\u062f\u0647 \u0648 \u0686\u0631\u0627 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0628\u0647 \u0634\u06a9\u0644 \u0641\u0639\u0644\u06cc \u062f\u0631\u0622\u0645\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0631\u0648\u06cc\u062f\u0627\u062f\u0645\u062d\u0648\u0631\u060c \u0628\u0647\u200c\u062c\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0627\u062c\u0632\u0627\u06cc \u0635\u0641\u062d\u0647 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0647\u0645\u062f\u06cc\u06af\u0647 \u0631\u0648 \u06a9\u0646\u062a\u0631\u0644 \u06a9\u0646\u0646\u060c \u0647\u0631 \u0627\u062a\u0641\u0627\u0642 \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9 <strong>Event<\/strong> \u0648\u0627\u0631\u062f \u06cc\u06a9 \u062c\u0631\u06cc\u0627\u0646 \u0645\u0634\u062e\u0635 \u0645\u06cc\u0634\u0647. ViewModel \u0631\u0648\u06cc\u062f\u0627\u062f \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0645\u0646\u0637\u0642 \u0645\u0631\u0628\u0648\u0637 \u0631\u0648 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u06cc\u06a9 \u0648\u0636\u0639\u06cc\u062a \u062c\u062f\u06cc\u062f \u0645\u06cc\u200c\u0633\u0627\u0632\u0647. \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0647\u0645 \u0641\u0642\u0637 \u0648\u0636\u0639\u06cc\u062a \u062c\u062f\u06cc\u062f \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u062f\u0647. \u0627\u06cc\u0646 \u062c\u0631\u06cc\u0627\u0646 \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0635\u0641\u062d\u0647 \u0627\u0632 \u06cc\u06a9 \u0645\u0633\u06cc\u0631 \u0642\u0627\u0628\u0644\u200c\u067e\u06cc\u0634\u200c\u0628\u06cc\u0646\u06cc \u0639\u0628\u0648\u0631 \u06a9\u0646\u0646:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">User Event<br>\u2193<br>ViewModel<br>\u2193<br>Business Logic<br>\u2193<br>New UI State<br>\u2193<br>Compose Recomposition<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0645\u0639\u0645\u0627\u0631\u06cc \u067e\u06cc\u0634\u0646\u0647\u0627\u062f\u06cc \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u060c State \u0647\u0645\u06cc\u0634\u0647 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647\u060c \u0627\u0645\u0627 Event \u0627\u062a\u0641\u0627\u0642 \u0645\u06cc\u200c\u0627\u0641\u062a\u0647 \u0648 \u0639\u0645\u0631 \u0645\u062d\u062f\u0648\u062f\u06cc \u062f\u0627\u0631\u0647. Event \u0648\u0631\u0648\u062f\u06cc \u0641\u0631\u0627\u06cc\u0646\u062f \u062a\u0648\u0644\u06cc\u062f State \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0647 \u0648 \u062e\u0631\u0648\u062c\u06cc \u0627\u0648\u0646 \u0641\u0631\u0627\u06cc\u0646\u062f\u060c \u0648\u0636\u0639\u06cc\u062a\u06cc\u0647 \u06a9\u0647 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u062f\u0631\u0633 \u0635\u0641\u062d\u0647 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u062f\u0646\u0628\u0627\u0644\u200c\u0634\u062f\u0647 \u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0631\u0648 \u0628\u0647 \u06cc\u06a9 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u06a9\u0627\u0645\u0644\u0627\u064b \u0631\u0648\u06cc\u062f\u0627\u062f\u0645\u062d\u0648\u0631 \u062a\u0628\u062f\u06cc\u0644 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. \u0627\u06cc\u0646 \u0635\u0641\u062d\u0647 \u0628\u0627\u06cc\u062f \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647\u060c \u062c\u0633\u062a\u200c\u0648\u062c\u0648 \u06a9\u0646\u0647\u060c \u0645\u0631\u062a\u0628\u200c\u0633\u0627\u0632\u06cc \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u0647\u060c \u0642\u06cc\u0645\u062a\u200c\u0647\u0627 \u0631\u0648 \u062a\u0627\u0632\u0647\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u0647\u060c \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 \u062d\u0630\u0641 \u06a9\u0646\u0647\u060c Snackbar \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647 \u0648 \u062f\u0631 \u0635\u0648\u0631\u062a \u0644\u0645\u0633 \u0645\u062d\u0635\u0648\u0644\u060c \u0648\u0627\u0631\u062f \u0635\u0641\u062d\u0647 \u062c\u0632\u0626\u06cc\u0627\u062a \u0628\u0634\u0647. \u0647\u062f\u0641 \u0641\u0642\u0637 \u0646\u0648\u0634\u062a\u0646 \u0686\u0646\u062f \u06a9\u0644\u0627\u0633 Event \u0648 State \u0646\u06cc\u0633\u062a\u061b \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc\u0645 \u0628\u0641\u0647\u0645\u06cc\u0645 \u0686\u0647 \u0686\u06cc\u0632\u06cc \u0648\u0627\u0642\u0639\u0627\u064b Event \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0647\u060c \u0686\u0647 \u0686\u06cc\u0632\u06cc \u0628\u0627\u06cc\u062f State \u0628\u0627\u0634\u0647\u060c Navigation \u0648 Snackbar \u0686\u0637\u0648\u0631 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0645\u06cc\u0634\u0646 \u0648 \u0686\u0631\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0628\u06cc\u200c\u0642\u0627\u0639\u062f\u0647 \u0627\u0632 <code>SharedFlow<\/code> \u06af\u0627\u0647\u06cc \u0631\u0648\u06cc\u062f\u0627\u062f\u0647\u0627 \u0631\u0648 \u0627\u0632 \u0628\u06cc\u0646 \u0645\u06cc\u200c\u0628\u0631\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u062f\u0633\u062a\u0648\u0631\u06cc \u0686\u0647 \u0645\u0634\u06a9\u0644\u06cc \u062f\u0627\u0631\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0635\u0641\u062d\u0647 \u0641\u0647\u0631\u0633\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0648 \u0628\u0647 \u0634\u06a9\u0644 \u0632\u06cc\u0631 \u067e\u06cc\u0627\u062f\u0647 \u06a9\u0631\u062f\u0647\u200c\u0627\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nfun TrackedProductsScreen(\n    viewModel: TrackedProductsViewModel,\n    navController: NavController\n) {\n    val products by viewModel.products.collectAsState()\n    val isLoading by viewModel.isLoading.collectAsState()\n    val error by viewModel.error.collectAsState()\n\n    if (error != null) {\n        Toast.makeText(\n            LocalContext.current,\n            error,\n            Toast.LENGTH_LONG\n        ).show()\n    }\n\n    Button(\n        onClick = {\n            viewModel.isLoading.value = true\n\n            viewModel.refresh {\n                viewModel.isLoading.value = false\n            }\n        }\n    ) {\n        Text(\"\u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc\")\n    }\n\n    LazyColumn {\n        items(products) { product ->\n            Text(\n                text = product.title,\n                modifier = Modifier.clickable {\n                    navController.navigate(\n                        \"product\/${product.id}\"\n                    )\n                }\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductsScreen<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    viewModel: <\/span><span style=\"color: #6F42C1\">TrackedProductsViewModel<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    navController: <\/span><span style=\"color: #6F42C1\">NavController<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products <\/span><span style=\"color: #D73A49\">by<\/span><span style=\"color: #24292E\"> viewModel.products.<\/span><span style=\"color: #6F42C1\">collectAsState<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isLoading <\/span><span style=\"color: #D73A49\">by<\/span><span style=\"color: #24292E\"> viewModel.isLoading.<\/span><span style=\"color: #6F42C1\">collectAsState<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> error <\/span><span style=\"color: #D73A49\">by<\/span><span style=\"color: #24292E\"> viewModel.error.<\/span><span style=\"color: #6F42C1\">collectAsState<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (error <\/span><span style=\"color: #D73A49\">!=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Toast.<\/span><span style=\"color: #6F42C1\">makeText<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            LocalContext.current,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            error,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            Toast.LENGTH_LONG<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ).<\/span><span style=\"color: #6F42C1\">show<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">Button<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        onClick <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            viewModel.isLoading.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            viewModel.<\/span><span style=\"color: #6F42C1\">refresh<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                viewModel.isLoading.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">Text<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;\u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">LazyColumn<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">items<\/span><span style=\"color: #24292E\">(products) { product <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">Text<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                text <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> product.title,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                modifier <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> Modifier.<\/span><span style=\"color: #6F42C1\">clickable<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    navController.<\/span><span style=\"color: #6F42C1\">navigate<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        <\/span><span style=\"color: #032F62\">&quot;product\/${product.id}&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06a9\u062f \u0686\u0646\u062f \u0645\u0634\u06a9\u0644 \u0645\u0639\u0645\u0627\u0631\u06cc \u062f\u0627\u0631\u0647. \u0627\u0648\u0644 \u0627\u06cc\u0646\u06a9\u0647 UI \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b State \u062f\u0627\u062e\u0644\u06cc ViewModel \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u062f\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>viewModel.isLoading.value = true\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u067e\u0633 ViewModel \u062f\u06cc\u06af\u0647 \u062a\u0646\u0647\u0627 \u0645\u0633\u0626\u0648\u0644 \u062a\u0648\u0644\u06cc\u062f \u0648\u0636\u0639\u06cc\u062a \u0646\u06cc\u0633\u062a. \u062f\u0648\u0645 \u0627\u06cc\u0646\u06a9\u0647 Callback \u067e\u0627\u06cc\u0627\u0646 Refresh \u062f\u0627\u062e\u0644 \u062e\u0648\u062f Composable \u06a9\u0646\u062a\u0631\u0644 \u0634\u062f\u0647 \u0648 \u0627\u06af\u0631 \u0645\u0646\u0637\u0642 Refresh \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647\u060c UI \u0647\u0645 \u0628\u0627\u06cc\u062f \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647. \u0633\u0648\u0645 \u0627\u06cc\u0646\u06a9\u0647 Toast \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0647\u0646\u06af\u0627\u0645 Composition \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647. Recomposition \u0645\u0645\u06a9\u0646\u0647 \u0686\u0646\u062f \u0628\u0627\u0631 \u0627\u062a\u0641\u0627\u0642 \u0628\u06cc\u0641\u062a\u0647 \u0648 \u0647\u0645\u0648\u0646 Toast \u062f\u0648\u0628\u0627\u0631\u0647 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0628\u0634\u0647. \u0686\u0647\u0627\u0631\u0645 \u0627\u06cc\u0646\u06a9\u0647 \u0645\u062d\u0635\u0648\u0644\u0627\u062a\u060c Loading \u0648 Error \u062f\u0631 \u0633\u0647 \u062c\u0631\u06cc\u0627\u0646 \u062c\u062f\u0627 \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u0646 \u0648 \u0645\u0645\u06a9\u0646\u0647 \u062a\u0631\u06a9\u06cc\u0628\u200c\u0647\u0627\u06cc\u06cc \u0628\u0647 \u0648\u062c\u0648\u062f \u0628\u06cc\u0627\u062f \u06a9\u0647 \u0627\u0632 \u0646\u0638\u0631 \u0645\u0646\u0637\u0642\u06cc \u0646\u0627\u0633\u0627\u0632\u06af\u0627\u0631 \u0628\u0627\u0634\u0646\u061b \u0645\u062b\u0644\u0627\u064b <code>isLoading = false<\/code> \u0628\u0627\u0634\u0647 \u0627\u0645\u0627 \u0641\u0647\u0631\u0633\u062a \u0647\u0646\u0648\u0632 \u062e\u0627\u0644\u06cc \u0648 \u062e\u0637\u0627 \u0647\u0645 <code>null<\/code> \u0628\u0627\u0634\u0647\u060c \u0628\u062f\u0648\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0645\u0639\u0644\u0648\u0645 \u0628\u0627\u0634\u0647 \u0635\u0641\u062d\u0647 \u062f\u0631 \u0648\u0636\u0639\u06cc\u062a \u0627\u0648\u0644\u06cc\u0647\u200c\u0633\u062a \u06cc\u0627 \u0648\u0627\u0642\u0639\u0627\u064b \u0647\u06cc\u0686 \u0645\u062d\u0635\u0648\u0644\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 Compose\u060c \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0627\u0632 State \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647. \u0648\u0642\u062a\u06cc State \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0628\u062e\u0634\u200c\u0647\u0627\u06cc \u0648\u0627\u0628\u0633\u062a\u0647 \u062f\u0648\u0628\u0627\u0631\u0647 Compose \u0645\u06cc\u0634\u0646. \u0627\u0644\u06af\u0648\u06cc \u062c\u0631\u06cc\u0627\u0646 \u06cc\u06a9\u200c\u0637\u0631\u0641\u0647 \u062f\u0627\u062f\u0647 \u0647\u0645 \u062f\u0642\u06cc\u0642\u0627\u064b \u0628\u0627 \u0647\u0645\u06cc\u0646 \u0645\u062f\u0644 \u0647\u0645\u0627\u0647\u0646\u06af\u0647: State \u0627\u0632 \u0628\u0627\u0644\u0627 \u0628\u0647 \u067e\u0627\u06cc\u06cc\u0646 \u0645\u06cc\u0627\u062f \u0648 Event \u0627\u0632 UI \u0628\u0647 \u0633\u0645\u062a State Holder \u0628\u0627\u0644\u0627 \u0645\u06cc\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0639\u0645\u0627\u0631\u06cc \u0645\u0637\u0644\u0648\u0628 \u0645\u0627 \u0627\u06cc\u0646\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>UI reads state\nUI sends event\nViewModel changes state\nUI renders new state\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">UI \u0646\u0628\u0627\u06cc\u062f \u062e\u0648\u062f\u0634 \u062a\u0635\u0645\u06cc\u0645 \u0628\u06af\u06cc\u0631\u0647 Refresh \u0686\u0647 \u0632\u0645\u0627\u0646\u06cc \u062a\u0645\u0627\u0645 \u0634\u062f\u0647\u060c \u062d\u0630\u0641 \u0645\u062d\u0635\u0648\u0644 \u0686\u0647 \u0627\u062b\u0631\u06cc \u0631\u0648\u06cc \u0641\u0647\u0631\u0633\u062a \u062f\u0627\u0631\u0647 \u06cc\u0627 \u062e\u0637\u0627 \u0686\u0637\u0648\u0631 \u0630\u062e\u06cc\u0631\u0647 \u0628\u0634\u0647. UI \u0641\u0642\u0637 \u0627\u0639\u0644\u0627\u0645 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0686\u0647 \u0627\u062a\u0641\u0627\u0642\u06cc \u0627\u0641\u062a\u0627\u062f\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>RefreshClicked\nSearchQueryChanged\nProductClicked\nDeleteProductClicked\nRetryClicked\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">ViewModel \u0647\u0645 \u0628\u0631\u0627\u0633\u0627\u0633 \u0627\u06cc\u0646 \u0627\u062a\u0641\u0627\u0642\u200c\u0647\u0627\u060c \u0648\u0636\u0639\u06cc\u062a \u062c\u062f\u06cc\u062f \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0641\u0627\u0648\u062a Event\u060c State \u0648 Effect<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"819\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-12-1-1024x819.avif\" alt=\"\" class=\"wp-image-6167\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-12-1-1024x819.avif 1024w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-12-1-300x240.avif 300w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-12-1-768x615.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-12-1.avif 1402w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0633\u0627\u062e\u062a Event-Driven UI \u0628\u0627\u06cc\u062f \u0633\u0647 \u0645\u0641\u0647\u0648\u0645 \u0631\u0648 \u0627\u0632 \u0647\u0645 \u062c\u062f\u0627 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Event\nState\nEffect\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Event<\/strong> \u0627\u062a\u0641\u0627\u0642\u06cc\u0647 \u06a9\u0647 \u0648\u0627\u0631\u062f \u0633\u06cc\u0633\u062a\u0645 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u06a9\u0627\u0631\u0628\u0631 \u0631\u0648\u06cc Refresh \u0632\u062f.\n\u0645\u062a\u0646 \u062c\u0633\u062a\u200c\u0648\u062c\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f.\n\u0627\u062a\u0635\u0627\u0644 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0628\u0631\u06af\u0634\u062a.\nRepository \u062f\u0627\u062f\u0647 \u062a\u0627\u0632\u0647 \u0645\u0646\u062a\u0634\u0631 \u06a9\u0631\u062f.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>State<\/strong> \u062a\u0635\u0648\u06cc\u0631\u06cc \u0627\u0632 \u0648\u0636\u0639\u06cc\u062a \u0641\u0639\u0644\u06cc \u0635\u0641\u062d\u0647\u200c\u0633\u062a:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u0641\u0647\u0631\u0633\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0686\u06cc\u0633\u062a\u061f\n\u0622\u06cc\u0627 \u0635\u0641\u062d\u0647 \u062f\u0631 \u062d\u0627\u0644 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0627\u0633\u062a\u061f\n\u0639\u0628\u0627\u0631\u062a \u062c\u0633\u062a\u200c\u0648\u062c\u0648\u06cc \u0641\u0639\u0644\u06cc \u0686\u06cc\u0633\u062a\u061f\n\u06a9\u062f\u0627\u0645 \u0646\u0648\u0639 \u0645\u0631\u062a\u0628\u200c\u0633\u0627\u0632\u06cc \u0627\u0646\u062a\u062e\u0627\u0628 \u0634\u062f\u0647\u061f\n\u0622\u06cc\u0627 \u067e\u06cc\u0627\u0645 \u062e\u0637\u0627\u06cc\u06cc \u0628\u0627\u06cc\u062f \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0634\u0648\u062f\u061f\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Effect<\/strong> \u0639\u0645\u0644\u06cc \u06cc\u06a9\u200c\u0628\u0627\u0631\u0647\u200c\u0633\u062a \u06a9\u0647 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u062a\u0648\u0633\u0637 UI \u0627\u062c\u0631\u0627 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u0631\u0641\u062a\u0646 \u0628\u0647 \u0635\u0641\u062d\u0647 \u062c\u0632\u0626\u06cc\u0627\u062a\n\u0628\u0627\u0632 \u06a9\u0631\u062f\u0646 \u0645\u0631\u0648\u0631\u06af\u0631\n\u0646\u0645\u0627\u06cc\u0634 Snackbar\n\u0628\u0627\u0632 \u06a9\u0631\u062f\u0646 \u0635\u0641\u062d\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0633\u06cc\u0633\u062a\u0645\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0647\u0645\u06cc\u0646\u200c\u062c\u0627 \u06cc\u06a9 \u0646\u06a9\u062a\u0647 \u0645\u0639\u0645\u0627\u0631\u06cc \u0645\u0647\u0645 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647. \u062f\u0631 \u062a\u0648\u0635\u06cc\u0647 \u0641\u0639\u0644\u06cc Android\u060c \u0627\u062a\u0641\u0627\u0642\u06cc \u06a9\u0647 \u0627\u0632 ViewModel \u0645\u0646\u0634\u0623 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647 \u0628\u0647\u062a\u0631\u0647 \u062a\u0627 \u062c\u0627\u06cc \u0645\u0645\u06a9\u0646 \u0628\u0647 <strong>UI State<\/strong> \u062a\u0628\u062f\u06cc\u0644 \u0628\u0634\u0647\u060c \u0646\u0647 \u0627\u06cc\u0646\u06a9\u0647 \u0641\u0642\u0637 \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9 Event \u06cc\u06a9\u200c\u0628\u0627\u0631\u0645\u0635\u0631\u0641 \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0647. \u062f\u0644\u06cc\u0644\u0634 \u0627\u06cc\u0646\u0647 \u06a9\u0647 State \u0628\u0639\u062f \u0627\u0632 \u0686\u0631\u062e\u0634 \u0635\u0641\u062d\u0647\u060c \u062a\u0648\u0642\u0641 Lifecycle \u06cc\u0627 \u0628\u0627\u0632\u0633\u0627\u0632\u06cc UI \u0642\u0627\u0628\u0644 \u0628\u0627\u0632\u06cc\u0627\u0628\u06cc \u0648 \u0645\u0634\u0627\u0647\u062f\u0647 \u0628\u0627\u0642\u06cc \u0645\u06cc\u200c\u0645\u0648\u0646\u0647\u060c \u0627\u0645\u0627 Event \u0644\u062d\u0638\u0647\u200c\u0627\u06cc \u0645\u0645\u06a9\u0646\u0647 \u0632\u0645\u0627\u0646\u06cc \u0645\u0646\u062a\u0634\u0631 \u0628\u0634\u0647 \u06a9\u0647 \u0647\u06cc\u0686 Collector \u0641\u0639\u0627\u0644\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u0647 \u0648 \u0627\u0632 \u062f\u0633\u062a \u0628\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0628\u0647\u200c\u062c\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 ViewModel \u0627\u06cc\u0646 \u0631\u0648 \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NavigateToProduct(42)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u062f\u0631 State \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>selectedProductId = 42\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">UI \u0627\u06cc\u0646 State \u0631\u0648 \u0645\u06cc\u200c\u0628\u06cc\u0646\u0647\u060c Navigation \u0631\u0648 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0647 \u0648 \u0628\u0639\u062f \u0627\u0639\u0644\u0627\u0645 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u06a9\u0647 \u0645\u0642\u0635\u062f \u0645\u0635\u0631\u0641 \u0634\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>viewModel.onEvent(\n    TrackedProductsEvent.NavigationHandled\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">viewModel.<\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    TrackedProductsEvent.NavigationHandled<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0631\u0648\u0634 \u0627\u0632 \u0646\u0638\u0631 \u0642\u0627\u0628\u0644\u06cc\u062a \u0628\u0627\u0632\u062a\u0648\u0644\u06cc\u062f \u0645\u0637\u0645\u0626\u0646\u200c\u062a\u0631\u0647. \u0627\u0644\u0628\u062a\u0647 \u062f\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc \u0647\u0646\u0648\u0632 \u0628\u0631\u0627\u06cc \u0628\u0639\u0636\u06cc Effect\u0647\u0627\u06cc \u06a9\u0627\u0645\u0644\u0627\u064b \u06af\u0630\u0631\u0627 \u0627\u0632 <code>SharedFlow<\/code> \u06cc\u0627 <code>Channel<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647. \u0645\u0633\u0626\u0644\u0647 \u0627\u06cc\u0646 \u0646\u06cc\u0633\u062a \u06a9\u0647 SharedFlow \u0645\u0645\u0646\u0648\u0639\u0647\u061b \u0645\u0633\u0626\u0644\u0647 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0622\u06af\u0627\u0647\u0627\u0646\u0647 \u0628\u062f\u0648\u0646\u06cc\u0645 \u06a9\u062f\u0648\u0645 \u0627\u062a\u0641\u0627\u0642 \u062f\u0631 \u0635\u0648\u0631\u062a \u0627\u0632\u062f\u0633\u062a\u200c\u0631\u0641\u062a\u0646\u060c \u0645\u0634\u06a9\u0644 \u062c\u062f\u06cc \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0639\u0631\u06cc\u0641 Event\u0647\u0627\u06cc \u0635\u0641\u062d\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0648\u0644 \u062a\u0645\u0627\u0645 \u0648\u0631\u0648\u062f\u06cc\u200c\u0647\u0627\u06cc \u0635\u0641\u062d\u0647 \u0631\u0648 \u0645\u0634\u062e\u0635 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. \u06cc\u06a9 <code>sealed interface<\/code> \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645 \u062a\u0627 \u0645\u062c\u0645\u0648\u0639\u0647 Event\u0647\u0627 \u0645\u062d\u062f\u0648\u062f \u0648 \u0642\u0627\u0628\u0644\u200c\u0631\u062f\u06cc\u0627\u0628\u06cc \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>sealed interface TrackedProductsEvent {\n\n    data object ScreenStarted :\n        TrackedProductsEvent\n\n    data object RefreshClicked :\n        TrackedProductsEvent\n\n    data object RetryClicked :\n        TrackedProductsEvent\n\n    data class SearchQueryChanged(\n        val query: String\n    ) : TrackedProductsEvent\n\n    data class SortChanged(\n        val sort: ProductSort\n    ) : TrackedProductsEvent\n\n    data class ProductClicked(\n        val productId: Long\n    ) : TrackedProductsEvent\n\n    data class DeleteProductClicked(\n        val productId: Long\n    ) : TrackedProductsEvent\n\n    data object DeleteDialogConfirmed :\n        TrackedProductsEvent\n\n    data object DeleteDialogDismissed :\n        TrackedProductsEvent\n\n    data object UserMessageShown :\n        TrackedProductsEvent\n\n    data object NavigationHandled :\n        TrackedProductsEvent\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">sealed<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductsEvent<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ScreenStarted<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">RefreshClicked<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">RetryClicked<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">SearchQueryChanged<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> query: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">SortChanged<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> sort: <\/span><span style=\"color: #6F42C1\">ProductSort<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductClicked<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DeleteProductClicked<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DeleteDialogConfirmed<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DeleteDialogDismissed<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">UserMessageShown<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">NavigationHandled<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0627\u0645 Event \u0628\u0627\u06cc\u062f \u0686\u06cc\u0632\u06cc \u0631\u0648 \u062a\u0648\u0635\u06cc\u0641 \u06a9\u0646\u0647 \u06a9\u0647 <strong>\u0627\u062a\u0641\u0627\u0642 \u0627\u0641\u062a\u0627\u062f\u0647<\/strong>\u060c \u0646\u0647 \u0627\u06cc\u0646\u06a9\u0647 ViewModel \u0628\u0627\u06cc\u062f \u0686\u0647 \u06a9\u0627\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u0628\u062f\u0647. \u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644 \u0627\u06cc\u0646 \u0646\u0627\u0645 \u0645\u0646\u0627\u0633\u0628 \u0646\u06cc\u0633\u062a:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LoadProducts\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0686\u0648\u0646 \u06cc\u06a9 \u062f\u0633\u062a\u0648\u0631 \u0628\u0647 ViewModel\u0647. \u0646\u0627\u0645 \u0632\u06cc\u0631 \u0628\u0647\u062a\u0631\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ScreenStarted\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 Event \u0641\u0642\u0637 \u0648\u0627\u0642\u0639\u06cc\u062a \u0631\u0648 \u0628\u06cc\u0627\u0646 \u0645\u06cc\u200c\u06a9\u0646\u0647: \u0635\u0641\u062d\u0647 \u0634\u0631\u0648\u0639 \u0634\u062f\u0647. ViewModel \u062a\u0635\u0645\u06cc\u0645 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647 \u0622\u06cc\u0627 \u0628\u0627\u06cc\u062f \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0648 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u06a9\u0646\u0647\u060c \u0627\u0632 Cache \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0647 \u06cc\u0627 \u0627\u0635\u0644\u0627\u064b \u06a9\u0627\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u0646\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u062a\u0641\u0627\u0648\u062a \u062f\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u06a9\u0648\u0686\u06a9 \u062e\u06cc\u0644\u06cc \u0645\u0647\u0645 \u0628\u0647 \u0646\u0638\u0631 \u0646\u0645\u06cc\u200c\u0631\u0633\u0647\u060c \u0627\u0645\u0627 \u062f\u0631 \u0633\u06cc\u0633\u062a\u0645 \u0628\u0632\u0631\u06af \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 Event\u0647\u0627 \u0628\u0647 Intent \u0648\u0627\u0642\u0639\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0646\u0632\u062f\u06cc\u06a9 \u0628\u0645\u0648\u0646\u0646. \u0628\u0631\u0627\u06cc \u0645\u062b\u0627\u0644:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>DeleteProductClicked(productId)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">DeleteProductClicked<\/span><span style=\"color: #24292E\">(productId)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0627\u06cc\u0646 \u0645\u0639\u0646\u06cc \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0645\u062d\u0635\u0648\u0644 \u0628\u0627\u06cc\u062f \u0641\u0648\u0631\u0627\u064b \u062d\u0630\u0641 \u0628\u0634\u0647. ViewModel \u0645\u0645\u06a9\u0646\u0647 \u0627\u0628\u062a\u062f\u0627 Dialog \u062a\u0623\u06cc\u06cc\u062f \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0628\u062f\u0647. \u0627\u06af\u0631 Event \u0631\u0648 <code>DeleteProduct<\/code> \u0646\u0627\u0645\u200c\u06af\u0630\u0627\u0631\u06cc \u06a9\u0646\u06cc\u0645\u060c \u0627\u0632 \u0642\u0628\u0644 \u062f\u0631\u0628\u0627\u0631\u0647 \u0646\u062a\u06cc\u062c\u0647 \u062a\u0635\u0645\u06cc\u0645 \u06af\u0631\u0641\u062a\u0647\u200c\u0627\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0639\u0631\u06cc\u0641 State \u06a9\u0627\u0645\u0644 \u0635\u0641\u062d\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0628\u0627\u06cc\u062f \u0645\u0634\u062e\u0635 \u06a9\u0646\u06cc\u0645 UI \u0628\u0631\u0627\u06cc Render \u0634\u062f\u0646 \u0628\u0647 \u0686\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u06cc \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class TrackedProductsUiState(\n    val products: List&lt;TrackedProductUiModel> =\n        emptyList(),\n\n    val searchQuery: String = \"\",\n\n    val selectedSort: ProductSort =\n        ProductSort.LAST_UPDATED,\n\n    val isInitialLoading: Boolean = true,\n\n    val isRefreshing: Boolean = false,\n\n    val deletingProductId: Long? = null,\n\n    val productPendingDeletion:\n        TrackedProductUiModel? = null,\n\n    val userMessage: UiMessage? = null,\n\n    val navigationTarget:\n        TrackedProductsNavigation? = null,\n\n    val isOffline: Boolean = false\n) {\n    val showEmptyState: Boolean\n        get() =\n            !isInitialLoading &amp;&amp;\n            products.isEmpty() &amp;&amp;\n            searchQuery.isBlank()\n\n    val showNoSearchResult: Boolean\n        get() =\n            !isInitialLoading &amp;&amp;\n            products.isEmpty() &amp;&amp;\n            searchQuery.isNotBlank()\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductsUiState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> products: <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">TrackedProductUiModel<\/span><span style=\"color: #24292E\">&gt; <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">emptyList<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> searchQuery: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> selectedSort: <\/span><span style=\"color: #6F42C1\">ProductSort<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ProductSort.LAST_UPDATED,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isInitialLoading: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isRefreshing: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> deletingProductId: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productPendingDeletion:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductUiModel? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> userMessage: <\/span><span style=\"color: #6F42C1\">UiMessage<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> navigationTarget:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsNavigation? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isOffline: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> showEmptyState: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">!<\/span><span style=\"color: #24292E\">isInitialLoading <\/span><span style=\"color: #D73A49\">&amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            products.<\/span><span style=\"color: #6F42C1\">isEmpty<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">&amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            searchQuery.<\/span><span style=\"color: #6F42C1\">isBlank<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> showNoSearchResult: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">!<\/span><span style=\"color: #24292E\">isInitialLoading <\/span><span style=\"color: #D73A49\">&amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            products.<\/span><span style=\"color: #6F42C1\">isEmpty<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">&amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            searchQuery.<\/span><span style=\"color: #6F42C1\">isNotBlank<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">State \u0628\u0627\u06cc\u062f \u062a\u0645\u0627\u0645 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0644\u0627\u0632\u0645 \u0628\u0631\u0627\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0635\u0641\u062d\u0647 \u0631\u0648 \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 UI \u0642\u0631\u0627\u0631 \u0628\u062f\u0647. Composable \u0646\u0628\u0627\u06cc\u062f \u0645\u062c\u0628\u0648\u0631 \u0628\u0627\u0634\u0647 \u0627\u0632 \u0686\u0646\u062f \u0645\u0646\u0628\u0639 \u0645\u062e\u062a\u0644\u0641 \u062d\u062f\u0633 \u0628\u0632\u0646\u0647 \u06a9\u0647 \u0635\u0641\u062d\u0647 \u062f\u0631 \u0686\u0647 \u0648\u0636\u0639\u06cc\u062a\u06cc \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u0645\u200c\u0647\u0627 \u06cc\u06a9 \u0645\u062f\u0644 \u0645\u0633\u062a\u0642\u0644 \u062a\u0639\u0631\u06cc\u0641 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>sealed interface UiMessage {\n\n    data class Text(\n        val value: String\n    ) : UiMessage\n\n    data class Resource(\n        @StringRes\n        val resourceId: Int\n    ) : UiMessage\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">sealed<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">UiMessage<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Text<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\">: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">UiMessage<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Resource<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">@StringRes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> resourceId: <\/span><span style=\"color: #6F42C1\">Int<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">UiMessage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Navigation \u0647\u0645 \u0645\u062f\u0644 \u0645\u0634\u062e\u0635 \u062e\u0648\u062f\u0634 \u0631\u0648 \u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>sealed interface TrackedProductsNavigation {\n\n    data class ProductDetails(\n        val productId: Long\n    ) : TrackedProductsNavigation\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">sealed<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductsNavigation<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductDetails<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">TrackedProductsNavigation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0631\u062a\u0628\u200c\u0633\u0627\u0632\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>enum class ProductSort {\n    LAST_UPDATED,\n    LOWEST_PRICE,\n    HIGHEST_DISCOUNT,\n    ALPHABETICAL\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">enum<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductSort<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    LAST_UPDATED,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    LOWEST_PRICE,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    HIGHEST_DISCOUNT,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ALPHABETICAL<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062f\u0644 UI \u0628\u0647\u062a\u0631\u0647 \u0627\u0632 \u0645\u062f\u0644 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u06cc\u0627 API \u062c\u062f\u0627 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class TrackedProductUiModel(\n    val id: Long,\n    val title: String,\n    val formattedPrice: String,\n    val formattedPreviousPrice: String?,\n    val discountPercent: Int?,\n    val imageUrl: String?,\n    val hasPriceDrop: Boolean\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductUiModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> id: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> title: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> formattedPrice: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> formattedPreviousPrice: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">?,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> discountPercent: <\/span><span style=\"color: #6F42C1\">Int<\/span><span style=\"color: #24292E\">?,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> imageUrl: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">?,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> hasPriceDrop: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Repository \u0645\u0645\u06a9\u0646\u0647 \u0642\u06cc\u0645\u062a \u0631\u0648 \u0628\u0647\u200c\u0635\u0648\u0631\u062a <code>Long<\/code> \u0648 \u062a\u0627\u0631\u06cc\u062e \u0631\u0648 \u0628\u0647\u200c\u0635\u0648\u0631\u062a <code>Instant<\/code> \u0628\u062f\u0647\u060c \u0627\u0645\u0627 UI \u0641\u0642\u0637 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0622\u0645\u0627\u062f\u0647 \u0646\u0645\u0627\u06cc\u0634 \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 Formatting \u0648 \u062a\u0635\u0645\u06cc\u0645\u200c\u0647\u0627\u06cc \u0646\u0645\u0627\u06cc\u0634\u06cc \u062f\u0631 \u06cc\u06a9 \u0646\u0642\u0637\u0647 \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u06cc\u06a9 Event Handler \u0645\u0631\u06a9\u0632\u06cc \u06cc\u0627 \u0686\u0646\u062f \u062a\u0627\u0628\u0639 \u062c\u062f\u0627\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0648 \u0633\u0628\u06a9 \u0631\u0627\u06cc\u062c \u0628\u0631\u0627\u06cc \u062f\u0631\u06cc\u0627\u0641\u062a Event \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647. \u062f\u0631 \u0633\u0628\u06a9 \u0627\u0648\u0644\u060c ViewModel \u0628\u0631\u0627\u06cc \u0647\u0631 \u0639\u0645\u0644\u06cc\u0627\u062a \u062a\u0627\u0628\u0639 \u0645\u0633\u062a\u0642\u0644 \u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun refresh()\nfun search(query: String)\nfun deleteProduct(id: Long)\nfun openProduct(id: Long)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">refresh<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">search<\/span><span style=\"color: #24292E\">(query: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">deleteProduct<\/span><span style=\"color: #24292E\">(id: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">openProduct<\/span><span style=\"color: #24292E\">(id: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0633\u0628\u06a9 \u062f\u0648\u0645\u060c \u062a\u0645\u0627\u0645 Event\u0647\u0627 \u0627\u0632 \u06cc\u06a9 \u0648\u0631\u0648\u062f\u06cc \u0639\u0628\u0648\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun onEvent(\n    event: TrackedProductsEvent\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    event: <\/span><span style=\"color: #6F42C1\">TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0631 \u062f\u0648 \u0631\u0648\u0634 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u062f\u0631\u0633\u062a \u0628\u0627\u0634\u0646. Android \u062f\u0631 \u0645\u062b\u0627\u0644\u200c\u0647\u0627\u06cc \u0631\u0633\u0645\u06cc \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u062a\u0648\u0627\u0628\u0639 \u0631\u0648 \u0628\u0631\u0627\u0633\u0627\u0633 \u0641\u0639\u0644 \u0646\u0627\u0645\u200c\u06af\u0630\u0627\u0631\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0645\u062b\u0644 <code>refresh<\/code> \u06cc\u0627 <code>login<\/code>\u060c \u0648 UI \u0631\u0648\u06cc\u062f\u0627\u062f \u0631\u0648 \u0627\u0632 \u0637\u0631\u06cc\u0642 Callback\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 <code>onRefreshClicked<\/code> \u0628\u0627\u0644\u0627 \u0645\u06cc\u200c\u0641\u0631\u0633\u062a\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u062f\u0631\u0633 \u0627\u0632 \u0648\u0631\u0648\u062f\u06cc \u0645\u0631\u06a9\u0632\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645\u060c \u0686\u0648\u0646 \u0628\u0631\u0627\u06cc \u0622\u0645\u0648\u0632\u0634 Event-Driven UI \u062c\u0631\u06cc\u0627\u0646 \u0631\u0648 \u0648\u0627\u0636\u062d\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun onEvent(\n    event: TrackedProductsEvent\n) {\n    when (event) {\n        TrackedProductsEvent.ScreenStarted -> {\n            handleScreenStarted()\n        }\n\n        TrackedProductsEvent.RefreshClicked -> {\n            refreshProducts()\n        }\n\n        TrackedProductsEvent.RetryClicked -> {\n            refreshProducts()\n        }\n\n        is TrackedProductsEvent\n            .SearchQueryChanged -> {\n            updateSearchQuery(\n                event.query\n            )\n        }\n\n        is TrackedProductsEvent\n            .SortChanged -> {\n            updateSort(\n                event.sort\n            )\n        }\n\n        is TrackedProductsEvent\n            .ProductClicked -> {\n            selectProduct(\n                event.productId\n            )\n        }\n\n        is TrackedProductsEvent\n            .DeleteProductClicked -> {\n            requestProductDeletion(\n                event.productId\n            )\n        }\n\n        TrackedProductsEvent\n            .DeleteDialogConfirmed -> {\n            confirmProductDeletion()\n        }\n\n        TrackedProductsEvent\n            .DeleteDialogDismissed -> {\n            dismissDeleteDialog()\n        }\n\n        TrackedProductsEvent\n            .UserMessageShown -> {\n            clearUserMessage()\n        }\n\n        TrackedProductsEvent\n            .NavigationHandled -> {\n            clearNavigationTarget()\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    event: <\/span><span style=\"color: #6F42C1\">TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (event) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent.ScreenStarted <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">handleScreenStarted<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent.RefreshClicked <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">refreshProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent.RetryClicked <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">refreshProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .SearchQueryChanged <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">updateSearchQuery<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                event.query<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .SortChanged <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">updateSort<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                event.sort<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .ProductClicked <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">selectProduct<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                event.productId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .DeleteProductClicked <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">requestProductDeletion<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                event.productId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .DeleteDialogConfirmed <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">confirmProductDeletion<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .DeleteDialogDismissed <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">dismissDeleteDialog<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .UserMessageShown <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">clearUserMessage<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .NavigationHandled <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">clearNavigationTarget<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0632\u06cc\u062a \u0627\u06cc\u0646 \u0645\u062f\u0644 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u062a\u0645\u0627\u0645 \u0648\u0631\u0648\u062f\u06cc\u200c\u0647\u0627\u06cc \u0635\u0641\u062d\u0647 \u0627\u0632 \u06cc\u06a9 \u062f\u0631\u06af\u0627\u0647 \u0639\u0628\u0648\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646. \u0628\u0631\u0627\u06cc Logging\u060c \u062a\u0633\u062a \u0648 \u0628\u0631\u0631\u0633\u06cc \u062c\u0631\u06cc\u0627\u0646 \u0631\u0641\u062a\u0627\u0631 \u0647\u0645 \u0633\u0627\u062f\u0647\u200c\u062a\u0631\u0647. \u0627\u0645\u0627 \u0646\u0628\u0627\u06cc\u062f <code>onEvent<\/code> \u062a\u0628\u062f\u06cc\u0644 \u0628\u0647 \u06cc\u06a9 \u062a\u0627\u0628\u0639 \u0647\u0632\u0627\u0631\u062e\u0637\u06cc \u0628\u0634\u0647. \u0627\u06cc\u0646 \u062a\u0627\u0628\u0639 \u0641\u0642\u0637 Event \u0631\u0648 \u0628\u0647 Handler \u0645\u0646\u0627\u0633\u0628 \u0647\u062f\u0627\u06cc\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 \u0645\u0646\u0637\u0642 \u0647\u0631 \u0639\u0645\u0644\u06cc\u0627\u062a \u062f\u0627\u062e\u0644 \u062a\u0627\u0628\u0639 \u062c\u062f\u0627 \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0633\u0627\u062e\u062a ViewModel \u0631\u0648\u06cc\u062f\u0627\u062f\u0645\u062d\u0648\u0631<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 ViewModel \u0627\u0635\u0644\u06cc \u0631\u0648 \u0645\u06cc\u200c\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class TrackedProductsViewModel(\n    private val observeTrackedProducts:\n        ObserveTrackedProductsUseCase,\n\n    private val refreshTrackedProducts:\n        RefreshTrackedProductsUseCase,\n\n    private val deleteTrackedProduct:\n        DeleteTrackedProductUseCase,\n\n    private val productUiMapper:\n        TrackedProductUiMapper,\n\n    private val savedStateHandle:\n        SavedStateHandle\n) : ViewModel() {\n\n    private val searchQuery =\n        savedStateHandle.getStateFlow(\n            key = SEARCH_QUERY_KEY,\n            initialValue = \"\"\n        )\n\n    private val selectedSort =\n        savedStateHandle.getStateFlow(\n            key = SORT_KEY,\n            initialValue =\n                ProductSort\n                    .LAST_UPDATED\n                    .name\n        )\n\n    private val internalState =\n        MutableStateFlow(\n            InternalState()\n        )\n\n    val uiState:\n        StateFlow&lt;TrackedProductsUiState> =\n        combine(\n            observeTrackedProducts(),\n            searchQuery,\n            selectedSort,\n            internalState\n        ) {\n            products,\n            query,\n            sortName,\n            internal ->\n\n            val sort =\n                runCatching {\n                    ProductSort.valueOf(\n                        sortName\n                    )\n                }.getOrDefault(\n                    ProductSort.LAST_UPDATED\n                )\n\n            val visibleProducts =\n                products\n                    .filterByQuery(query)\n                    .sortedBy(sort)\n                    .map(\n                        productUiMapper::map\n                    )\n\n            TrackedProductsUiState(\n                products =\n                    visibleProducts,\n\n                searchQuery =\n                    query,\n\n                selectedSort =\n                    sort,\n\n                isInitialLoading =\n                    internal\n                        .isInitialLoading,\n\n                isRefreshing =\n                    internal\n                        .isRefreshing,\n\n                deletingProductId =\n                    internal\n                        .deletingProductId,\n\n                productPendingDeletion =\n                    internal\n                        .pendingDeletion\n                        ?.let(\n                            productUiMapper::map\n                        ),\n\n                userMessage =\n                    internal.userMessage,\n\n                navigationTarget =\n                    internal\n                        .navigationTarget,\n\n                isOffline =\n                    internal.isOffline\n            )\n        }\n            .stateIn(\n                scope = viewModelScope,\n                started =\n                    SharingStarted\n                        .WhileSubscribed(5_000),\n                initialValue =\n                    TrackedProductsUiState()\n            )\n\n    init {\n        observeInitialData()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductsViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> observeTrackedProducts:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ObserveTrackedProductsUseCase,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> refreshTrackedProducts:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        RefreshTrackedProductsUseCase,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> deleteTrackedProduct:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        DeleteTrackedProductUseCase,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productUiMapper:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductUiMapper,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> savedStateHandle:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        SavedStateHandle<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ViewModel<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> searchQuery <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        savedStateHandle.<\/span><span style=\"color: #6F42C1\">getStateFlow<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            key <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> SEARCH_QUERY_KEY,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            initialValue <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> selectedSort <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        savedStateHandle.<\/span><span style=\"color: #6F42C1\">getStateFlow<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            key <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> SORT_KEY,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            initialValue <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ProductSort<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .LAST_UPDATED<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> internalState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">MutableStateFlow<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">InternalState<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> uiState:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        StateFlow<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">TrackedProductsUiState<\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">combine<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">observeTrackedProducts<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            searchQuery,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            selectedSort,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            internalState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            products,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            query,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            sortName,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">internal<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> sort <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">runCatching<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ProductSort.<\/span><span style=\"color: #6F42C1\">valueOf<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        sortName<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }.<\/span><span style=\"color: #6F42C1\">getOrDefault<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ProductSort.LAST_UPDATED<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> visibleProducts <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                products<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">filterByQuery<\/span><span style=\"color: #24292E\">(query)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">sortedBy<\/span><span style=\"color: #24292E\">(sort)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        productUiMapper::<\/span><span style=\"color: #6F42C1\">map<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">TrackedProductsUiState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    visibleProducts,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                searchQuery <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    query,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                selectedSort <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    sort,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                isInitialLoading <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #D73A49\">internal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .isInitialLoading,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                isRefreshing <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #D73A49\">internal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .isRefreshing,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                deletingProductId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #D73A49\">internal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .deletingProductId,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                productPendingDeletion <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #D73A49\">internal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .pendingDeletion<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        ?.<\/span><span style=\"color: #6F42C1\">let<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            productUiMapper::<\/span><span style=\"color: #6F42C1\">map<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        ),<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                userMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #D73A49\">internal<\/span><span style=\"color: #24292E\">.userMessage,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                navigationTarget <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #D73A49\">internal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .navigationTarget,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                isOffline <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #D73A49\">internal<\/span><span style=\"color: #24292E\">.isOffline<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">stateIn<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                scope <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> viewModelScope,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                started <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    SharingStarted<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">WhileSubscribed<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">5_000<\/span><span style=\"color: #24292E\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                initialValue <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #6F42C1\">TrackedProductsUiState<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">init<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">observeInitialData<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646\u062c\u0627 State \u0646\u0647\u0627\u06cc\u06cc \u0627\u0632 \u0686\u0646\u062f \u0645\u0646\u0628\u0639 \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Room data\nSearch query\nSelected sort\nInternal operation state\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Room <\/span><span style=\"color: #D73A49\">data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Search query<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Selected sort<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Internal operation state<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0641\u0642\u0637 \u06cc\u06a9 <code>uiState<\/code> \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0627\u0645\u0627 ViewModel \u062f\u0631 \u062f\u0627\u062e\u0644 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0686\u0646\u062f \u062c\u0631\u06cc\u0627\u0646 \u0631\u0648 \u0628\u0627 \u0647\u0645 \u062a\u0631\u06a9\u06cc\u0628 \u06a9\u0646\u0647. \u0627\u06cc\u0646 \u062f\u0642\u06cc\u0642\u0627\u064b \u0646\u0642\u0634 UI Layer\u0647: \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0631\u0648 \u0628\u0647 \u0634\u06a9\u0644\u06cc \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0646\u0647 \u06a9\u0647 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0628\u062a\u0648\u0646\u0647 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b Render \u06a9\u0646\u0647. Android \u0647\u0645 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647 ViewModel \u0648\u0636\u0639\u06cc\u062a \u0642\u0627\u0628\u0644\u200c\u0645\u0634\u0627\u0647\u062f\u0647 \u0631\u0648 \u0627\u0632 \u0637\u0631\u06cc\u0642 \u0633\u0627\u062e\u062a\u0627\u0631\u06cc \u0645\u062b\u0644 <code>StateFlow<\/code> \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 UI \u0642\u0631\u0627\u0631 \u0628\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">State \u062f\u0627\u062e\u0644\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private data class InternalState(\n    val isInitialLoading: Boolean = true,\n    val isRefreshing: Boolean = false,\n    val deletingProductId: Long? = null,\n    val pendingDeletion:\n        TrackedProduct? = null,\n    val userMessage: UiMessage? = null,\n    val navigationTarget:\n        TrackedProductsNavigation? = null,\n    val isOffline: Boolean = false\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">InternalState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isInitialLoading: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isRefreshing: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> deletingProductId: <\/span><span style=\"color: #6F42C1\">Long<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> pendingDeletion:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProduct? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> userMessage: <\/span><span style=\"color: #6F42C1\">UiMessage<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> navigationTarget:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsNavigation? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isOffline: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0645\u06a9\u0646\u0647 \u0628\u067e\u0631\u0633\u06cc \u0686\u0631\u0627 \u0645\u0633\u062a\u0642\u06cc\u0645 \u06cc\u06a9 <code>MutableStateFlow&lt;TrackedProductsUiState&gt;<\/code> \u0646\u0633\u0627\u062e\u062a\u06cc\u0645. \u0686\u0648\u0646 \u0628\u062e\u0634\u06cc \u0627\u0632 State \u0627\u0632 Room\u060c Search \u0648 Sort \u0645\u062d\u0627\u0633\u0628\u0647 \u0645\u06cc\u0634\u0647. \u0627\u06af\u0631 \u0647\u0631 \u0628\u0627\u0631 \u0647\u0645\u0647 \u0627\u06cc\u0646 \u062f\u0627\u062f\u0647\u200c\u0647\u0627 \u0631\u0648 \u062f\u0633\u062a\u06cc \u062f\u0627\u062e\u0644 \u06cc\u06a9 State \u06a9\u067e\u06cc \u06a9\u0646\u06cc\u0645\u060c \u0627\u062d\u062a\u0645\u0627\u0644 \u0646\u0627\u0633\u0627\u0632\u06af\u0627\u0631\u06cc \u0628\u0627\u0644\u0627 \u0645\u06cc\u0631\u0647. \u0628\u0627 <code>combine<\/code>\u060c State \u0646\u0647\u0627\u06cc\u06cc \u0627\u0632 Source\u0647\u0627\u06cc \u0645\u0634\u062e\u0635 \u0645\u0634\u062a\u0642 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0634\u0631\u0648\u0639 \u0635\u0641\u062d\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc ViewModel \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647\u060c \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc Room \u0627\u0632 \u0637\u0631\u06cc\u0642 <code>observeTrackedProducts()<\/code> \u0628\u0647\u200c\u0635\u0648\u0631\u062a Flow \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u0634\u0646. \u062f\u0631 \u06a9\u0646\u0627\u0631 \u0627\u0648\u0646 \u0645\u06cc\u200c\u062e\u0648\u0627\u06cc\u0645 \u06cc\u06a9 Refresh \u0627\u0648\u0644\u06cc\u0647 \u0647\u0645 \u0627\u0646\u062c\u0627\u0645 \u0628\u062f\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun observeInitialData() {\n    viewModelScope.launch {\n        refreshTrackedProducts()\n            .onSuccess {\n                internalState.update {\n                    it.copy(\n                        isInitialLoading =\n                            false,\n                        isOffline = false\n                    )\n                }\n            }\n            .onFailure { throwable ->\n                internalState.update {\n                    it.copy(\n                        isInitialLoading =\n                            false,\n                        isOffline =\n                            throwable\n                                is IOException,\n                        userMessage =\n                            throwable\n                                .toUiMessage()\n                    )\n                }\n            }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">observeInitialData<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    viewModelScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">refreshTrackedProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">onSuccess<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        isInitialLoading <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        isOffline <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">onFailure<\/span><span style=\"color: #24292E\"> { throwable <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        isInitialLoading <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        isOffline <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            throwable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> IOException,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        userMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            throwable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                .<\/span><span style=\"color: #6F42C1\">toUiMessage<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc\u060c \u062d\u062a\u06cc \u0627\u06af\u0631 Network \u0634\u06a9\u0633\u062a \u0628\u062e\u0648\u0631\u0647\u060c \u062f\u0627\u062f\u0647 Cache\u0634\u062f\u0647 Room \u0647\u0645\u0686\u0646\u0627\u0646 \u062f\u0627\u062e\u0644 UI \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0645\u06cc\u0634\u0647. <code>isInitialLoading<\/code> \u0641\u0642\u0637 \u0632\u0645\u0627\u0646\u06cc \u0631\u0648\u0634\u0646\u0647 \u06a9\u0647 \u0647\u0646\u0648\u0632 \u0627\u0648\u0644\u06cc\u0646 \u062a\u0644\u0627\u0634 \u0628\u0631\u0627\u06cc \u0622\u0645\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0635\u0641\u062d\u0647 \u062a\u0645\u0627\u0645 \u0646\u0634\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0642\u062a \u06a9\u0646 \u06a9\u0647 <code>ScreenStarted<\/code> \u0648 <code>init<\/code> \u0631\u0648 \u0646\u0628\u0627\u06cc\u062f \u0647\u0645\u200c\u0632\u0645\u0627\u0646 \u0628\u0631\u0627\u06cc \u06cc\u06a9 \u06a9\u0627\u0631 \u062a\u06a9\u0631\u0627\u0631\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645. \u0627\u06af\u0631 <code>init<\/code> Refresh \u0631\u0648 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u062f\u0647\u060c \u0641\u0631\u0633\u062a\u0627\u062f\u0646 <code>ScreenStarted<\/code> \u0627\u0632 Composable \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0648\u0645 \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0647. \u06cc\u06a9\u06cc \u0627\u0632 \u0627\u06cc\u0646 \u062f\u0648 \u0645\u062f\u0644 \u0631\u0648 \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ViewModel init\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>LaunchedEffect(Unit) \u2192 ScreenStarted\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">LaunchedEffect<\/span><span style=\"color: #24292E\">(Unit) \u2192 ScreenStarted<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0639\u0645\u0644\u06cc\u0627\u062a\u06cc \u06a9\u0647 \u0628\u0627\u06cc\u062f \u062f\u0642\u06cc\u0642\u0627\u064b \u06cc\u06a9 \u0628\u0627\u0631 \u062f\u0631 \u0639\u0645\u0631 ViewModel \u0627\u062c\u0631\u0627 \u0628\u0634\u0646\u060c <code>init<\/code> \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0633\u0627\u062f\u0647\u200c\u062a\u0631\u0647. \u0628\u0631\u0627\u06cc \u0639\u0645\u0644\u06cc\u0627\u062a\u06cc \u06a9\u0647 \u0648\u0627\u0628\u0633\u062a\u0647 \u0628\u0647 \u062d\u0636\u0648\u0631 UI \u06cc\u0627 \u067e\u0627\u0631\u0627\u0645\u062a\u0631 \u0635\u0641\u062d\u0647\u200c\u0627\u0646\u060c Event \u0634\u0631\u0648\u0639 \u0635\u0641\u062d\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0645\u0646\u0627\u0633\u0628\u200c\u062a\u0631 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0645\u062f\u06cc\u0631\u06cc\u062a Refresh<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Refresh \u06cc\u06a9 Event \u06a9\u0627\u0631\u0628\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun refreshProducts() {\n    if (\n        internalState.value\n            .isRefreshing\n    ) {\n        return\n    }\n\n    viewModelScope.launch {\n        internalState.update {\n            it.copy(\n                isRefreshing = true,\n                userMessage = null\n            )\n        }\n\n        refreshTrackedProducts()\n            .onSuccess {\n                internalState.update {\n                    it.copy(\n                        isRefreshing = false,\n                        isOffline = false,\n                        userMessage =\n                            UiMessage.Resource(\n                                R.string\n                                    .products_updated\n                            )\n                    )\n                }\n            }\n            .onFailure { throwable ->\n                internalState.update {\n                    it.copy(\n                        isRefreshing = false,\n                        isOffline =\n                            throwable\n                                is IOException,\n                        userMessage =\n                            throwable\n                                .toUiMessage()\n                    )\n                }\n            }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">refreshProducts<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        internalState.<\/span><span style=\"color: #D73A49\">value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .isRefreshing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    viewModelScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                isRefreshing <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                userMessage <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">refreshTrackedProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">onSuccess<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        isRefreshing <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        isOffline <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        userMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            UiMessage.<\/span><span style=\"color: #6F42C1\">Resource<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                R.string<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                    .products_updated<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">onFailure<\/span><span style=\"color: #24292E\"> { throwable <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        isRefreshing <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        isOffline <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            throwable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> IOException,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        userMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            throwable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                .<\/span><span style=\"color: #6F42C1\">toUiMessage<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">UI \u0641\u0642\u0637 Event \u0645\u06cc\u200c\u0641\u0631\u0633\u062a\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>onEvent(\n    TrackedProductsEvent\n        .RefreshClicked\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .RefreshClicked<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646\u06a9\u0647 \u0647\u0646\u06af\u0627\u0645 Refresh \u0686\u0647 \u0686\u06cc\u0632\u06cc \u067e\u0627\u06a9 \u0628\u0634\u0647\u060c \u0686\u0647 \u067e\u06cc\u0627\u0645 \u0645\u0648\u0641\u0642\u06cc\u062a\u06cc \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0628\u0634\u0647 \u0648 \u0622\u06cc\u0627 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062a\u06a9\u0631\u0627\u0631\u06cc \u0631\u062f \u0628\u0634\u0647\u060c \u0647\u0645\u06af\u06cc \u062a\u0635\u0645\u06cc\u0645 ViewModel \u0647\u0633\u062a\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0633\u062a\u200c\u0648\u062c\u0648 \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 Event<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0639\u0628\u0627\u0631\u062a \u062c\u0633\u062a\u200c\u0648\u062c\u0648 State \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0647\u060c \u0627\u0645\u0627 \u062a\u063a\u06cc\u06cc\u0631 \u0627\u0648\u0646 \u0628\u0627 Event \u0627\u062a\u0641\u0627\u0642 \u0645\u06cc\u200c\u0627\u0641\u062a\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun updateSearchQuery(\n    query: String\n) {\n    savedStateHandle&#91;\n        SEARCH_QUERY_KEY\n    &#93; = query\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">updateSearchQuery<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    query: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    savedStateHandle&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        SEARCH_QUERY_KEY<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    &#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> query<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0686\u0648\u0646 Query \u062f\u0627\u062e\u0644 <code>SavedStateHandle<\/code> \u0630\u062e\u06cc\u0631\u0647 \u0634\u062f\u0647\u060c \u0628\u0639\u062f \u0627\u0632 \u0628\u0627\u0632\u0633\u0627\u0632\u06cc Process \u0647\u0645 \u0627\u0645\u06a9\u0627\u0646 \u0628\u0627\u0632\u06cc\u0627\u0628\u06cc \u0627\u0648\u0646 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647. \u0627\u0644\u0628\u062a\u0647 \u0641\u0642\u0637 State\u0647\u0627\u06cc\u06cc \u0631\u0648 \u0628\u0627\u06cc\u062f \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0646\u06cc\u0645 \u06a9\u0647 \u06a9\u0648\u0686\u06a9 \u0648 \u0642\u0627\u0628\u0644\u200cSerialize \u0628\u0627\u0634\u0646. \u0641\u0647\u0631\u0633\u062a \u06a9\u0627\u0645\u0644 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0645\u062a\u0639\u0644\u0642 \u0628\u0647 Room \u06cc\u0627 Repository\u0647 \u0648 \u0646\u0628\u0627\u06cc\u062f \u062f\u0627\u062e\u0644 <code>SavedStateHandle<\/code> \u0630\u062e\u06cc\u0631\u0647 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u06cc\u0644\u062a\u0631 \u0645\u062d\u0635\u0648\u0644\u0627\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun List&lt;TrackedProduct>\n    .filterByQuery(\n        query: String\n    ): List&lt;TrackedProduct> {\n\n    val normalizedQuery =\n        query.trim()\n\n    if (normalizedQuery.isBlank()) {\n        return this\n    }\n\n    return filter { product ->\n        product.title.contains(\n            other = normalizedQuery,\n            ignoreCase = true\n        )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">TrackedProduct<\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    .<\/span><span style=\"color: #6F42C1\">filterByQuery<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        query: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">TrackedProduct<\/span><span style=\"color: #24292E\">&gt; {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> normalizedQuery <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        query.<\/span><span style=\"color: #6F42C1\">trim<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (normalizedQuery.<\/span><span style=\"color: #6F42C1\">isBlank<\/span><span style=\"color: #24292E\">()) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">this<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">filter<\/span><span style=\"color: #24292E\"> { product <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        product.title.<\/span><span style=\"color: #6F42C1\">contains<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            other <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> normalizedQuery,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ignoreCase <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0631\u062a\u0628\u200c\u0633\u0627\u0632\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun List&lt;TrackedProduct>\n    .sortedBy(\n        sort: ProductSort\n    ): List&lt;TrackedProduct> {\n\n    return when (sort) {\n        ProductSort.LAST_UPDATED -> {\n            sortedByDescending {\n                it.updatedAt\n            }\n        }\n\n        ProductSort.LOWEST_PRICE -> {\n            sortedBy {\n                it.currentPrice\n            }\n        }\n\n        ProductSort.HIGHEST_DISCOUNT -> {\n            sortedByDescending {\n                it.discountPercent\n                    ?: 0\n            }\n        }\n\n        ProductSort.ALPHABETICAL -> {\n            sortedBy {\n                it.title\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">TrackedProduct<\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    .<\/span><span style=\"color: #6F42C1\">sortedBy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        sort: <\/span><span style=\"color: #6F42C1\">ProductSort<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">TrackedProduct<\/span><span style=\"color: #24292E\">&gt; {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (sort) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ProductSort.LAST_UPDATED <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">sortedByDescending<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                it.updatedAt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ProductSort.LOWEST_PRICE <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">sortedBy<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                it.currentPrice<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ProductSort.HIGHEST_DISCOUNT <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">sortedByDescending<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                it.discountPercent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    ?: <\/span><span style=\"color: #005CC5\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ProductSort.ALPHABETICAL <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">sortedBy<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                it.title<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u063a\u06cc\u06cc\u0631 Sort:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun updateSort(\n    sort: ProductSort\n) {\n    savedStateHandle&#91;\n        SORT_KEY\n    &#93; = sort.name\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">updateSort<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    sort: <\/span><span style=\"color: #6F42C1\">ProductSort<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    savedStateHandle&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        SORT_KEY<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    &#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> sort.name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Dialog \u062d\u0630\u0641 \u0647\u0645 \u0628\u062e\u0634\u06cc \u0627\u0632 State\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0645\u0627\u06cc\u0634 Dialog \u0646\u0628\u0627\u06cc\u062f \u06cc\u06a9 \u0641\u0631\u0645\u0627\u0646 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0645\u062b\u0644 \u0627\u06cc\u0646 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>_showDeleteDialog.emit(product)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">_showDeleteDialog.<\/span><span style=\"color: #6F42C1\">emit<\/span><span style=\"color: #24292E\">(product)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Dialog \u062f\u0631 \u0647\u0631 \u0644\u062d\u0638\u0647 \u06cc\u0627 \u0628\u0627\u0632\u0647 \u06cc\u0627 \u0628\u0633\u062a\u0647\u200c\u0633\u062a. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0648\u0636\u0639\u06cc\u062a \u0627\u0648\u0646 \u0631\u0648 \u0645\u06cc\u0634\u0647 \u0628\u0647\u200c\u0637\u0648\u0631 \u0637\u0628\u06cc\u0639\u06cc \u062f\u0627\u062e\u0644 UI State \u0646\u06af\u0647 \u062f\u0627\u0634\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun requestProductDeletion(\n    productId: Long\n) {\n    val product =\n        observeTrackedProducts\n            .currentProducts()\n            .firstOrNull {\n                it.id == productId\n            }\n            ?: return\n\n    internalState.update {\n        it.copy(\n            pendingDeletion =\n                product\n        )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">requestProductDeletion<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> product <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        observeTrackedProducts<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">currentProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">firstOrNull<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                it.id <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> productId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ?: <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            pendingDeletion <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                product<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0645\u0639\u0645\u0627\u0631\u06cc \u0628\u0647\u062a\u0631\u060c Repository \u06cc\u0627 \u06cc\u06a9 State Cache \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0645\u062d\u0635\u0648\u0644 \u0641\u0639\u0644\u06cc \u0631\u0648 \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 ViewModel \u0642\u0631\u0627\u0631 \u0628\u062f\u0647. \u06cc\u0627 Event \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0645\u062f\u0644 UI \u0645\u0648\u0631\u062f\u0646\u06cc\u0627\u0632 \u0631\u0648 \u062d\u0645\u0644 \u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class DeleteProductClicked(\n    val product:\n        TrackedProductUiModel\n) : TrackedProductsEvent\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DeleteProductClicked<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> product:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductUiModel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0628\u0647\u062a\u0631\u0647 Event \u0641\u0642\u0637 \u0634\u0646\u0627\u0633\u0647 \u0631\u0648 \u062d\u0645\u0644 \u06a9\u0646\u0647 \u0648 ViewModel \u0645\u0648\u062c\u0648\u062f\u06cc\u062a \u0627\u0635\u0644\u06cc \u0631\u0648 \u0627\u0632 \u0645\u0646\u0628\u0639 \u0645\u0639\u062a\u0628\u0631 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u0647. \u062f\u0627\u062f\u0647 UI \u0645\u0645\u06a9\u0646\u0647 \u0642\u062f\u06cc\u0645\u06cc \u06cc\u0627 \u062a\u063a\u06cc\u06cc\u0631\u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u0647. \u0628\u0633\u062a\u0646 Dialog:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun dismissDeleteDialog() {\n    internalState.update {\n        it.copy(\n            pendingDeletion = null\n        )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">dismissDeleteDialog<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            pendingDeletion <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0623\u06cc\u06cc\u062f \u062d\u0630\u0641:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun confirmProductDeletion() {\n    val product =\n        internalState.value\n            .pendingDeletion\n            ?: return\n\n    if (\n        internalState.value\n            .deletingProductId != null\n    ) {\n        return\n    }\n\n    viewModelScope.launch {\n        internalState.update {\n            it.copy(\n                pendingDeletion = null,\n                deletingProductId =\n                    product.id\n            )\n        }\n\n        deleteTrackedProduct(\n            product.id\n        )\n            .onSuccess {\n                internalState.update {\n                    it.copy(\n                        deletingProductId =\n                            null,\n                        userMessage =\n                            UiMessage.Text(\n                                \"\u0645\u062d\u0635\u0648\u0644 \u062d\u0630\u0641 \u0634\u062f.\"\n                            )\n                    )\n                }\n            }\n            .onFailure { throwable ->\n                internalState.update {\n                    it.copy(\n                        deletingProductId =\n                            null,\n                        userMessage =\n                            throwable\n                                .toUiMessage()\n                    )\n                }\n            }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">confirmProductDeletion<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> product <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        internalState.<\/span><span style=\"color: #D73A49\">value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .pendingDeletion<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ?: <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        internalState.<\/span><span style=\"color: #D73A49\">value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .deletingProductId <\/span><span style=\"color: #D73A49\">!=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    viewModelScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                pendingDeletion <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                deletingProductId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    product.id<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">deleteTrackedProduct<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            product.id<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">onSuccess<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        deletingProductId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        userMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            UiMessage.<\/span><span style=\"color: #6F42C1\">Text<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                <\/span><span style=\"color: #032F62\">&quot;\u0645\u062d\u0635\u0648\u0644 \u062d\u0630\u0641 \u0634\u062f.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">onFailure<\/span><span style=\"color: #24292E\"> { throwable <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        deletingProductId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        userMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            throwable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                .<\/span><span style=\"color: #6F42C1\">toUiMessage<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u062d\u0630\u0641 Optimistic \u0628\u0627\u0634\u0647\u060c \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 \u0641\u0648\u0631\u06cc \u0627\u0632 Room \u062d\u0630\u0641 \u06a9\u0646\u06cc\u0645 \u0648 \u062f\u0631 \u0635\u0648\u0631\u062a \u062e\u0637\u0627 \u0628\u0631\u06af\u0631\u062f\u0648\u0646\u06cc\u0645. \u0627\u0645\u0627 \u0627\u06cc\u0646 \u062a\u0635\u0645\u06cc\u0645 \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 Data \u0648 Domain Layer\u0647\u060c \u0646\u0647 Composable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Snackbar\u061b Event \u06cc\u06a9\u200c\u0628\u0627\u0631\u0647 \u06cc\u0627 State \u0645\u0635\u0631\u0641\u200c\u0634\u0648\u0646\u062f\u0647\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Snackbar \u0645\u0648\u0642\u062a\u0647\u060c \u0627\u0645\u0627 \u0648\u0636\u0639\u06cc\u062a \u00ab\u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u062f\u0631 \u0627\u0646\u062a\u0638\u0627\u0631 \u0646\u0645\u0627\u06cc\u0634 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647\u00bb \u0642\u0627\u0628\u0644\u200c\u0645\u062f\u0644\u200c\u0633\u0627\u0632\u06cc \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 State \u0647\u0633\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val userMessage: UiMessage?\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> userMessage: <\/span><span style=\"color: #6F42C1\">UiMessage<\/span><span style=\"color: #24292E\">?<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u067e\u06cc\u0627\u0645 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u0634\u0647\u060c State \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647. UI \u067e\u06cc\u0627\u0645 \u0631\u0648 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u062f\u0647 \u0648 \u0628\u0639\u062f Event \u0632\u06cc\u0631 \u0631\u0648 \u0645\u06cc\u200c\u0641\u0631\u0633\u062a\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>TrackedProductsEvent.UserMessageShown\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">TrackedProductsEvent.UserMessageShown<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">ViewModel \u067e\u06cc\u0627\u0645 \u0631\u0648 \u067e\u0627\u06a9 \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun clearUserMessage() {\n    internalState.update {\n        it.copy(\n            userMessage = null\n        )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">clearUserMessage<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            userMessage <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Composable:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nprivate fun ObserveUserMessage(\n    message: UiMessage?,\n    snackbarHostState:\n        SnackbarHostState,\n    onMessageShown: () -> Unit\n) {\n    val context =\n        LocalContext.current\n\n    LaunchedEffect(message) {\n        val currentMessage =\n            message ?: return@LaunchedEffect\n\n        val text =\n            when (currentMessage) {\n                is UiMessage.Text -> {\n                    currentMessage.value\n                }\n\n                is UiMessage.Resource -> {\n                    context.getString(\n                        currentMessage\n                            .resourceId\n                    )\n                }\n            }\n\n        snackbarHostState\n            .showSnackbar(text)\n\n        onMessageShown()\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ObserveUserMessage<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    message: <\/span><span style=\"color: #6F42C1\">UiMessage<\/span><span style=\"color: #24292E\">?,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    snackbarHostState:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        SnackbarHostState,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onMessageShown: () <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> context <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        LocalContext.current<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">LaunchedEffect<\/span><span style=\"color: #24292E\">(message) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> currentMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            message ?: <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\">@LaunchedEffect<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> text <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (currentMessage) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> UiMessage.Text <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    currentMessage.<\/span><span style=\"color: #D73A49\">value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> UiMessage.Resource <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    context.<\/span><span style=\"color: #6F42C1\">getString<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        currentMessage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            .resourceId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        snackbarHostState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">showSnackbar<\/span><span style=\"color: #24292E\">(text)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">onMessageShown<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0633\u062a\u0641\u0627\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>ObserveUserMessage(\n    message =\n        uiState.userMessage,\n\n    snackbarHostState =\n        snackbarHostState,\n\n    onMessageShown = {\n        onEvent(\n            TrackedProductsEvent\n                .UserMessageShown\n        )\n    }\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">ObserveUserMessage<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    message <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        uiState.userMessage,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    snackbarHostState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        snackbarHostState,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onMessageShown <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .UserMessageShown<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0627\u0644\u06af\u0648 \u06cc\u06a9 \u0645\u0632\u06cc\u062a \u0645\u0647\u0645 \u062f\u0627\u0631\u0647. \u0641\u0631\u0636 \u06a9\u0646 \u067e\u06cc\u0627\u0645 \u062f\u0631\u0633\u062a \u0632\u0645\u0627\u0646\u06cc \u062a\u0648\u0644\u06cc\u062f \u0628\u0634\u0647 \u06a9\u0647 Activity \u0628\u0647 Background \u0631\u0641\u062a\u0647. \u0686\u0648\u0646 \u067e\u06cc\u0627\u0645 \u062f\u0627\u062e\u0644 State \u0628\u0627\u0642\u06cc \u0645\u06cc\u200c\u0645\u0648\u0646\u0647\u060c \u0648\u0642\u062a\u06cc UI \u062f\u0648\u0628\u0627\u0631\u0647 \u0641\u0639\u0627\u0644 \u0634\u062f \u0627\u0648\u0646 \u0631\u0648 \u0645\u06cc\u200c\u0628\u06cc\u0646\u0647. \u062f\u0631 \u0645\u0642\u0627\u0628\u0644\u060c \u0627\u06af\u0631 \u067e\u06cc\u0627\u0645 \u0628\u0627 <code>SharedFlow(replay = 0)<\/code> \u0645\u0646\u062a\u0634\u0631 \u0634\u062f\u0647 \u0628\u0648\u062f\u060c \u0645\u0645\u06a9\u0646 \u0628\u0648\u062f \u0647\u06cc\u0686 Collector \u0641\u0639\u0627\u0644\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647 \u0648 \u067e\u06cc\u0627\u0645 \u0628\u0631\u0627\u06cc \u0647\u0645\u06cc\u0634\u0647 \u0627\u0632 \u0628\u06cc\u0646 \u0628\u0631\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0648\u0635\u06cc\u0647 \u0631\u0633\u0645\u06cc Android \u0647\u0645 \u062a\u0623\u06a9\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0627\u062a\u0641\u0627\u0642\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0627\u0632 ViewModel \u0622\u063a\u0627\u0632 \u0645\u06cc\u0634\u0646 \u0628\u0647\u062a\u0631\u0647 \u0628\u0647 \u062a\u063a\u06cc\u06cc\u0631 UI State \u0645\u0646\u062a\u0647\u06cc \u0628\u0634\u0646 \u062a\u0627 \u062f\u0631 \u0628\u0631\u0627\u0628\u0631 \u062a\u063a\u06cc\u06cc\u0631 Configuration \u06cc\u0627 \u0648\u0642\u0641\u0647 Lifecycle \u0642\u0627\u0628\u0644\u200c\u0628\u0627\u0632\u062a\u0648\u0644\u06cc\u062f \u0628\u0627\u0642\u06cc \u0628\u0645\u0648\u0646\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Navigation \u062f\u0631 \u0645\u0639\u0645\u0627\u0631\u06cc \u0631\u0648\u06cc\u062f\u0627\u062f\u0645\u062d\u0648\u0631<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Navigation \u062e\u0648\u062f\u0634 \u0645\u0646\u0637\u0642 UI \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0647 \u0648 ViewModel \u0646\u0628\u0627\u06cc\u062f <code>NavController<\/code> \u0631\u0648 \u0628\u0634\u0646\u0627\u0633\u0647. \u0627\u0645\u0627 ViewModel \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 State\u06cc \u062a\u0648\u0644\u06cc\u062f \u06a9\u0646\u0647 \u06a9\u0647 \u0646\u0634\u0627\u0646 \u0628\u062f\u0647 \u06a9\u0627\u0631\u0628\u0631 \u06cc\u06a9 \u0645\u062d\u0635\u0648\u0644 \u0631\u0648 \u0627\u0646\u062a\u062e\u0627\u0628 \u06a9\u0631\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun selectProduct(\n    productId: Long\n) {\n    internalState.update {\n        it.copy(\n            navigationTarget =\n                TrackedProductsNavigation\n                    .ProductDetails(\n                        productId\n                    )\n        )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">selectProduct<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            navigationTarget <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                TrackedProductsNavigation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .<\/span><span style=\"color: #6F42C1\">ProductDetails<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        productId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Composable \u0645\u0642\u0635\u062f \u0631\u0648 \u0645\u0634\u0627\u0647\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nprivate fun ObserveNavigation(\n    target:\n        TrackedProductsNavigation?,\n\n    onNavigateToProduct:\n        (Long) -> Unit,\n\n    onNavigationHandled:\n        () -> Unit\n) {\n    LaunchedEffect(target) {\n        when (target) {\n            is TrackedProductsNavigation\n                .ProductDetails -> {\n\n                onNavigateToProduct(\n                    target.productId\n                )\n\n                onNavigationHandled()\n            }\n\n            null -> Unit\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ObserveNavigation<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    target:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsNavigation?,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onNavigateToProduct:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        (Long) <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onNavigationHandled:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        () <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">LaunchedEffect<\/span><span style=\"color: #24292E\">(target) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (target) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsNavigation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .ProductDetails <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">onNavigateToProduct<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    target.productId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">onNavigationHandled<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 Navigation\u060c ViewModel \u0645\u0642\u0635\u062f \u0631\u0648 \u067e\u0627\u06a9 \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun clearNavigationTarget() {\n    internalState.update {\n        it.copy(\n            navigationTarget = null\n        )\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">clearNavigationTarget<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            navigationTarget <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0635\u0641\u062d\u0647 \u0627\u0635\u0644\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>ObserveNavigation(\n    target =\n        uiState.navigationTarget,\n\n    onNavigateToProduct = {\n        productId ->\n\n        navController.navigate(\n            \"product\/$productId\"\n        )\n    },\n\n    onNavigationHandled = {\n        onEvent(\n            TrackedProductsEvent\n                .NavigationHandled\n        )\n    }\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">ObserveNavigation<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    target <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        uiState.navigationTarget,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onNavigateToProduct <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        productId <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        navController.<\/span><span style=\"color: #6F42C1\">navigate<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;product\/<\/span><span style=\"color: #005CC5\">$productId<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onNavigationHandled <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .NavigationHandled<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0645\u062f\u0644 \u0627\u0632 \u0627\u0631\u0633\u0627\u0644 \u0645\u0633\u062a\u0642\u06cc\u0645 <code>NavController<\/code> \u0628\u0647 ViewModel \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 Navigation \u0631\u0648 \u0642\u0627\u0628\u0644\u200c\u062a\u0633\u062a \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0631\u0627 SharedFlow \u0647\u0645\u06cc\u0634\u0647 \u0627\u0646\u062a\u062e\u0627\u0628 \u062f\u0631\u0633\u062a\u06cc \u0628\u0631\u0627\u06cc UI Event \u0646\u06cc\u0633\u062a\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0644\u06af\u0648\u0647\u0627\u06cc \u0628\u0633\u06cc\u0627\u0631 \u0631\u0627\u06cc\u062c \u0627\u06cc\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private val _events =\n    MutableSharedFlow&lt;UiEvent>()\n\nval events =\n    _events.asSharedFlow()\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> _events <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">MutableSharedFlow<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">UiEvent<\/span><span style=\"color: #24292E\">&gt;()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> events <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    _events.<\/span><span style=\"color: #6F42C1\">asSharedFlow<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u0628\u0639\u062f:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>_events.emit(\n    UiEvent.ShowSnackbar(\n        \"\u062e\u0637\u0627 \u0631\u062e \u062f\u0627\u062f.\"\n    )\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">_events.<\/span><span style=\"color: #6F42C1\">emit<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    UiEvent.<\/span><span style=\"color: #6F42C1\">ShowSnackbar<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;\u062e\u0637\u0627 \u0631\u062e \u062f\u0627\u062f.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0631\u0648\u0634 \u062f\u0631 \u0628\u0639\u0636\u06cc \u0633\u0646\u0627\u0631\u06cc\u0648\u0647\u0627 \u062e\u0648\u0628\u0647\u060c \u0627\u0645\u0627 \u0628\u0627\u06cc\u062f \u0631\u0641\u062a\u0627\u0631 <code>SharedFlow<\/code> \u0631\u0648 \u0628\u0634\u0646\u0627\u0633\u06cc\u0645. SharedFlow \u0630\u0627\u062a\u0627\u064b Hot Stream\u0647 \u0648 \u0641\u0642\u0637 Collector\u0647\u0627\u06cc \u0641\u0639\u0627\u0644 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u0627\u0646\u062a\u0634\u0627\u0631\u0647\u0627\u06cc \u062c\u0627\u0631\u06cc \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u0646\u060c \u0645\u06af\u0631 \u0627\u06cc\u0646\u06a9\u0647 Replay \u06cc\u0627 Buffer \u0645\u0634\u062e\u0635\u06cc \u062a\u0646\u0638\u06cc\u0645 \u0634\u062f\u0647 \u0628\u0627\u0634\u0647. <code>StateFlow<\/code> \u062f\u0631 \u0645\u0642\u0627\u0628\u0644 \u0647\u0645\u06cc\u0634\u0647 \u0645\u0642\u062f\u0627\u0631 \u0641\u0639\u0644\u06cc \u0631\u0648 \u0646\u06af\u0647 \u0645\u06cc\u200c\u062f\u0627\u0631\u0647 \u0648 Collector \u062c\u062f\u06cc\u062f \u0628\u0644\u0627\u0641\u0627\u0635\u0644\u0647 \u0622\u062e\u0631\u06cc\u0646 State \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>ViewModel emits event\nActivity is stopped\nCollector is inactive\nEvent disappears\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">ViewModel emits event<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Activity <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> stopped<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Collector <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> inactive<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Event disappears<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u06cc\u06a9 \u0631\u0648\u06cc\u062f\u0627\u062f Analytics \u0634\u0627\u06cc\u062f \u0645\u0634\u06a9\u0644\u06cc \u0646\u0628\u0627\u0634\u0647. \u0627\u0645\u0627 \u0628\u0631\u0627\u06cc Navigation \u0628\u0639\u062f \u0627\u0632 \u067e\u0631\u062f\u0627\u062e\u062a \u06cc\u0627 \u0646\u0645\u0627\u06cc\u0634 \u062e\u0637\u0627\u06cc \u0645\u0647\u0645\u060c \u0627\u0632\u062f\u0633\u062a\u200c\u0631\u0641\u062a\u0646 \u0631\u0648\u06cc\u062f\u0627\u062f \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062c\u0631\u06cc\u0627\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648 \u062e\u0631\u0627\u0628 \u06a9\u0646\u0647. \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0627\u06cc\u0646 \u062a\u0646\u0638\u06cc\u0645 \u0647\u0645 \u0647\u0645\u0647 \u0645\u0634\u06a9\u0644\u0627\u062a \u0631\u0648 \u062d\u0644 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>MutableSharedFlow&lt;UiEvent>(\n    replay = 1\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">MutableSharedFlow<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">UiEvent<\/span><span style=\"color: #24292E\">&gt;(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    replay <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0686\u0648\u0646 Collector \u062c\u062f\u06cc\u062f \u0645\u0645\u06a9\u0646\u0647 Event \u0642\u0628\u0644\u06cc \u0631\u0648 \u062f\u0648\u0628\u0627\u0631\u0647 \u0645\u0635\u0631\u0641 \u06a9\u0646\u0647 \u0648 Navigation \u062a\u06a9\u0631\u0627\u0631\u06cc \u0627\u062a\u0641\u0627\u0642 \u0628\u06cc\u0641\u062a\u0647. \u0628\u0639\u062f \u0645\u062c\u0628\u0648\u0631 \u0645\u06cc\u0634\u06cc\u0645 Replay Cache \u0631\u0648 \u067e\u0627\u06a9 \u06a9\u0646\u06cc\u0645 \u06cc\u0627 Wrapper\u0647\u0627\u06cc \u067e\u06cc\u0686\u06cc\u062f\u0647 \u0628\u0633\u0627\u0632\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0642\u0627\u0639\u062f\u0647 \u0639\u0645\u0644\u06cc \u0645\u0627 \u0627\u06cc\u0646\u0647:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0686\u06cc\u0632\u06cc \u06a9\u0647 UI \u0628\u0627\u06cc\u062f \u062f\u0631 \u0647\u0631 \u0644\u062d\u0638\u0647 \u0628\u062f\u0627\u0646\u062f:<br>StateFlow<br><br>\u0627\u062a\u0641\u0627\u0642\u06cc \u06a9\u0647 \u0627\u0632 \u062f\u0633\u062a \u0631\u0641\u062a\u0646\u0634 \u0645\u0647\u0645 \u0646\u06cc\u0633\u062a:<br>SharedFlow<br><br>\u0639\u0645\u0644 \u06cc\u06a9\u200c\u0628\u0627\u0631\u0647\u200c\u0627\u06cc \u06a9\u0647 \u0628\u0627\u06cc\u062f \u062a\u0636\u0645\u06cc\u0646 \u0634\u0648\u062f:<br>State \u0645\u0635\u0631\u0641\u200c\u0634\u0648\u0646\u062f\u0647 \u06cc\u0627 Queue \u067e\u0627\u06cc\u062f\u0627\u0631<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u0647 \u0632\u0645\u0627\u0646\u06cc SharedFlow \u0645\u0646\u0627\u0633\u0628 \u0627\u0633\u062a\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SharedFlow \u0647\u0645\u0686\u0646\u0627\u0646 \u06a9\u0627\u0631\u0628\u0631\u062f\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc \u062f\u0627\u0631\u0647. \u0645\u062b\u0644\u0627\u064b \u06cc\u06a9 Event \u0633\u0631\u0627\u0633\u0631\u06cc \u0628\u0631\u0627\u06cc \u0627\u0637\u0644\u0627\u0639 \u062f\u0627\u062f\u0646 \u062a\u063a\u06cc\u06cc\u0631 Theme \u0628\u0647 \u0686\u0646\u062f \u0628\u062e\u0634 \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u0631\u062e\u062f\u0627\u062f\u0647\u0627\u06cc Telemetry\u060c Refresh \u0639\u0645\u0648\u0645\u06cc \u06cc\u0627 \u062a\u063a\u06cc\u06cc\u0631 \u0627\u062a\u0635\u0627\u0644 WebSocket \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0628\u0627 SharedFlow \u0645\u0646\u0627\u0633\u0628 \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0627\u0644:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class AppEventBus {\n\n    private val _events =\n        MutableSharedFlow&lt;AppEvent>(\n            extraBufferCapacity = 16\n        )\n\n    val events:\n        SharedFlow&lt;AppEvent> =\n        _events.asSharedFlow()\n\n    fun publish(\n        event: AppEvent\n    ) {\n        _events.tryEmit(event)\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AppEventBus<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> _events <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">MutableSharedFlow<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">AppEvent<\/span><span style=\"color: #24292E\">&gt;(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            extraBufferCapacity <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">16<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> events:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        SharedFlow<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">AppEvent<\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        _events.<\/span><span style=\"color: #6F42C1\">asSharedFlow<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">publish<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        event: <\/span><span style=\"color: #6F42C1\">AppEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        _events.<\/span><span style=\"color: #6F42C1\">tryEmit<\/span><span style=\"color: #24292E\">(event)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>sealed interface AppEvent {\n\n    data object SessionExpired :\n        AppEvent\n\n    data class ProductChanged(\n        val productId: Long\n    ) : AppEvent\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">sealed<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AppEvent<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">SessionExpired<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        AppEvent<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductChanged<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">AppEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 Event Bus \u0646\u0628\u0627\u06cc\u062f \u0628\u0647 \u0631\u0627\u0647 \u0641\u0631\u0627\u0631 \u0645\u0639\u0645\u0627\u0631\u06cc \u062a\u0628\u062f\u06cc\u0644 \u0628\u0634\u0647. \u0627\u06af\u0631 \u0647\u0631 Feature \u0628\u062f\u0648\u0646 \u0642\u0631\u0627\u0631\u062f\u0627\u062f \u0645\u0634\u062e\u0635 Event \u0639\u0645\u0648\u0645\u06cc \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u0647\u060c \u0628\u0639\u062f \u0627\u0632 \u0645\u062f\u062a\u06cc \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0646 \u0645\u0646\u0634\u0623 \u0631\u0641\u062a\u0627\u0631\u0647\u0627 \u0628\u0633\u06cc\u0627\u0631 \u0633\u062e\u062a \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>ProductRepository publishes event\nHomeViewModel receives event\nNotificationService receives event\nProfileScreen unexpectedly refreshes\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">ProductRepository publishes event<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">HomeViewModel receives event<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">NotificationService receives event<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">ProfileScreen unexpectedly refreshes<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u062c\u0627\u06cc \u0645\u0645\u06a9\u0646\u060c \u062f\u0627\u062f\u0647 \u067e\u0627\u06cc\u062f\u0627\u0631 \u0631\u0648 \u0627\u0632 Repository \u0628\u0647\u200c\u0635\u0648\u0631\u062a Flow \u0645\u0646\u062a\u0634\u0631 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. \u0645\u062b\u0644\u0627\u064b \u0627\u06af\u0631 \u0645\u062d\u0635\u0648\u0644 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f\u0647\u060c Room \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0645\u06cc\u0634\u0647 \u0648 \u062a\u0645\u0627\u0645 Observer\u0647\u0627 \u062f\u0627\u062f\u0647 \u062c\u062f\u06cc\u062f \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0646\u061b \u0646\u06cc\u0627\u0632\u06cc \u0646\u06cc\u0633\u062a Event \u062c\u062f\u0627\u06af\u0627\u0646\u0647 <code>ProductChanged<\/code> \u0628\u0647 \u0647\u0645\u0647 \u062c\u0627 \u0634\u0644\u06cc\u06a9 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0635\u0641\u062d\u0647 Stateless \u0648 Stateful<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647\u062a\u0631\u0647 Composable \u0627\u0635\u0644\u06cc \u0631\u0648 \u0628\u0647 \u062f\u0648 \u0628\u062e\u0634 \u062a\u0642\u0633\u06cc\u0645 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Route Composable\nScreen Composable\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Route Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Screen Composable<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Route \u0628\u0627 ViewModel\u060c Navigation \u0648 Lifecycle \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nfun TrackedProductsRoute(\n    viewModel:\n        TrackedProductsViewModel,\n    onNavigateToProduct:\n        (Long) -> Unit\n) {\n    val uiState by\n        viewModel.uiState\n            .collectAsStateWithLifecycle()\n\n    val snackbarHostState =\n        remember {\n            SnackbarHostState()\n        }\n\n    ObserveUserMessage(\n        message =\n            uiState.userMessage,\n\n        snackbarHostState =\n            snackbarHostState,\n\n        onMessageShown = {\n            viewModel.onEvent(\n                TrackedProductsEvent\n                    .UserMessageShown\n            )\n        }\n    )\n\n    ObserveNavigation(\n        target =\n            uiState.navigationTarget,\n\n        onNavigateToProduct =\n            onNavigateToProduct,\n\n        onNavigationHandled = {\n            viewModel.onEvent(\n                TrackedProductsEvent\n                    .NavigationHandled\n            )\n        }\n    )\n\n    TrackedProductsScreen(\n        state = uiState,\n        snackbarHostState =\n            snackbarHostState,\n        onEvent =\n            viewModel::onEvent\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductsRoute<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    viewModel:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsViewModel,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onNavigateToProduct:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        (Long) <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> uiState <\/span><span style=\"color: #D73A49\">by<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModel.uiState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">collectAsStateWithLifecycle<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> snackbarHostState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">remember<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">SnackbarHostState<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">ObserveUserMessage<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        message <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            uiState.userMessage,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        snackbarHostState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            snackbarHostState,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        onMessageShown <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            viewModel.<\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .UserMessageShown<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">ObserveNavigation<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        target <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            uiState.navigationTarget,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        onNavigateToProduct <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            onNavigateToProduct,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        onNavigationHandled <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            viewModel.<\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .NavigationHandled<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">TrackedProductsScreen<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        state <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> uiState,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        snackbarHostState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            snackbarHostState,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        onEvent <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            viewModel::<\/span><span style=\"color: #6F42C1\">onEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 <code>collectAsStateWithLifecycle<\/code> \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u062c\u0645\u0639\u200c\u0622\u0648\u0631\u06cc State \u0628\u0627 Lifecycle \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0647\u0645\u0627\u0647\u0646\u06af \u0628\u0627\u0634\u0647. \u0627\u0644\u06af\u0648\u06cc \u0631\u0633\u0645\u06cc Android \u0647\u0645 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647 UI State \u0628\u0647\u200c\u0634\u06a9\u0644 Lifecycle-aware \u0645\u0635\u0631\u0641 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Screen \u0641\u0642\u0637 State \u0648 Event Callback \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nfun TrackedProductsScreen(\n    state:\n        TrackedProductsUiState,\n\n    snackbarHostState:\n        SnackbarHostState,\n\n    onEvent:\n        (TrackedProductsEvent) -> Unit\n) {\n    Scaffold(\n        snackbarHost = {\n            SnackbarHost(\n                hostState =\n                    snackbarHostState\n            )\n        },\n\n        topBar = {\n            TrackedProductsTopBar(\n                selectedSort =\n                    state.selectedSort,\n\n                onSortChanged = {\n                    onEvent(\n                        TrackedProductsEvent\n                            .SortChanged(it)\n                    )\n                }\n            )\n        }\n    ) { paddingValues ->\n\n        TrackedProductsContent(\n            modifier =\n                Modifier.padding(\n                    paddingValues\n                ),\n\n            state = state,\n\n            onSearchQueryChanged = {\n                onEvent(\n                    TrackedProductsEvent\n                        .SearchQueryChanged(\n                            it\n                        )\n                )\n            },\n\n            onRefreshClicked = {\n                onEvent(\n                    TrackedProductsEvent\n                        .RefreshClicked\n                )\n            },\n\n            onRetryClicked = {\n                onEvent(\n                    TrackedProductsEvent\n                        .RetryClicked\n                )\n            },\n\n            onProductClicked = {\n                onEvent(\n                    TrackedProductsEvent\n                        .ProductClicked(it)\n                )\n            },\n\n            onDeleteClicked = {\n                onEvent(\n                    TrackedProductsEvent\n                        .DeleteProductClicked(\n                            it\n                        )\n                )\n            }\n        )\n    }\n\n    state.productPendingDeletion\n        ?.let { product ->\n\n            DeleteProductDialog(\n                productTitle =\n                    product.title,\n\n                onConfirm = {\n                    onEvent(\n                        TrackedProductsEvent\n                            .DeleteDialogConfirmed\n                    )\n                },\n\n                onDismiss = {\n                    onEvent(\n                        TrackedProductsEvent\n                            .DeleteDialogDismissed\n                    )\n                }\n            )\n        }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductsScreen<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    state:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsUiState,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    snackbarHostState:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        SnackbarHostState,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onEvent:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        (TrackedProductsEvent) <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">Scaffold<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        snackbarHost <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">SnackbarHost<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                hostState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    snackbarHostState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        topBar <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">TrackedProductsTopBar<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                selectedSort <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    state.selectedSort,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                onSortChanged <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            .<\/span><span style=\"color: #6F42C1\">SortChanged<\/span><span style=\"color: #24292E\">(it)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) { paddingValues <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">TrackedProductsContent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            modifier <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Modifier.<\/span><span style=\"color: #6F42C1\">padding<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    paddingValues<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                ),<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> state,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            onSearchQueryChanged <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">SearchQueryChanged<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            it<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            onRefreshClicked <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .RefreshClicked<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            onRetryClicked <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .RetryClicked<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            onProductClicked <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">ProductClicked<\/span><span style=\"color: #24292E\">(it)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            onDeleteClicked <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">DeleteProductClicked<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            it<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    state.productPendingDeletion<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ?.<\/span><span style=\"color: #6F42C1\">let<\/span><span style=\"color: #24292E\"> { product <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">DeleteProductDialog<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                productTitle <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    product.title,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                onConfirm <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            .DeleteDialogConfirmed<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                },<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                onDismiss <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            .DeleteDialogDismissed<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 <code>TrackedProductsScreen<\/code> \u0647\u06cc\u0686 \u0627\u0637\u0644\u0627\u0639\u06cc \u0627\u0632 ViewModel\u060c Repository \u06cc\u0627 NavController \u0646\u062f\u0627\u0631\u0647. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 Preview \u0648 \u062a\u0633\u062a \u06a9\u0631\u062f\u0646 \u0627\u0648\u0646 \u0633\u0627\u062f\u0647\u200c\u0633\u062a.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Render \u06a9\u0631\u062f\u0646 \u0648\u0636\u0639\u06cc\u062a\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062d\u062a\u0648\u0627\u06cc \u0635\u0641\u062d\u0647 \u0641\u0642\u0637 \u0628\u0631\u0627\u0633\u0627\u0633 State \u062a\u0635\u0645\u06cc\u0645 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nprivate fun TrackedProductsContent(\n    modifier: Modifier = Modifier,\n    state:\n        TrackedProductsUiState,\n    onSearchQueryChanged:\n        (String) -> Unit,\n    onRefreshClicked:\n        () -> Unit,\n    onRetryClicked:\n        () -> Unit,\n    onProductClicked:\n        (Long) -> Unit,\n    onDeleteClicked:\n        (Long) -> Unit\n) {\n    Column(\n        modifier = modifier\n            .fillMaxSize()\n    ) {\n        ProductSearchField(\n            query =\n                state.searchQuery,\n\n            onQueryChanged =\n                onSearchQueryChanged\n        )\n\n        if (state.isOffline) {\n            OfflineBanner(\n                onRetryClicked =\n                    onRetryClicked\n            )\n        }\n\n        when {\n            state.isInitialLoading -> {\n                InitialLoadingContent()\n            }\n\n            state.showEmptyState -> {\n                EmptyTrackedProductsContent()\n            }\n\n            state.showNoSearchResult -> {\n                NoSearchResultContent(\n                    query =\n                        state.searchQuery\n                )\n            }\n\n            else -> {\n                TrackedProductList(\n                    products =\n                        state.products,\n\n                    isRefreshing =\n                        state.isRefreshing,\n\n                    deletingProductId =\n                        state\n                            .deletingProductId,\n\n                    onRefreshClicked =\n                        onRefreshClicked,\n\n                    onProductClicked =\n                        onProductClicked,\n\n                    onDeleteClicked =\n                        onDeleteClicked\n                )\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductsContent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    modifier: <\/span><span style=\"color: #6F42C1\">Modifier<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> Modifier,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    state:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsUiState,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onSearchQueryChanged:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        (String) <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onRefreshClicked:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        () <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onRetryClicked:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        () <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onProductClicked:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        (Long) <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onDeleteClicked:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        (Long) <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">Column<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        modifier <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> modifier<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">fillMaxSize<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">ProductSearchField<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            query <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                state.searchQuery,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            onQueryChanged <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                onSearchQueryChanged<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (state.isOffline) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">OfflineBanner<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                onRetryClicked <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    onRetryClicked<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state.isInitialLoading <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">InitialLoadingContent<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state.showEmptyState <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">EmptyTrackedProductsContent<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state.showNoSearchResult <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">NoSearchResultContent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    query <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        state.searchQuery<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #6F42C1\">TrackedProductList<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        state.products,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    isRefreshing <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        state.isRefreshing,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    deletingProductId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        state<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            .deletingProductId,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    onRefreshClicked <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        onRefreshClicked,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    onProductClicked <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        onProductClicked,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    onDeleteClicked <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        onDeleteClicked<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u06cc\u0686 \u0645\u062a\u063a\u06cc\u0631 \u0645\u0633\u062a\u0642\u0644\u06cc \u062f\u0627\u062e\u0644 Composable \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u0647 \u06a9\u0647 \u0628\u0627 State \u0627\u0635\u0644\u06cc \u0646\u0627\u0633\u0627\u0632\u06af\u0627\u0631 \u0628\u0634\u0647. \u062a\u0645\u0627\u0645 \u062a\u0635\u0645\u06cc\u0645\u200c\u0647\u0627\u06cc \u0635\u0641\u062d\u0647 \u0627\u0632 \u06cc\u06a9 Snapshot \u0648\u0627\u062d\u062f \u06af\u0631\u0641\u062a\u0647 \u0645\u06cc\u0634\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">State \u0645\u062d\u0644\u06cc UI \u0631\u0648 \u0628\u06cc\u200c\u062f\u0644\u06cc\u0644 \u0628\u0647 ViewModel \u0645\u0646\u062a\u0642\u0644 \u0646\u06a9\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Event-Driven UI \u0628\u0647 \u0627\u06cc\u0646 \u0645\u0639\u0646\u06cc \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0647\u0631 \u0648\u0636\u0639\u06cc\u062a \u06a9\u0648\u0686\u06cc\u06a9\u06cc \u0628\u0627\u06cc\u062f \u062f\u0627\u062e\u0644 ViewModel \u0642\u0631\u0627\u0631 \u0628\u06af\u06cc\u0631\u0647. \u0645\u062b\u0644\u0627\u064b \u0628\u0627\u0632 \u0648 \u0628\u0633\u062a\u0647 \u0628\u0648\u062f\u0646 \u06cc\u06a9 \u0628\u062e\u0634 \u062a\u0648\u0636\u06cc\u062d\u0627\u062a \u06cc\u0627 \u0648\u0636\u0639\u06cc\u062a Focus \u06cc\u06a9 TextField \u0645\u0645\u06a9\u0646\u0647 \u0641\u0642\u0637 \u0628\u0647 \u0647\u0645\u0648\u0646 Composable \u0645\u0631\u0628\u0648\u0637 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Composable\nfun ProductDescription(\n    description: String\n) {\n    var expanded by rememberSaveable {\n        mutableStateOf(false)\n    }\n\n    Column {\n        Text(\n            text = description,\n            maxLines =\n                if (expanded) {\n                    Int.MAX_VALUE\n                } else {\n                    3\n                }\n        )\n\n        TextButton(\n            onClick = {\n                expanded = !expanded\n            }\n        ) {\n            Text(\n                if (expanded) {\n                    \"\u0646\u0645\u0627\u06cc\u0634 \u06a9\u0645\u062a\u0631\"\n                } else {\n                    \"\u0646\u0645\u0627\u06cc\u0634 \u0628\u06cc\u0634\u062a\u0631\"\n                }\n            )\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Composable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductDescription<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    description: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> expanded <\/span><span style=\"color: #D73A49\">by<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">rememberSaveable<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">mutableStateOf<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">Column<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">Text<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            text <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> description,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            maxLines <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (expanded) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    Int.MAX_VALUE<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #005CC5\">3<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">TextButton<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            onClick <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                expanded <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">!<\/span><span style=\"color: #24292E\">expanded<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">Text<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (expanded) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;\u0646\u0645\u0627\u06cc\u0634 \u06a9\u0645\u062a\u0631&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                } <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;\u0646\u0645\u0627\u06cc\u0634 \u0628\u06cc\u0634\u062a\u0631&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 Event \u0641\u0642\u0637 \u0631\u0641\u062a\u0627\u0631 \u06cc\u06a9 \u0639\u0646\u0635\u0631 UI \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u062f\u0647 \u0648 Business Logic \u0646\u062f\u0627\u0631\u0647\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u062e\u0648\u062f UI \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0627\u0648\u0646 \u0631\u0648 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u0647. Android \u0647\u0645 \u0628\u06cc\u0646 Business Logic \u0648 UI Behavior Logic \u062a\u0641\u0627\u0648\u062a \u0645\u06cc\u200c\u0630\u0627\u0631\u0647: \u0627\u062a\u0641\u0627\u0642\u06cc \u0645\u062b\u0644 Refresh \u0628\u0627\u06cc\u062f \u0628\u0647 ViewModel \u0628\u0631\u0647\u060c \u0627\u0645\u0627 \u0628\u0627\u0632 \u0648 \u0628\u0633\u062a\u0647 \u0634\u062f\u0646 \u06cc\u06a9 \u0639\u0646\u0635\u0631 \u0646\u0645\u0627\u06cc\u0634\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u062f\u0631 UI \u0645\u062f\u06cc\u0631\u06cc\u062a \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0642\u0627\u0639\u062f\u0647 \u0639\u0645\u0644\u06cc: <br>\u0627\u06af\u0631 State \u0631\u0648\u06cc \u0645\u0646\u0637\u0642 \u06a9\u0633\u0628\u200c\u0648\u06a9\u0627\u0631\u060c \u0686\u0646\u062f \u0635\u0641\u062d\u0647 \u06cc\u0627 \u0628\u0627\u0632\u06cc\u0627\u0628\u06cc \u062f\u0627\u062f\u0647 \u0627\u062b\u0631 \u062f\u0627\u0631\u062f:<br>ViewModel<br><br>\u0627\u06af\u0631 State \u0641\u0642\u0637 \u0634\u06a9\u0644 \u0645\u0648\u0642\u062a \u06cc\u06a9 \u0639\u0646\u0635\u0631 \u0631\u0627 \u06a9\u0646\u062a\u0631\u0644 \u0645\u06cc\u200c\u06a9\u0646\u062f:<br>Composable<br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Event\u0647\u0627\u06cc \u062e\u0627\u0631\u062c\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 Event\u0647\u0627 \u0627\u0632 \u0644\u0645\u0633 \u06a9\u0627\u0631\u0628\u0631 \u0627\u06cc\u062c\u0627\u062f \u0646\u0645\u06cc\u0634\u0646. \u062a\u063a\u06cc\u06cc\u0631 \u062f\u0627\u062f\u0647 \u062f\u0631 Room\u060c \u062f\u0631\u06cc\u0627\u0641\u062a Push\u060c \u0628\u0631\u06af\u0634\u062a \u0627\u062a\u0635\u0627\u0644 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0648 \u0645\u0646\u0642\u0636\u06cc \u0634\u062f\u0646 Session \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0646\u0646 \u0645\u0646\u0628\u0639 \u062a\u063a\u06cc\u06cc\u0631 State \u0628\u0627\u0634\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 Connection Observer \u0627\u06cc\u0646 Flow \u0631\u0648 \u0645\u0646\u062a\u0634\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface ConnectivityObserver {\n\n    val status:\n        Flow&lt;ConnectivityStatus>\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ConnectivityObserver<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> status:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Flow<\/span><span style=\"color: #D73A49\">&lt;<\/span><span style=\"color: #24292E\">ConnectivityStatus<\/span><span style=\"color: #D73A49\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">ViewModel \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u0627\u0648\u0646 \u0631\u0648 \u0628\u0647 UI State \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun observeConnectivity() {\n    viewModelScope.launch {\n        connectivityObserver\n            .status\n            .collectLatest { status ->\n                internalState.update {\n                    it.copy(\n                        isOffline =\n                            status ==\n                                ConnectivityStatus\n                                    .Unavailable\n                    )\n                }\n            }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">observeConnectivity<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    viewModelScope.<\/span><span style=\"color: #6F42C1\">launch<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        connectivityObserver<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .status<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            .<\/span><span style=\"color: #6F42C1\">collectLatest<\/span><span style=\"color: #24292E\"> { status <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        isOffline <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            status <\/span><span style=\"color: #D73A49\">==<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                ConnectivityStatus<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                    .Unavailable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627 Session Repository \u0627\u0639\u0644\u0627\u0645 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0627\u0632 \u062d\u0633\u0627\u0628 \u062e\u0627\u0631\u062c \u0634\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>authRepository\n    .sessionState\n    .collectLatest { session ->\n        when (session) {\n            SessionState.Expired -> {\n                internalState.update {\n                    it.copy(\n                        navigationTarget =\n                            TrackedProductsNavigation\n                                .Login\n                    )\n                }\n            }\n\n            else -> Unit\n        }\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">authRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    .sessionState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    .<\/span><span style=\"color: #6F42C1\">collectLatest<\/span><span style=\"color: #24292E\"> { session <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (session) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            SessionState.Expired <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                internalState.<\/span><span style=\"color: #6F42C1\">update<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    it.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        navigationTarget <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            TrackedProductsNavigation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                                .Login<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> Unit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0647\u0645\u0647 \u0627\u06cc\u0646 \u062d\u0627\u0644\u062a\u200c\u0647\u0627\u060c \u0645\u0646\u0628\u0639 Event \u0645\u062a\u0641\u0627\u0648\u062a\u0647 \u0627\u0645\u0627 \u0646\u062a\u06cc\u062c\u0647 \u0647\u0645\u0686\u0646\u0627\u0646 \u062a\u0648\u0644\u06cc\u062f State \u062c\u062f\u06cc\u062f\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Reducer\u061b \u0648\u0642\u062a\u06cc State \u067e\u06cc\u0686\u06cc\u062f\u0647\u200c\u062a\u0631 \u0645\u06cc\u0634\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0635\u0641\u062d\u0647\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af \u0645\u0645\u06a9\u0646\u0647 \u062f\u0647\u200c\u0647\u0627 Event \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u0628\u0631\u0627\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u0633\u062a\u0642\u06cc\u0645 State \u062f\u0631 \u0646\u0642\u0627\u0637 \u0645\u062e\u062a\u0644\u0641\u060c \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u06cc\u06a9 Reducer \u0628\u0633\u0627\u0632\u06cc\u0645. Reducer State \u0641\u0639\u0644\u06cc \u0648 Result \u062a\u0627\u0632\u0647 \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 State \u0628\u0639\u062f\u06cc \u0631\u0648 \u0645\u06cc\u200c\u0633\u0627\u0632\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>sealed interface TrackedProductsResult {\n\n    data object RefreshStarted :\n        TrackedProductsResult\n\n    data object RefreshSucceeded :\n        TrackedProductsResult\n\n    data class RefreshFailed(\n        val message: UiMessage,\n        val isOffline: Boolean\n    ) : TrackedProductsResult\n\n    data class DeleteStarted(\n        val productId: Long\n    ) : TrackedProductsResult\n\n    data class DeleteSucceeded(\n        val productId: Long\n    ) : TrackedProductsResult\n\n    data class DeleteFailed(\n        val message: UiMessage\n    ) : TrackedProductsResult\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">sealed<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductsResult<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">RefreshStarted<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">RefreshSucceeded<\/span><span style=\"color: #24292E\"> :<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">RefreshFailed<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> message: <\/span><span style=\"color: #6F42C1\">UiMessage<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> isOffline: <\/span><span style=\"color: #6F42C1\">Boolean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DeleteStarted<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DeleteSucceeded<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> productId: <\/span><span style=\"color: #6F42C1\">Long<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DeleteFailed<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> message: <\/span><span style=\"color: #6F42C1\">UiMessage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) : <\/span><span style=\"color: #6F42C1\">TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Reducer:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class TrackedProductsReducer {\n\n    fun reduce(\n        current:\n            TrackedProductsUiState,\n\n        result:\n            TrackedProductsResult\n    ): TrackedProductsUiState {\n\n        return when (result) {\n            TrackedProductsResult\n                .RefreshStarted -> {\n\n                current.copy(\n                    isRefreshing = true,\n                    userMessage = null\n                )\n            }\n\n            TrackedProductsResult\n                .RefreshSucceeded -> {\n\n                current.copy(\n                    isRefreshing = false,\n                    isOffline = false\n                )\n            }\n\n            is TrackedProductsResult\n                .RefreshFailed -> {\n\n                current.copy(\n                    isRefreshing = false,\n                    isOffline =\n                        result.isOffline,\n                    userMessage =\n                        result.message\n                )\n            }\n\n            is TrackedProductsResult\n                .DeleteStarted -> {\n\n                current.copy(\n                    deletingProductId =\n                        result.productId\n                )\n            }\n\n            is TrackedProductsResult\n                .DeleteSucceeded -> {\n\n                current.copy(\n                    deletingProductId =\n                        null,\n                    userMessage =\n                        UiMessage.Text(\n                            \"\u0645\u062d\u0635\u0648\u0644 \u062d\u0630\u0641 \u0634\u062f.\"\n                        )\n                )\n            }\n\n            is TrackedProductsResult\n                .DeleteFailed -> {\n\n                current.copy(\n                    deletingProductId =\n                        null,\n                    userMessage =\n                        result.message\n                )\n            }\n        }\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TrackedProductsReducer<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">reduce<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        current:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsUiState,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        result:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ): <\/span><span style=\"color: #6F42C1\">TrackedProductsUiState<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (result) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .RefreshStarted <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                current.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    isRefreshing <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    userMessage <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .RefreshSucceeded <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                current.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    isRefreshing <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    isOffline <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .RefreshFailed <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                current.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    isRefreshing <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">false<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    isOffline <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        result.isOffline,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    userMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        result.message<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .DeleteStarted <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                current.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    deletingProductId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        result.productId<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .DeleteSucceeded <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                current.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    deletingProductId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    userMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        UiMessage.<\/span><span style=\"color: #6F42C1\">Text<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                            <\/span><span style=\"color: #032F62\">&quot;\u0645\u062d\u0635\u0648\u0644 \u062d\u0630\u0641 \u0634\u062f.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsResult<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .DeleteFailed <\/span><span style=\"color: #D73A49\">-&gt;<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                current.<\/span><span style=\"color: #6F42C1\">copy<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    deletingProductId <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    userMessage <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        result.message<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0645\u062f\u0644 \u0634\u0628\u06cc\u0647 \u0645\u0639\u0645\u0627\u0631\u06cc MVI \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">Intent\/Event<br>\u2193<br>Processor<br>\u2193<br>Result<br>\u2193<br>Reducer<br>\u2193<br>State<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Reducer \u0628\u0627\u06cc\u062f Pure Function \u0628\u0627\u0634\u0647\u061b \u06cc\u0639\u0646\u06cc Network\u060c Database \u06cc\u0627 Logging \u0627\u0646\u062c\u0627\u0645 \u0646\u062f\u0647. \u0641\u0642\u0637 State \u0641\u0639\u0644\u06cc \u0648 Result \u0631\u0648 \u0628\u0647 State \u062c\u062f\u06cc\u062f \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0646\u0647. \u0627\u06cc\u0646 \u0648\u06cc\u0698\u06af\u06cc \u062a\u0633\u062a \u06a9\u0631\u062f\u0646 \u0631\u0648 \u0628\u0633\u06cc\u0627\u0631 \u0633\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0647\u0645\u0647 \u0635\u0641\u062d\u0647\u200c\u0647\u0627 \u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 Reducer \u0645\u0633\u062a\u0642\u0644 \u0646\u062f\u0627\u0631\u06cc\u0645. \u0635\u0641\u062d\u0647 \u06a9\u0648\u0686\u06a9 \u0628\u0627 <code>MutableStateFlow.update<\/code> \u062e\u0648\u0627\u0646\u0627\u062a\u0631 \u0645\u06cc\u200c\u0645\u0648\u0646\u0647. Reducer \u0632\u0645\u0627\u0646\u06cc \u0627\u0631\u0632\u0634 \u062f\u0627\u0631\u0647 \u06a9\u0647 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a State \u0632\u06cc\u0627\u062f\u060c \u0648\u0627\u0628\u0633\u062a\u0647 \u0648 \u067e\u06cc\u0686\u06cc\u062f\u0647 \u0634\u062f\u0647 \u0628\u0627\u0634\u0646.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u067e\u0631\u062f\u0627\u0632\u0634 Event \u062a\u06a9\u0631\u0627\u0631\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06af\u0627\u0647\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0686\u0646\u062f \u0628\u0627\u0631 \u0633\u0631\u06cc\u0639 \u0631\u0648\u06cc \u062f\u06a9\u0645\u0647 \u062d\u0630\u0641 \u06cc\u0627 Refresh \u0645\u06cc\u200c\u0632\u0646\u0647. \u0628\u062e\u0634\u06cc \u0627\u0632 \u06a9\u0646\u062a\u0631\u0644 \u062f\u0631 UI \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Button(\n    enabled =\n        !state.isRefreshing,\n\n    onClick = onRefreshClicked\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">Button<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    enabled <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">!<\/span><span style=\"color: #24292E\">state.isRefreshing,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    onClick <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> onRefreshClicked<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 ViewModel \u0647\u0645 \u0628\u0627\u06cc\u062f \u0627\u0632 \u062e\u0648\u062f\u0634 \u0645\u062d\u0627\u0641\u0638\u062a \u06a9\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>if (\n    internalState.value\n        .isRefreshing\n) {\n    return\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    internalState.<\/span><span style=\"color: #D73A49\">value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .isRefreshing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">UI \u0642\u0627\u0628\u0644\u200c\u0627\u0639\u062a\u0645\u0627\u062f \u06a9\u0627\u0645\u0644 \u0646\u06cc\u0633\u062a\u061b Event \u0645\u0645\u06a9\u0646\u0647 \u0627\u0632 \u062a\u0633\u062a\u060c Accessibility\u060c \u0686\u0646\u062f Composable \u06cc\u0627 \u0645\u0633\u06cc\u0631 \u062f\u06cc\u06af\u0631\u06cc \u0648\u0627\u0631\u062f \u0628\u0634\u0647. \u0642\u0627\u0646\u0648\u0646 \u06a9\u0633\u0628\u200c\u0648\u06a9\u0627\u0631 \u0628\u0627\u06cc\u062f \u062f\u0631 ViewModel \u06cc\u0627 Use Case \u0647\u0645 \u06a9\u0646\u062a\u0631\u0644 \u0628\u0634\u0647. \u0628\u0631\u0627\u06cc Event\u0647\u0627\u06cc \u0645\u062a\u0646\u06cc \u0645\u062b\u0644 \u062c\u0633\u062a\u200c\u0648\u062c\u0648 \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u0648\u0631\u0648\u062f\u06cc \u0631\u0648 \u0628\u0647 Flow \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private val events =\n    MutableSharedFlow&lt;\n        TrackedProductsEvent\n    >(\n        extraBufferCapacity = 64\n    )\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> events <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    MutableSharedFlow<\/span><span style=\"color: #D73A49\">&lt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        extraBufferCapacity <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">64<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u0641\u0642\u0637 Search Event\u0647\u0627 \u0631\u0648 Debounce \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun observeSearchEvents() {\n    events\n        .filterIsInstance&lt;\n            TrackedProductsEvent\n                .SearchQueryChanged\n        >()\n        .map { it.query }\n        .debounce(400)\n        .distinctUntilChanged()\n        .onEach { query ->\n            savedStateHandle&#91;\n                SEARCH_QUERY_KEY\n            &#93; = query\n        }\n        .launchIn(viewModelScope)\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">observeSearchEvents<\/span><span style=\"color: #24292E\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    events<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .filterIsInstance<\/span><span style=\"color: #D73A49\">&lt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .SearchQueryChanged<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">&gt;<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">map<\/span><span style=\"color: #24292E\"> { it.query }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">debounce<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">400<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">distinctUntilChanged<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">onEach<\/span><span style=\"color: #24292E\"> { query <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            savedStateHandle&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                SEARCH_QUERY_KEY<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            &#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> query<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">launchIn<\/span><span style=\"color: #24292E\">(viewModelScope)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0628\u0631\u0627\u06cc TextField \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0628\u0647\u062a\u0631\u0647 \u0645\u0642\u062f\u0627\u0631 \u0646\u0645\u0627\u06cc\u0634\u200c\u062f\u0627\u062f\u0647\u200c\u0634\u062f\u0647 \u0641\u0648\u0631\u0627\u064b \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647 \u0648 \u0641\u0642\u0637 \u062f\u0631\u062e\u0648\u0627\u0633\u062a Network \u0628\u0627 Debounce \u0627\u062c\u0631\u0627 \u0628\u0634\u0647. \u0648\u06af\u0631\u0646\u0647 \u062a\u0627\u06cc\u067e \u06a9\u0627\u0631\u0628\u0631 \u0628\u0627 \u062a\u0623\u062e\u06cc\u0631 \u0631\u0648\u06cc \u0635\u0641\u062d\u0647 \u062f\u06cc\u062f\u0647 \u0645\u06cc\u0634\u0647. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u062f\u0648 State \u062f\u0627\u0631\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Raw query for UI\nDebounced query for API\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Raw query <\/span><span style=\"color: #D73A49\">for<\/span><span style=\"color: #24292E\"> UI<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Debounced query <\/span><span style=\"color: #D73A49\">for<\/span><span style=\"color: #24292E\"> API<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0627\u0644:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private val searchQuery =\n    MutableStateFlow(\"\")\n\nprivate val debouncedQuery =\n    searchQuery\n        .debounce(400)\n        .distinctUntilChanged()\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> searchQuery <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">MutableStateFlow<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> debouncedQuery <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    searchQuery<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">debounce<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">400<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        .<\/span><span style=\"color: #6F42C1\">distinctUntilChanged<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Event \u0628\u0644\u0627\u0641\u0627\u0635\u0644\u0647 \u0645\u0642\u062f\u0627\u0631 UI \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun updateSearchQuery(\n    query: String\n) {\n    searchQuery.value = query\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">updateSearchQuery<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    query: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    searchQuery.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> query<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 API \u0641\u0642\u0637 \u0627\u0632 <code>debouncedQuery<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u062a\u0633\u062a Event-Driven ViewModel<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u0645\u0632\u06cc\u062a\u200c\u0647\u0627\u06cc \u0627\u06cc\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc\u060c \u062a\u0633\u062a\u200c\u067e\u0630\u06cc\u0631\u06cc\u0647. \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 Event \u0628\u0641\u0631\u0633\u062a\u06cc\u0645 \u0648 State \u062e\u0631\u0648\u062c\u06cc \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645. \u0645\u062b\u0627\u0644 \u062a\u0633\u062a Refresh \u0645\u0648\u0641\u0642:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Test\nfun refreshClicked_setsLoading_thenSuccess() =\n    runTest {\n\n        val repository =\n            FakeTrackedProductsRepository()\n\n        val viewModel =\n            createViewModel(\n                repository =\n                    repository\n            )\n\n        viewModel.onEvent(\n            TrackedProductsEvent\n                .RefreshClicked\n        )\n\n        advanceUntilIdle()\n\n        val state =\n            viewModel.uiState.value\n\n        assertFalse(\n            state.isRefreshing\n        )\n\n        assertFalse(\n            state.isOffline\n        )\n\n        assertNotNull(\n            state.userMessage\n        )\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">refreshClicked_setsLoading_thenSuccess<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">runTest<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> repository <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">FakeTrackedProductsRepository<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> viewModel <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">createViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                repository <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    repository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModel.<\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .RefreshClicked<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">advanceUntilIdle<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> state <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            viewModel.uiState.<\/span><span style=\"color: #D73A49\">value<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">assertFalse<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state.isRefreshing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">assertFalse<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state.isOffline<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">assertNotNull<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            state.userMessage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0633\u062a \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 Refresh \u062a\u06a9\u0631\u0627\u0631\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Test\nfun repeatedRefresh_doesNotStartSecondRequest() =\n    runTest {\n\n        val repository =\n            FakeTrackedProductsRepository(\n                delayMillis = 1_000\n            )\n\n        val viewModel =\n            createViewModel(\n                repository\n            )\n\n        viewModel.onEvent(\n            TrackedProductsEvent\n                .RefreshClicked\n        )\n\n        viewModel.onEvent(\n            TrackedProductsEvent\n                .RefreshClicked\n        )\n\n        advanceUntilIdle()\n\n        assertEquals(\n            expected = 1,\n            actual =\n                repository.refreshCallCount\n        )\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">repeatedRefresh_doesNotStartSecondRequest<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">runTest<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> repository <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">FakeTrackedProductsRepository<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                delayMillis <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1_000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> viewModel <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">createViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                repository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModel.<\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .RefreshClicked<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModel.<\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .RefreshClicked<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">advanceUntilIdle<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">assertEquals<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            expected <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            actual <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                repository.refreshCallCount<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0633\u062a Navigation:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Test\nfun productClicked_setsNavigationTarget() =\n    runTest {\n\n        val viewModel =\n            createViewModel()\n\n        viewModel.onEvent(\n            TrackedProductsEvent\n                .ProductClicked(\n                    productId = 42\n                )\n        )\n\n        assertEquals(\n            TrackedProductsNavigation\n                .ProductDetails(42),\n\n            viewModel\n                .uiState\n                .value\n                .navigationTarget\n        )\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">productClicked_setsNavigationTarget<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">runTest<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> viewModel <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">createViewModel<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModel.<\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">ProductClicked<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    productId <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">42<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">assertEquals<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsNavigation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">ProductDetails<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">42<\/span><span style=\"color: #24292E\">),<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            viewModel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .uiState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #D73A49\">value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .navigationTarget<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0633\u062a \u0645\u0635\u0631\u0641 Navigation:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@Test\nfun navigationHandled_clearsTarget() =\n    runTest {\n\n        val viewModel =\n            createViewModel()\n\n        viewModel.onEvent(\n            TrackedProductsEvent\n                .ProductClicked(42)\n        )\n\n        viewModel.onEvent(\n            TrackedProductsEvent\n                .NavigationHandled\n        )\n\n        assertNull(\n            viewModel\n                .uiState\n                .value\n                .navigationTarget\n        )\n    }\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">@Test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">navigationHandled_clearsTarget<\/span><span style=\"color: #24292E\">() <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">runTest<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> viewModel <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">createViewModel<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModel.<\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #6F42C1\">ProductClicked<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">42<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        viewModel.<\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .NavigationHandled<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6F42C1\">assertNull<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            viewModel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .uiState<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .<\/span><span style=\"color: #D73A49\">value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                .navigationTarget<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0686\u0648\u0646 UI \u0641\u0642\u0637 State \u0648 Event Handler \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u062a\u0633\u062a Screenshot \u0648 Compose \u0647\u0645 \u0633\u0627\u062f\u0647\u200c\u062a\u0631 \u0645\u06cc\u0634\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>composeTestRule.setContent {\n    TrackedProductsScreen(\n        state =\n            TrackedProductsUiState(\n                products =\n                    sampleProducts\n            ),\n\n        snackbarHostState =\n            SnackbarHostState(),\n\n        onEvent = {}\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">composeTestRule.<\/span><span style=\"color: #6F42C1\">setContent<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">TrackedProductsScreen<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        state <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">TrackedProductsUiState<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                products <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    sampleProducts<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            ),<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        snackbarHostState <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">SnackbarHostState<\/span><span style=\"color: #24292E\">(),<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        onEvent <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> {}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Logging \u0631\u0648\u06cc\u062f\u0627\u062f\u0647\u0627<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0632\u0645\u0627\u0646 \u062a\u0648\u0633\u0639\u0647 \u0645\u06cc\u200c\u062a\u0648\u0646\u06cc\u0645 \u062a\u0645\u0627\u0645 Event\u0647\u0627 \u0631\u0648 \u062b\u0628\u062a \u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun onEvent(\n    event: TrackedProductsEvent\n) {\n    if (BuildConfig.DEBUG) {\n        Log.d(\n            \"TrackedProducts\",\n            \"Event: $event\"\n        )\n    }\n\n    when (event) {\n        \/\/ handlers\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">onEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    event: <\/span><span style=\"color: #6F42C1\">TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (BuildConfig.DEBUG) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;TrackedProducts&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;Event: <\/span><span style=\"color: #005CC5\">$event<\/span><span style=\"color: #032F62\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (event) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #6A737D\">\/\/ handlers<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc Production \u0646\u0628\u0627\u06cc\u062f Event\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u062f\u0627\u0631\u0646 \u06a9\u0627\u0645\u0644 Log \u0628\u0634\u0646. \u0645\u062b\u0644\u0627\u064b Query \u062c\u0633\u062a\u200c\u0648\u062c\u0648 \u06cc\u0627 URL \u062e\u0635\u0648\u0635\u06cc \u0645\u062d\u0635\u0648\u0644 \u0645\u0645\u06a9\u0646\u0647 \u062f\u0627\u062f\u0647 \u0634\u062e\u0635\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0645\u062d\u0633\u0648\u0628 \u0628\u0634\u0647. \u0628\u0647\u062a\u0631\u0647 \u0641\u0642\u0637 \u0646\u0648\u0639 Event \u0648 \u0634\u0646\u0627\u0633\u0647\u200c\u0647\u0627\u06cc \u063a\u06cc\u0631\u062d\u0633\u0627\u0633 \u062b\u0628\u062a \u0628\u0634\u0646. \u06cc\u06a9 Event Logger \u062c\u062f\u0627:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface UiEventLogger {\n\n    fun log(\n        screen: String,\n        eventName: String\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">UiEventLogger<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">log<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        screen: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        eventName: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0633\u062a\u0641\u0627\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private fun logEvent(\n    event: TrackedProductsEvent\n) {\n    uiEventLogger.log(\n        screen =\n            \"tracked_products\",\n\n        eventName =\n            when (event) {\n                TrackedProductsEvent\n                    .RefreshClicked ->\n                    \"refresh_clicked\"\n\n                is TrackedProductsEvent\n                    .ProductClicked ->\n                    \"product_clicked\"\n\n                is TrackedProductsEvent\n                    .DeleteProductClicked ->\n                    \"delete_clicked\"\n\n                else ->\n                    event::class\n                        .simpleName\n                        .orEmpty()\n            }\n    )\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">logEvent<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    event: <\/span><span style=\"color: #6F42C1\">TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    uiEventLogger.<\/span><span style=\"color: #6F42C1\">log<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        screen <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #032F62\">&quot;tracked_products&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        eventName <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">when<\/span><span style=\"color: #24292E\"> (event) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .RefreshClicked <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;refresh_clicked&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .ProductClicked <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;product_clicked&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">is<\/span><span style=\"color: #24292E\"> TrackedProductsEvent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    .DeleteProductClicked <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    <\/span><span style=\"color: #032F62\">&quot;delete_clicked&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                    event::<\/span><span style=\"color: #6F42C1\">class<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .simpleName<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                        .<\/span><span style=\"color: #6F42C1\">orEmpty<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Event-Driven UI \u0645\u0634\u0627\u0647\u062f\u0647 \u0631\u0641\u062a\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0648 Debug \u06a9\u0631\u062f\u0646 \u062c\u0631\u06cc\u0627\u0646\u200c\u0647\u0627 \u0631\u0648 \u0633\u0627\u062f\u0647\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0686\u0648\u0646 \u0647\u0631 \u0648\u0631\u0648\u062f\u06cc \u0646\u0627\u0645 \u0645\u0634\u062e\u0635\u06cc \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u062a\u0645\u0627\u0645 \u0627\u062a\u0641\u0627\u0642\u200c\u0647\u0627 \u0631\u0648 \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0634\u06cc\u06a9 \u0634\u062f\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc \u062f\u0627\u062e\u0644 \u06cc\u06a9 <code>UiEvent<\/code> \u0642\u0631\u0627\u0631 \u0628\u062f\u06cc\u0645\u060c \u0627\u0645\u0627 State \u0647\u0645\u0686\u0646\u0627\u0646 \u062f\u0631 \u0686\u0646\u062f \u0645\u062a\u063a\u06cc\u0631 \u062c\u062f\u0627 \u0648 \u0646\u0627\u0645\u0631\u062a\u0628\u0637 \u067e\u062e\u0634 \u0628\u0627\u0634\u0647. Event-Driven UI \u0641\u0642\u0637 \u062f\u0627\u0634\u062a\u0646 Sealed Class \u0646\u06cc\u0633\u062a\u061b \u0628\u0627\u06cc\u062f \u062c\u0631\u06cc\u0627\u0646 \u062a\u063a\u06cc\u06cc\u0631 State \u0647\u0645 \u06cc\u06a9\u200c\u0637\u0631\u0641\u0647 \u0648 \u0642\u0627\u0628\u0644\u200c\u0631\u062f\u06cc\u0627\u0628\u06cc \u0628\u0627\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0634\u062a\u0628\u0627\u0647 \u062f\u0648\u0645 \u0627\u06cc\u0646\u0647 \u06a9\u0647 UI \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b State ViewModel \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>viewModel.uiState.value.isLoading = true\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">viewModel.uiState.<\/span><span style=\"color: #D73A49\">value<\/span><span style=\"color: #24292E\">.isLoading <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">true<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">State \u0628\u0627\u06cc\u062f Immutable \u0648 \u0641\u0642\u0637 \u0627\u0632 \u0637\u0631\u06cc\u0642 Event Handler \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647. Compose \u0647\u0645 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0645\u0642\u0627\u062f\u06cc\u0631 Immutable \u0648 Callback\u0647\u0627\u06cc Event \u0628\u0647 Composable \u062f\u0627\u062f\u0647 \u0628\u0634\u0646 \u062a\u0627 \u0627\u062d\u062a\u0645\u0627\u0644 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u0633\u062a\u0642\u06cc\u0645 State \u0648 \u0645\u0634\u06a9\u0644\u0627\u062a \u0647\u0645\u200c\u0632\u0645\u0627\u0646\u06cc \u06a9\u0645\u062a\u0631 \u0628\u0634\u0647. \u0627\u0634\u062a\u0628\u0627\u0647 \u0633\u0648\u0645 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0647\u0631 Snackbar \u0648 Navigation \u0628\u0627 <code>SharedFlow<\/code> \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0647\u060c \u0628\u062f\u0648\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u062f\u0631\u0628\u0627\u0631\u0647 Lifecycle \u0648 \u0627\u062d\u062a\u0645\u0627\u0644 \u0627\u0632\u062f\u0633\u062a\u200c\u0631\u0641\u062a\u0646 \u0631\u0648\u06cc\u062f\u0627\u062f \u0641\u06a9\u0631 \u06a9\u0646\u06cc\u0645. \u0627\u0634\u062a\u0628\u0627\u0647 \u0686\u0647\u0627\u0631\u0645 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u062a\u0645\u0627\u0645 State\u0647\u0627\u06cc \u06a9\u0648\u0686\u06a9 UI \u0628\u0647 ViewModel \u0645\u0646\u062a\u0642\u0644 \u0628\u0634\u0646 \u0648 ViewModel \u0627\u0632 \u062c\u0632\u0626\u06cc\u0627\u062a \u0646\u0645\u0627\u06cc\u0634\u06cc \u067e\u0631 \u0628\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TextField focus\nAnimation progress\nExpanded card\nScroll indicator\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0627\u06cc\u0646 State\u0647\u0627 \u0627\u0631\u0632\u0634 \u06a9\u0633\u0628\u200c\u0648\u06a9\u0627\u0631\u06cc \u06cc\u0627 \u0646\u06cc\u0627\u0632 \u0628\u0647 \u0645\u0627\u0646\u062f\u06af\u0627\u0631\u06cc \u0646\u062f\u0627\u0631\u0646\u060c \u0628\u0647\u062a\u0631\u0647 \u0645\u062d\u0644\u06cc \u0628\u0627\u0642\u06cc \u0628\u0645\u0648\u0646\u0646. \u0627\u0634\u062a\u0628\u0627\u0647 \u067e\u0646\u062c\u0645 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u06cc\u06a9 Event \u06a9\u0644\u06cc \u0648 \u0645\u0628\u0647\u0645 \u0628\u0633\u0627\u0632\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>data class Click(\n    val id: Int\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Click<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> id: <\/span><span style=\"color: #6F42C1\">Int<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0628\u0627 \u0639\u062f\u062f\u0647\u0627 \u062d\u062f\u0633 \u0628\u0632\u0646\u06cc\u0645 \u06a9\u062f\u0648\u0645 \u062f\u06a9\u0645\u0647 \u0644\u0645\u0633 \u0634\u062f\u0647. Event \u0628\u0627\u06cc\u062f \u0645\u0639\u0646\u0627\u06cc \u0631\u0648\u0634\u0646\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>RefreshClicked\nProductClicked\nDeleteProductClicked\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0634\u062a\u0628\u0627\u0647 \u0634\u0634\u0645 \u0627\u06cc\u0646\u0647 \u06a9\u0647 Event Handler \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0647\u0632\u0627\u0631\u0627\u0646 \u062e\u0637 \u0645\u0646\u0637\u0642 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. <code>onEvent<\/code>\u00a0\u0628\u0627\u06cc\u062f Router \u0628\u0627\u0634\u0647 \u0648 \u0645\u0646\u0637\u0642 \u0647\u0631 \u0639\u0645\u0644\u06cc\u0627\u062a \u0628\u0647 \u062a\u0627\u0628\u0639\u060c Use Case \u06cc\u0627 Reducer \u0645\u0646\u0627\u0633\u0628 \u0645\u0646\u062a\u0642\u0644 \u0628\u0634\u0647. \u0627\u0634\u062a\u0628\u0627\u0647 \u0647\u0641\u062a\u0645 \u0647\u0645 \u0627\u06cc\u0646\u0647 \u06a9\u0647 State\u0647\u0627\u06cc \u0646\u0627\u0645\u0645\u06a9\u0646 \u0628\u0633\u0627\u0632\u06cc\u0645. \u0645\u062b\u0644\u0627\u064b \u0647\u0645\u200c\u0632\u0645\u0627\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>isInitialLoading = true\nshowEmptyState = true\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">State\u0647\u0627\u06cc \u0645\u0634\u062a\u0642\u200c\u0634\u062f\u0647 \u0645\u062b\u0644 <code>showEmptyState<\/code> \u0628\u0647\u062a\u0631\u0647 \u0627\u0632 State \u0627\u0635\u0644\u06cc \u0645\u062d\u0627\u0633\u0628\u0647 \u0628\u0634\u0646 \u062a\u0627 \u062a\u0646\u0627\u0642\u0636 \u0627\u06cc\u062c\u0627\u062f \u0646\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0645\u0639\u0645\u0627\u0631\u06cc \u0646\u0647\u0627\u06cc\u06cc \u0635\u0641\u062d\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u062c\u0631\u06cc\u0627\u0646 \u06a9\u0627\u0645\u0644 \u0635\u0641\u062d\u0647 \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0628\u0647 \u0627\u06cc\u0646 \u0634\u06a9\u0644 \u062f\u0631\u0645\u06cc\u0627\u062f:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">User types query<br>\u2193<br>SearchQueryChanged<br>\u2193<br>ViewModel updates query state<br>\u2193<br>Combined products are filtered<br>\u2193<br>New UiState is emitted<br>\u2193<br>Compose renders filtered list<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Refresh:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">User taps refresh<br>\u2193<br>RefreshClicked<br>\u2193<br>ViewModel sets isRefreshing<br>\u2193<br>Use case refreshes repository<br>\u2193<br>Room is updated<br>\u2193<br>Product Flow emits new data<br>\u2193<br>UiState changes<br>\u2193<br>Compose renders fresh data<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0630\u0641:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">DeleteProductClicked<br>\u2193<br>State contains pending product<br>\u2193<br>UI displays confirmation dialog<br>\u2193<br>DeleteDialogConfirmed<br>\u2193<br>Use case deletes product<br>\u2193<br>Room emits updated list<br>\u2193<br>Snackbar message enters state<br>\u2193<br>UI shows Snackbar<br>\u2193<br>UserMessageShown<br>\u2193<br>Message is cleared<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Navigation:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">ProductClicked<br>\u2193<br>navigationTarget enters state<br>\u2193<br>UI performs navigation<br>\u2193<br>NavigationHandled<br>\u2193<br>navigationTarget is cleared<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc\u060c UI \u0647\u06cc\u0686 \u0645\u0646\u0637\u0642 \u06a9\u0633\u0628\u200c\u0648\u06a9\u0627\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u0646\u0645\u06cc\u062f\u0647. ViewModel \u0647\u0645 \u0647\u06cc\u0686 Composable\u060c SnackbarHost \u06cc\u0627 NavController \u0631\u0648 \u0646\u0645\u06cc\u200c\u0634\u0646\u0627\u0633\u0647. \u0627\u0631\u062a\u0628\u0627\u0637 \u062f\u0648 \u0637\u0631\u0641 \u0641\u0642\u0637 \u0628\u0627 State \u0648 Event \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0686\u06a9\u200c\u0644\u06cc\u0633\u062a Event-Driven UI<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u067e\u06cc\u0634 \u0627\u0632 \u0646\u0647\u0627\u06cc\u06cc \u06a9\u0631\u062f\u0646 \u0647\u0631 \u0635\u0641\u062d\u0647 \u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646\u060c \u0627\u06cc\u0646 \u0645\u0648\u0627\u0631\u062f \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u062a\u0645\u0627\u0645 \u0648\u0631\u0648\u062f\u06cc\u200c\u0647\u0627\u06cc \u0645\u0647\u0645 \u0635\u0641\u062d\u0647 Event \u0645\u0634\u062e\u0635 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>Event \u0646\u0627\u0645 \u0627\u062a\u0641\u0627\u0642 \u0631\u0648 \u062a\u0648\u0635\u06cc\u0641 \u06a9\u0646\u0647\u060c \u0646\u0647 \u062f\u0633\u062a\u0648\u0631 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0631\u0648.<\/li>\n\n\n\n<li>UI State \u062a\u0645\u0627\u0645 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0644\u0627\u0632\u0645 \u0628\u0631\u0627\u06cc Render \u0631\u0648 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>State \u0627\u0632 \u0628\u06cc\u0631\u0648\u0646 Immutable \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>ViewModel \u062a\u0646\u0647\u0627 \u0645\u062d\u0644 \u062a\u063a\u06cc\u06cc\u0631 State \u06a9\u0633\u0628\u200c\u0648\u06a9\u0627\u0631\u06cc \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>UI \u0641\u0642\u0637 State \u0631\u0648 \u0628\u062e\u0648\u0646\u0647 \u0648 Event \u0628\u0641\u0631\u0633\u062a\u0647.<\/li>\n\n\n\n<li>\u062f\u0627\u062f\u0647 \u0627\u0632 \u0628\u0627\u0644\u0627 \u0628\u0647 \u067e\u0627\u06cc\u06cc\u0646 \u0648 Event \u0627\u0632 \u067e\u0627\u06cc\u06cc\u0646 \u0628\u0647 \u0628\u0627\u0644\u0627 \u062d\u0631\u06a9\u062a \u06a9\u0646\u0647.<\/li>\n\n\n\n<li>State\u0647\u0627\u06cc \u0645\u0634\u062a\u0642\u200c\u0634\u062f\u0647 \u0627\u0632 \u0645\u0642\u0627\u062f\u06cc\u0631 \u0627\u0635\u0644\u06cc \u0645\u062d\u0627\u0633\u0628\u0647 \u0628\u0634\u0646.<\/li>\n\n\n\n<li>Loading \u0627\u0648\u0644\u06cc\u0647 \u0628\u0627 Refresh \u0627\u0632 \u0647\u0645 \u062c\u062f\u0627 \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>Snackbar \u0645\u0647\u0645 \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 State \u0645\u0635\u0631\u0641\u200c\u0634\u0648\u0646\u062f\u0647 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0628\u0634\u0647.<\/li>\n\n\n\n<li>Navigation \u0645\u0647\u0645 \u062f\u0631 \u0628\u0631\u0627\u0628\u0631 \u0648\u0642\u0641\u0647 Lifecycle \u0627\u0632 \u0628\u06cc\u0646 \u0646\u0631\u0647.<\/li>\n\n\n\n<li>\u0628\u0639\u062f \u0627\u0632 \u0645\u0635\u0631\u0641 \u067e\u06cc\u0627\u0645 \u06cc\u0627 Navigation\u060c Event \u067e\u0627\u06a9\u200c\u0633\u0627\u0632\u06cc \u0627\u0631\u0633\u0627\u0644 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>SharedFlow \u0641\u0642\u0637 \u0628\u0627 \u0634\u0646\u0627\u062e\u062a \u0631\u0641\u062a\u0627\u0631 Hot Stream \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u0648\u0636\u0639\u06cc\u062a\u200c\u0647\u0627\u06cc \u0645\u062d\u0644\u06cc \u0648 \u0635\u0631\u0641\u0627\u064b \u0646\u0645\u0627\u06cc\u0634\u06cc \u062f\u0627\u062e\u0644 Composable \u0628\u0627\u0642\u06cc \u0628\u0645\u0648\u0646\u0646.<\/li>\n\n\n\n<li>ViewModel \u0628\u0647 <code>NavController<\/code>\u060c <code>Context<\/code> \u06cc\u0627 Composable \u0648\u0627\u0628\u0633\u062a\u0647 \u0646\u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>Screen Stateless \u0627\u0632 Route \u062f\u0627\u0631\u0627\u06cc ViewModel \u062c\u062f\u0627 \u0628\u0627\u0634\u0647.<\/li>\n\n\n\n<li>Flow\u0647\u0627 \u0628\u0627 Lifecycle \u0645\u0646\u0627\u0633\u0628 Collect \u0628\u0634\u0646.<\/li>\n\n\n\n<li>Event \u062a\u06a9\u0631\u0627\u0631\u06cc \u06cc\u0627 \u06a9\u0644\u06cc\u06a9 \u0686\u0646\u062f\u0628\u0627\u0631\u0647 \u062f\u0631 ViewModel \u0647\u0645 \u06a9\u0646\u062a\u0631\u0644 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u0639\u0645\u0644\u06cc\u0627\u062a Async \u062f\u0627\u062e\u0644 Use Case \u06cc\u0627 Repository \u0627\u0646\u062c\u0627\u0645 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>Event Handler \u0645\u0631\u06a9\u0632\u06cc \u0628\u0647 \u062a\u0627\u0628\u0639 \u063a\u0648\u0644\u200c\u067e\u06cc\u06a9\u0631 \u062a\u0628\u062f\u06cc\u0644 \u0646\u0634\u0647.<\/li>\n\n\n\n<li>\u062a\u063a\u06cc\u06cc\u0631\u0627\u062a State \u0642\u0627\u0628\u0644\u200c\u062a\u0633\u062a \u0628\u0627\u0634\u0646.<\/li>\n\n\n\n<li>Event\u0647\u0627\u06cc \u062d\u0633\u0627\u0633 \u0628\u062f\u0648\u0646 \u0641\u06cc\u0644\u062a\u0631 \u0648\u0627\u0631\u062f Log \u06cc\u0627 Analytics \u0646\u0634\u0646.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Event-Driven UI \u06cc\u0639\u0646\u06cc \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0628\u0647\u200c\u062c\u0627\u06cc \u062a\u063a\u06cc\u06cc\u0631 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0627\u062c\u0632\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u0627\u062a\u0641\u0627\u0642\u200c\u0647\u0627 \u0631\u0648 \u0628\u0647 \u0634\u06a9\u0644 Event \u0627\u0639\u0644\u0627\u0645 \u06a9\u0646\u0647. ViewModel \u0627\u06cc\u0646 \u0627\u062a\u0641\u0627\u0642\u200c\u0647\u0627 \u0631\u0648 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc\u200c\u06a9\u0646\u0647\u060c \u0645\u0646\u0637\u0642 \u0644\u0627\u0632\u0645 \u0631\u0648 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 State \u062a\u0627\u0632\u0647\u200c\u0627\u06cc \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647. UI \u0647\u0645 \u0641\u0642\u0637 State \u0631\u0648 Render \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0646\u062a\u06cc\u062c\u0647 \u0627\u06cc\u0646 \u062c\u0631\u06cc\u0627\u0646\u060c \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0642\u0627\u0628\u0644\u200c\u067e\u06cc\u0634\u200c\u0628\u06cc\u0646\u06cc\u200c\u062a\u0631\u060c \u062a\u0633\u062a\u200c\u067e\u0630\u06cc\u0631\u062a\u0631 \u0648 \u0645\u0642\u0627\u0648\u0645\u200c\u062a\u0631 \u062f\u0631 \u0628\u0631\u0627\u0628\u0631 \u067e\u06cc\u0686\u06cc\u062f\u06af\u06cc\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646\u060c \u0627\u062a\u0641\u0627\u0642\u200c\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 \u0644\u0645\u0633 Refresh\u060c \u062a\u063a\u06cc\u06cc\u0631 \u0639\u0628\u0627\u0631\u062a \u062c\u0633\u062a\u200c\u0648\u062c\u0648\u060c \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u062d\u0635\u0648\u0644\u060c \u062d\u0630\u0641 \u0648 Retry \u0647\u0645\u06af\u06cc Event \u0647\u0633\u062a\u0646. \u0641\u0647\u0631\u0633\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a\u060c \u0648\u0636\u0639\u06cc\u062a Loading\u060c \u0639\u0628\u0627\u0631\u062a \u062c\u0633\u062a\u200c\u0648\u062c\u0648\u060c Dialog \u062d\u0630\u0641 \u0648 \u067e\u06cc\u0627\u0645 \u062f\u0631 \u0627\u0646\u062a\u0638\u0627\u0631 \u0646\u0645\u0627\u06cc\u0634\u060c State \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0646. Navigation \u0648 Snackbar \u0647\u0645 \u0646\u0628\u0627\u06cc\u062f \u0628\u062f\u0648\u0646 \u0641\u06a9\u0631 \u0628\u0647\u200c\u0639\u0646\u0648\u0627\u0646 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627\u06cc \u0644\u062d\u0638\u0647\u200c\u0627\u06cc \u0641\u0631\u0633\u062a\u0627\u062f\u0647 \u0628\u0634\u0646\u061b \u0686\u0648\u0646 \u0645\u0645\u06a9\u0646\u0647 \u0647\u0646\u06af\u0627\u0645 \u0646\u0628\u0648\u062f Collector \u0627\u0632 \u0628\u06cc\u0646 \u0628\u0631\u0646. \u0628\u0631\u0627\u06cc \u0639\u0645\u0644\u06cc\u0627\u062a \u0645\u0647\u0645\u060c State \u0645\u0635\u0631\u0641\u200c\u0634\u0648\u0646\u062f\u0647 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u0646\u062a\u062e\u0627\u0628 \u0645\u0637\u0645\u0626\u0646\u200c\u062a\u0631\u06cc\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc \u0628\u0647 \u0627\u06cc\u0646 \u0645\u0639\u0646\u0627 \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0647\u0631 \u06a9\u0644\u06cc\u06a9 \u0633\u0627\u062f\u0647 \u0628\u0627\u06cc\u062f \u0627\u0632 \u067e\u0646\u062c \u0644\u0627\u06cc\u0647 \u0639\u0628\u0648\u0631 \u06a9\u0646\u0647. \u0628\u0627\u0632 \u0648 \u0628\u0633\u062a\u0647 \u0634\u062f\u0646 \u06cc\u06a9 \u0628\u062e\u0634 \u0646\u0645\u0627\u06cc\u0634\u06cc \u0645\u06cc\u200c\u062a\u0648\u0646\u0647 \u062f\u0627\u062e\u0644 \u062e\u0648\u062f Composable \u0628\u0627\u0642\u06cc \u0628\u0645\u0648\u0646\u0647. \u0645\u0631\u0632 \u0627\u0635\u0644\u06cc \u0627\u06cc\u0646\u0647: UI Logic \u0645\u062d\u0644\u06cc \u062f\u0631 UI \u0645\u062f\u06cc\u0631\u06cc\u062a \u0645\u06cc\u0634\u0647\u060c \u0627\u0645\u0627 \u0627\u062a\u0641\u0627\u0642\u06cc \u06a9\u0647 Business Logic \u0631\u0648 \u0641\u0639\u0627\u0644 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u06cc\u0627 \u0631\u0648\u06cc \u0648\u0636\u0639\u06cc\u062a \u067e\u0627\u06cc\u062f\u0627\u0631 \u0635\u0641\u062d\u0647 \u0627\u062b\u0631 \u0645\u06cc\u200c\u0630\u0627\u0631\u0647\u060c \u0628\u0627\u06cc\u062f \u0628\u0647 ViewModel \u0645\u0646\u062a\u0642\u0644 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0627 \u0627\u06cc\u0646 \u0633\u0627\u062e\u062a\u0627\u0631\u060c \u0647\u0631 \u0635\u0641\u062d\u0647 \u0628\u0647 \u06cc\u06a9 \u0645\u0627\u0634\u06cc\u0646 \u0642\u0627\u0628\u0644\u200c\u0631\u062f\u06cc\u0627\u0628\u06cc \u062a\u0628\u062f\u06cc\u0644 \u0645\u06cc\u0634\u0647: Event \u0648\u0627\u0631\u062f \u0645\u06cc\u0634\u0647\u060c State \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647 \u0648 UI \u062f\u0648\u0628\u0627\u0631\u0647 \u0628\u0631\u0627\u0633\u0627\u0633 State \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc\u0634\u0647. \u0647\u0645\u06cc\u0646 \u0686\u0631\u062e\u0647 \u0633\u0627\u062f\u0647\u060c \u067e\u0627\u06cc\u0647 \u0628\u0633\u06cc\u0627\u0631\u06cc \u0627\u0632 \u0645\u0639\u0645\u0627\u0631\u06cc\u200c\u0647\u0627\u06cc \u0645\u062f\u0631\u0646 \u0645\u062b\u0644 UDF \u0648 MVI \u0645\u062d\u0633\u0648\u0628 \u0645\u06cc\u0634\u0647 \u0648 \u0627\u062c\u0627\u0632\u0647 \u0645\u06cc\u062f\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0628\u062f\u0648\u0646 \u062a\u0628\u062f\u06cc\u0644 \u0634\u062f\u0646 \u0628\u0647 \u0645\u062c\u0645\u0648\u0639\u0647\u200c\u0627\u06cc \u0627\u0632 Callback\u0647\u0627 \u0648 \u0645\u062a\u063a\u06cc\u0631\u0647\u0627\u06cc \u067e\u0631\u0627\u06a9\u0646\u062f\u0647\u060c \u0628\u0647\u200c\u0645\u0631\u0648\u0631 \u0628\u0632\u0631\u06af\u200c\u062a\u0631 \u0628\u0634\u0647.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u200c\u0648\u0634\u0634\u0645<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u0637\u0631\u0627\u062d\u06cc \u0628\u0631\u0627\u06cc \u062a\u0648\u0633\u0639\u0647 \u0622\u06cc\u0646\u062f\u0647 (Designing for Future Growth)<\/h1>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-13-1-1024x683.avif\" alt=\"\" class=\"wp-image-6168\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-13-1-1024x683.avif 1024w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-13-1-300x200.avif 300w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-13-1-768x512.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-13-1.avif 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647 \u062a\u0627\u0632\u0647 \u0634\u0631\u0648\u0639 \u0645\u06cc\u0634\u0647\u060c \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0645\u0647 \u0686\u06cc\u0632 \u0633\u0627\u062f\u0647 \u0628\u0647 \u0646\u0638\u0631 \u0645\u06cc\u0627\u062f. \u0634\u0627\u06cc\u062f \u0641\u0642\u0637 \u067e\u0646\u062c \u0635\u0641\u062d\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645\u060c \u062f\u0647 API\u060c \u0686\u0646\u062f \u062c\u062f\u0648\u0644 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0648 \u062f\u0648 \u0633\u0647 Repository. \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0631\u062d\u0644\u0647 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0631 \u0645\u0639\u0645\u0627\u0631\u06cc\u200c\u0627\u06cc \u062c\u0648\u0627\u0628 \u0645\u06cc\u062f\u0647. \u062d\u062a\u06cc \u0627\u06af\u0631 \u0647\u0645\u0647 \u0686\u06cc\u0632 \u0631\u0648 \u062f\u0627\u062e\u0644 \u06cc\u06a9 \u0641\u0627\u06cc\u0644 \u0628\u0632\u0631\u06af \u0628\u0646\u0648\u06cc\u0633\u06cc\u060c \u0627\u062d\u062a\u0645\u0627\u0644\u0627\u064b \u067e\u0631\u0648\u0698\u0647 \u0628\u062f\u0648\u0646 \u0645\u0634\u06a9\u0644 \u0627\u062c\u0631\u0627 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0645\u0633\u0626\u0644\u0647 \u0627\u06cc\u0646\u062c\u0627\u0633\u062a \u06a9\u0647 \u0646\u0631\u0645\u200c\u0627\u0641\u0632\u0627\u0631 \u0628\u0631\u0627\u06cc \u0627\u0645\u0631\u0648\u0632 \u0646\u0648\u0634\u062a\u0647 \u0646\u0645\u06cc\u0634\u0647\u061b \u0628\u0631\u0627\u06cc \u0634\u0634 \u0645\u0627\u0647\u060c \u06cc\u06a9 \u0633\u0627\u0644 \u06cc\u0627 \u062d\u062a\u06cc \u0686\u0646\u062f \u0633\u0627\u0644 \u0628\u0639\u062f \u0646\u0648\u0634\u062a\u0647 \u0645\u06cc\u0634\u0647. \u0641\u0631\u0636 \u06a9\u0646 \u0627\u0645\u0631\u0648\u0632 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0641\u0642\u0637 \u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u062f\u06cc\u062c\u06cc\u200c\u06a9\u0627\u0644\u0627 \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0634\u0634 \u0645\u0627\u0647 \u0628\u0639\u062f \u06a9\u0627\u0631\u0641\u0631\u0645\u0627 \u0645\u06cc\u06af\u0647:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u062a\u0631\u0628 \u0647\u0645 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646.<\/li>\n\n\n\n<li>\u0622\u0645\u0627\u0632\u0648\u0646 \u0647\u0645 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646.<\/li>\n\n\n\n<li>\u0627\u0645\u06a9\u0627\u0646 \u0645\u0642\u0627\u06cc\u0633\u0647 \u0642\u06cc\u0645\u062a \u0641\u0631\u0648\u0634\u06af\u0627\u0647\u200c\u0647\u0627 \u0631\u0648 \u0647\u0645 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646.<\/li>\n\n\n\n<li>\u0633\u06cc\u0633\u062a\u0645 \u0627\u0639\u0644\u0627\u0646 \u0627\u06cc\u0645\u06cc\u0644\u06cc \u0647\u0645 \u0645\u06cc\u062e\u0648\u0627\u06cc\u0645.<\/li>\n\n\n\n<li>\u0646\u0633\u062e\u0647 iOS \u0647\u0645 \u0642\u0631\u0627\u0631\u0647 \u0633\u0627\u062e\u062a\u0647 \u0628\u0634\u0647.<\/li>\n\n\n\n<li>\u067e\u0646\u0644 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0647\u0645 \u0644\u0627\u0632\u0645 \u062f\u0627\u0631\u06cc\u0645.<\/li>\n\n\n\n<li>API \u0639\u0645\u0648\u0645\u06cc \u0647\u0645 \u0645\u06cc\u062e\u0648\u0627\u06cc\u0645.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0645\u0639\u0645\u0627\u0631\u06cc \u0627\u0632 \u0631\u0648\u0632 \u0627\u0648\u0644 \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0648\u0636\u0639\u06cc\u062a \u0641\u0639\u0644\u06cc \u0637\u0631\u0627\u062d\u06cc \u0634\u062f\u0647 \u0628\u0627\u0634\u0647\u060c \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0646 \u0647\u0631 \u0642\u0627\u0628\u0644\u06cc\u062a \u062c\u062f\u06cc\u062f \u06cc\u0639\u0646\u06cc \u062e\u0631\u0627\u0628 \u06a9\u0631\u062f\u0646 \u0628\u062e\u0634 \u0632\u06cc\u0627\u062f\u06cc \u0627\u0632 \u06a9\u062f\u0647\u0627\u06cc \u0642\u0628\u0644\u06cc. \u0647\u062f\u0641 \u0637\u0631\u0627\u062d\u06cc \u0628\u0631\u0627\u06cc \u0622\u06cc\u0646\u062f\u0647 \u0627\u06cc\u0646 \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0622\u06cc\u0646\u062f\u0647 \u0631\u0648 \u067e\u06cc\u0634\u200c\u0628\u06cc\u0646\u06cc \u06a9\u0646\u06cc\u0645\u061b \u0686\u0648\u0646 \u0647\u06cc\u0686\u200c\u06a9\u0633 \u0622\u06cc\u0646\u062f\u0647 \u0631\u0648 \u062f\u0642\u06cc\u0642 \u0646\u0645\u06cc\u200c\u062f\u0648\u0646\u0647. \u0647\u062f\u0641 \u0627\u06cc\u0646\u0647 \u06a9\u0647 <strong>\u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0622\u06cc\u0646\u062f\u0647\u060c \u06a9\u0645\u062a\u0631\u06cc\u0646 \u0647\u0632\u06cc\u0646\u0647 \u0645\u0645\u06a9\u0646 \u0631\u0648 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646.<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0628\u0632\u0631\u06af\u200c\u062a\u0631\u06cc\u0646 \u0627\u0634\u062a\u0628\u0627\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-14-1-1024x683.avif\" alt=\"\" class=\"wp-image-6169\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-14-1-1024x683.avif 1024w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-14-1-300x200.avif 300w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-14-1-768x512.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-14-1.avif 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u06cc\u0644\u06cc\u200c\u0647\u0627 \u0641\u06a9\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646 \u0637\u0631\u0627\u062d\u06cc \u0628\u0631\u0627\u06cc \u0622\u06cc\u0646\u062f\u0647 \u06cc\u0639\u0646\u06cc \u0627\u0632 \u0647\u0645\u0648\u0646 \u0631\u0648\u0632 \u0627\u0648\u0644 \u0647\u0645\u0647 \u0686\u06cc\u0632 \u0631\u0648 \u067e\u06cc\u0686\u06cc\u062f\u0647 \u0637\u0631\u0627\u062d\u06cc \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0628\u0631\u0627\u06cc \u067e\u0631\u0648\u0698\u0647\u200c\u0627\u06cc \u06a9\u0647 \u0641\u0642\u0637 \u06cc\u06a9 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u062f\u0627\u0631\u0647\u060c \u0627\u06cc\u0646 \u0633\u0627\u062e\u062a\u0627\u0631 \u0631\u0648 \u0645\u06cc\u0633\u0627\u0632\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>RepositoryFactory\nAbstractRepository\nRepositoryProvider\nRepositoryManager\nRepositoryAdapter\nRepositoryStrategy\nRepositoryRegistry\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u067e\u0631\u0648\u0698\u0647 \u0641\u0642\u0637 \u06cc\u06a9 Repository \u062f\u0627\u0631\u0647! \u0627\u06cc\u0646 \u0627\u0633\u0645\u0634 \u0637\u0631\u0627\u062d\u06cc \u0622\u06cc\u0646\u062f\u0647 \u0646\u06cc\u0633\u062a. \u0627\u06cc\u0646 \u0627\u0633\u0645\u0634 <strong>Over Engineering<\/strong> \u06cc\u0627 \u0645\u0647\u0646\u062f\u0633\u06cc \u0628\u06cc\u0634 \u0627\u0632 \u0627\u0646\u062f\u0627\u0632\u0647 \u0627\u0633\u062a. \u0645\u0639\u0645\u0627\u0631\u06cc \u062e\u0648\u0628\u060c \u0633\u0627\u062f\u0647\u200c\u062a\u0631\u06cc\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc\u200c\u0627\u06cc\u0647 \u06a9\u0647 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0622\u06cc\u0646\u062f\u0647 \u0631\u0648 \u0645\u0645\u06a9\u0646 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0646\u0647 \u0633\u0627\u062f\u0647\u200c\u062a\u0631. \u0646\u0647 \u067e\u06cc\u0686\u06cc\u062f\u0647\u200c\u062a\u0631.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u0622\u06cc\u0646\u062f\u0647 \u062f\u0642\u06cc\u0642\u0627\u064b \u0686\u0647 \u0686\u06cc\u0632\u06cc \u0631\u0627 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u062f\u0647\u062f\u061f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0628\u0632\u0631\u06af \u062f\u0646\u06cc\u0627 \u0631\u0648 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645\u060c \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0645\u0647 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0622\u06cc\u0646\u062f\u0647 \u062f\u0627\u062e\u0644 \u0686\u0646\u062f \u062f\u0633\u062a\u0647 \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0646. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0639\u0648\u0636 \u0645\u06cc\u200c\u0634\u0648\u062f.<br>API \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f.<br>UI \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f.<br>Business Rule \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f.<br>Feature \u062c\u062f\u06cc\u062f \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f.<br>Platform \u062c\u062f\u06cc\u062f \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f.<br>\u062a\u0639\u062f\u0627\u062f \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0632\u06cc\u0627\u062f \u0645\u06cc\u200c\u0634\u0648\u062f.<br>Performance \u0645\u0647\u0645\u200c\u062a\u0631 \u0645\u06cc\u200c\u0634\u0648\u062f.<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062c\u0627\u0644\u0628\u0647 \u06a9\u0647 \u0628\u06cc\u0634\u062a\u0631 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0646\u0631\u0645\u200c\u0627\u0641\u0632\u0627\u0631\u0647\u0627 \u062f\u0627\u062e\u0644 \u0647\u0645\u06cc\u0646 \u0686\u0646\u062f \u062f\u0633\u062a\u0647 \u062e\u0644\u0627\u0635\u0647 \u0645\u06cc\u0634\u0646. \u067e\u0633 \u0627\u06af\u0631 \u0645\u0639\u0645\u0627\u0631\u06cc \u0628\u062a\u0648\u0646\u0647 \u0627\u06cc\u0646 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0631\u0648 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u0647\u060c \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0628\u0631\u0627\u06cc \u0622\u06cc\u0646\u062f\u0647 \u0622\u0645\u0627\u062f\u0647 \u0627\u0633\u062a.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0645\u0639\u0645\u0627\u0631\u06cc \u0628\u0627\u06cc\u062f \u062a\u063a\u06cc\u06cc\u0631 \u0631\u0627 \u0627\u0631\u0632\u0627\u0646 \u06a9\u0646\u062f<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0627\u0645\u0631\u0648\u0632 Repository \u0627\u06cc\u0646 \u0634\u06a9\u0644\u06cc\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductRepository {\n\n    suspend fun getProducts(): List&lt;Product> {\n        ...\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getProducts<\/span><span style=\"color: #24292E\">(): <\/span><span style=\"color: #6F42C1\">List<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">&gt; {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">..<\/span><span style=\"color: #24292E\">.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f\u0627\u064b \u062a\u0635\u0645\u06cc\u0645 \u0645\u06cc\u200c\u06af\u06cc\u0631\u06cc Cache \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc. \u0627\u06af\u0631 \u06a9\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0628\u0627 Retrofit \u06a9\u0627\u0631 \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u0647\u060c \u0628\u0627\u06cc\u062f \u0635\u062f\u0647\u0627 \u0641\u0627\u06cc\u0644 \u0631\u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u06cc. \u0627\u0645\u0627 \u0627\u06af\u0631 \u0647\u0645\u0647 \u0627\u0632 Repository \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u0646\u060c \u0641\u0642\u0637 Repository \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u0627\u06cc\u0646 \u06cc\u0639\u0646\u06cc:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" dir=\"ltr\">Cost of Change \u2193\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0632\u06cc\u0646\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0645 \u0634\u062f\u0647. \u0627\u06cc\u0646 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u0648\u0638\u06cc\u0641\u0647 \u0645\u0639\u0645\u0627\u0631\u06cc\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0642\u0627\u0646\u0648\u0646 Open \/ Closed<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0639\u0631\u0648\u0641\u200c\u062a\u0631\u06cc\u0646 \u0642\u0648\u0627\u0646\u06cc\u0646 SOLID \u0647\u0645\u06cc\u0646 \u0645\u0648\u0636\u0648\u0639 \u0631\u0648 \u062a\u0648\u0636\u06cc\u062d \u0645\u06cc\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u06cc\u06af\u0647 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u0628\u0627\u06cc\u062f:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Open for Extension\n\nClosed for Modification\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0639\u0646\u06cc:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u062a\u0648\u0646\u06cc \u0642\u0627\u0628\u0644\u06cc\u062a \u062c\u062f\u06cc\u062f \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u062f\u0648\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0645\u062c\u0628\u0648\u0631 \u0628\u0634\u06cc \u06a9\u062f\u0647\u0627\u06cc \u0642\u0628\u0644\u06cc \u0631\u0648 \u062e\u0631\u0627\u0628 \u06a9\u0646\u06cc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0627\u0645\u0631\u0648\u0632 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0641\u0642\u0637 \u0627\u06cc\u0646 \u0646\u0648\u0639 \u0627\u0639\u0644\u0627\u0646 \u0631\u0648 \u062f\u0627\u0631\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>sealed interface NotificationType {\n\n    data object PriceDrop : NotificationType\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">sealed<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">NotificationType<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceDrop<\/span><span style=\"color: #24292E\"> : <\/span><span style=\"color: #6F42C1\">NotificationType<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0634\u0634 \u0645\u0627\u0647 \u0628\u0639\u062f:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>sealed interface NotificationType {\n\n    data object PriceDrop : NotificationType\n\n    data object ProductAvailable : NotificationType\n\n    data object PriceTargetReached : NotificationType\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">sealed<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">NotificationType<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceDrop<\/span><span style=\"color: #24292E\"> : <\/span><span style=\"color: #6F42C1\">NotificationType<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductAvailable<\/span><span style=\"color: #24292E\"> : <\/span><span style=\"color: #6F42C1\">NotificationType<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">object<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PriceTargetReached<\/span><span style=\"color: #24292E\"> : <\/span><span style=\"color: #6F42C1\">NotificationType<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0627 \u0686\u06cc\u0632\u06cc \u0627\u0632 \u0633\u06cc\u0633\u062a\u0645 \u0642\u0628\u0644\u06cc \u062e\u0631\u0627\u0628 \u0646\u06a9\u0631\u062f\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0642\u0637 \u0642\u0627\u0628\u0644\u06cc\u062a \u062c\u062f\u06cc\u062f \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u06cc\u0645.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0648\u0627\u0628\u0633\u062a\u06af\u06cc \u0628\u0647 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc\u060c \u062f\u0634\u0645\u0646 \u0622\u06cc\u0646\u062f\u0647 \u0627\u0633\u062a<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 ViewModel \u0645\u0633\u062a\u0642\u06cc\u0645 Retrofit \u0631\u0648 \u0635\u062f\u0627 \u0628\u0632\u0646\u0647.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class HomeViewModel {\n\n    val api = Retrofit....\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HomeViewModel<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> api <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> Retrofit<\/span><span style=\"color: #D73A49\">....<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f\u0627\u064b \u0627\u06af\u0631 API \u0639\u0648\u0636 \u0628\u0634\u0647&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0645\u0627\u0645 ViewModel\u0647\u0627 \u0628\u0627\u06cc\u062f \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0627\u06af\u0631 ViewModel \u0641\u0642\u0637 \u0627\u06cc\u0646 \u0631\u0648 \u0628\u062f\u0648\u0646\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface ProductRepository {\n\n    suspend fun getProducts()\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">getProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u06cc\u06af\u0647 \u0628\u0631\u0627\u0634 \u0645\u0647\u0645 \u0646\u06cc\u0633\u062a \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0627\u0632 \u06a9\u062c\u0627 \u0645\u06cc\u0627\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0645\u06a9\u0646\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Retrofit\n\nRoom\n\nGraphQL\n\nFirebase\n\nLocal JSON\n\nMock Server\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u067e\u0634\u062a \u0647\u0645\u06cc\u0646 Interface \u0642\u0631\u0627\u0631 \u0628\u06af\u06cc\u0631\u0646.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Feature \u0645\u062d\u0648\u0631 \u0637\u0631\u0627\u062d\u06cc \u06a9\u0646\u060c \u0646\u0647 Layer \u0645\u062d\u0648\u0631<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0634\u06a9\u0644\u0627\u062a \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0642\u062f\u06cc\u0645\u06cc \u0627\u06cc\u0646\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>activities\n\nfragments\n\nviewmodels\n\nrepositories\n\nmodels\n\nadapters\n\nutils\n\nhelpers\n\nnetwork\n\ndatabase\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u0635\u0641\u062d\u0647 Product \u0631\u0648 \u0628\u0627\u0632 \u0645\u06cc\u200c\u06a9\u0646\u06cc \u0628\u0627\u06cc\u062f \u0628\u06cc\u0646 \u062f\u0647 \u067e\u0648\u0634\u0647 \u0628\u0686\u0631\u062e\u06cc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u067e\u0631\u0648\u0698\u0647 \u0628\u0632\u0631\u06af \u0627\u06cc\u0646 \u0633\u0627\u062e\u062a\u0627\u0631 \u0634\u06a9\u0646\u062c\u0647 \u0627\u0633\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u0627\u062e\u062a\u0627\u0631 \u0628\u0647\u062a\u0631:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>features\n\n    product\n\n        ui\n\n        domain\n\n        data\n\n    profile\n\n    search\n\n    login\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0647\u0631 Feature \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0645\u0633\u062a\u0642\u0644 \u0634\u062f\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f\u0627\u064b \u0627\u06af\u0631 \u0628\u062e\u0648\u0627\u06cc Feature \u062c\u062f\u06cc\u062f \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u060c \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u06cc\u0686 \u0686\u06cc\u0632 \u0642\u0628\u0644\u06cc \u062a\u063a\u06cc\u06cc\u0631 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0627\u0632 Utility \u0647\u0627\u06cc \u063a\u0648\u0644\u200c\u067e\u06cc\u06a9\u0631 \u0641\u0631\u0627\u0631 \u06a9\u0646<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0645\u0647 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0642\u062f\u06cc\u0645\u06cc \u06cc\u0647 \u0641\u0627\u06cc\u0644 \u062f\u0627\u0631\u0646 \u0628\u0647 \u0627\u0633\u0645:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Utils.kt\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u062f\u0627\u062e\u0644\u0634:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Date\n\nPrice\n\nBitmap\n\nValidation\n\nToast\n\nPermission\n\nFile\n\nNetwork\n\nJson\n\nImage\n\nColor\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u0686\u06cc\u0632 \u0631\u06cc\u062e\u062a\u0647 \u0634\u062f\u0647 \u062f\u0627\u062e\u0644\u0634. \u0634\u0634 \u0645\u0627\u0647 \u0628\u0639\u062f:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Utils.kt\n\n4200 Lines\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u0647\u06cc\u0686\u200c\u06a9\u0633 \u062c\u0631\u0626\u062a \u062a\u063a\u06cc\u06cc\u0631\u0634 \u0631\u0648 \u0646\u062f\u0627\u0631\u0647. \u0628\u0647\u062a\u0631\u0647 \u0647\u0631 \u0645\u0648\u0636\u0648\u0639 Utility \u062e\u0648\u062f\u0634 \u0631\u0648 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PriceFormatter\n\nDateFormatter\n\nNetworkChecker\n\nPermissionManager\n\nFileDownloader\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Configuration \u0631\u0627 \u0627\u0632 \u06a9\u062f \u062c\u062f\u0627 \u06a9\u0646<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0627\u06cc\u0646 \u0627\u0634\u062a\u0628\u0627\u0647\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>const val BASE_URL =\n    \"https:\/\/api.gheimatban.com\"\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">const<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> BASE_URL <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;https:\/\/api.gheimatban.com&quot;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f\u0627\u064b \u0628\u0631\u0627\u06cc \u062a\u0633\u062a:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Stage\n\nQA\n\nProduction\n\nDevelopment\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u062c\u0627 \u0628\u0627\u06cc\u062f \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u06cc. \u0628\u0647\u062a\u0631\u0647 Configuration \u0645\u0633\u062a\u0642\u0644 \u0628\u0627\u0634\u0647. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>BuildConfig\n\nRemote Config\n\nGradle\n\nFlavor\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0639\u062f\u062f\u0647\u0627\u06cc \u062c\u0627\u062f\u0648\u06cc\u06cc \u0646\u0646\u0648\u06cc\u0633<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06a9\u062f:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>delay(3000)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u0647 \u0645\u0627\u0647 \u0628\u0639\u062f: \u0647\u06cc\u0686\u200c\u06a9\u0633 \u0646\u0645\u06cc\u200c\u062f\u0648\u0646\u0647 \u0686\u0631\u0627 \u0633\u0647 \u062b\u0627\u0646\u06cc\u0647. \u0628\u0647\u062a\u0631\u0647:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const val RETRY_DELAY =\n    3.seconds\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NetworkConfig.RetryDelay\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Enum \u0628\u0647\u062a\u0631 \u0627\u0632 String \u0627\u0633\u062a<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>if(status==\"ACTIVE\")\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\">(status<\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #032F62\">&quot;ACTIVE&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ACTIVE\n\nActive\n\nactive\n\nActivated\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u067e\u0631\u0648\u0698\u0647 \u0628\u0647 \u0647\u0645 \u0645\u06cc\u0631\u06cc\u0632\u0647. \u0628\u0647\u062a\u0631:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>enum class ProductStatus {\n\n    ACTIVE,\n\n    INACTIVE,\n\n    DELETED\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">enum<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductStatus<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ACTIVE,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    INACTIVE,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    DELETED<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0642\u0631\u0627\u0631\u062f\u0627\u062f\u0647\u0627 \u0631\u0627 \u0646\u0633\u062e\u0647\u200c\u0628\u0646\u062f\u06cc \u06a9\u0646<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0627\u0645\u0631\u0648\u0632 Push \u0627\u06cc\u0646 \u0634\u06a9\u0644\u06cc\u0647:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n    \"type\":\"PRICE_DROP\"\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;type&quot;<\/span><span style=\"color: #24292E\">:<\/span><span style=\"color: #032F62\">&quot;PRICE_DROP&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0633\u0627\u0644 \u0628\u0639\u062f:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n    \"type\":\"PRICE_DROP\",\n\n    \"discount\":20\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;type&quot;<\/span><span style=\"color: #24292E\">:<\/span><span style=\"color: #032F62\">&quot;PRICE_DROP&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;discount&quot;<\/span><span style=\"color: #24292E\">:<\/span><span style=\"color: #6F42C1\">20<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0633\u062e\u0647 \u0628\u0639\u062f:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n    \"schemaVersion\":2\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;schemaVersion&quot;<\/span><span style=\"color: #24292E\">:<\/span><span style=\"color: #6F42C1\">2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0633\u062e\u0647\u200c\u0628\u0646\u062f\u06cc \u0628\u0627\u0639\u062b \u0645\u06cc\u0634\u0647 \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u0642\u062f\u06cc\u0645\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645 \u0642\u0627\u0628\u0644 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0628\u0627\u0634\u0646.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0647\u0645\u06cc\u0634\u0647 \u0646\u0642\u0637\u0647 \u0648\u0631\u0648\u062f \u0645\u0634\u062e\u0635 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b Login. \u0627\u06cc\u0646 \u0627\u0634\u062a\u0628\u0627\u0647\u0647:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">LoginActivity<br>\u2193<br>Api<br>\u2193<br>Room<br>\u2193<br>Preference<br>\u2193<br>Firebase<br>\u2193<br>Analytics<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u062c\u0627 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0647\u0645\u062f\u06cc\u06af\u0647 \u0631\u0648 \u0635\u062f\u0627 \u0645\u06cc\u0632\u0646\u0646. \u0628\u0647\u062a\u0631\u0647:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">LoginViewModel<br>\u2193<br>LoginUseCase<br>\u2193<br>Repositories<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u0686\u06cc\u0632 \u0627\u0632 \u06cc\u06a9 \u0646\u0642\u0637\u0647 \u0639\u0628\u0648\u0631 \u06a9\u0646\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Feature Flag<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0628\u0647\u062a\u0631\u06cc\u0646 \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc \u062a\u0648\u0633\u0639\u0647 \u0622\u06cc\u0646\u062f\u0647 Feature Flag\u0647\u0627 \u0647\u0633\u062a\u0646. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>if(featureFlags.newSearch)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\">(featureFlags.newSearch)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u062f\u0648\u0646 \u0627\u0646\u062a\u0634\u0627\u0631 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0645\u06cc\u0634\u0647 \u0642\u0627\u0628\u0644\u06cc\u062a \u0631\u0648 \u0631\u0648\u0634\u0646 \u06cc\u0627 \u062e\u0627\u0645\u0648\u0634 \u06a9\u0631\u062f. \u062d\u062a\u06cc \u0628\u0631\u0627\u06cc \u062f\u0631\u0635\u062f\u06cc \u0627\u0632 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0648\u0627\u0628\u0633\u062a\u06af\u06cc\u200c\u0647\u0627 \u0631\u0627 \u0642\u0627\u0628\u0644 \u062a\u0639\u0648\u06cc\u0636 \u0646\u06af\u0647 \u062f\u0627\u0631<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 Image Loader \u0639\u0648\u0636 \u0634\u062f&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0628\u0627\u06cc\u062f \u06a9\u0644 \u067e\u0631\u0648\u0698\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface ImageLoader {\n\n    suspend fun load(url:String)\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ImageLoader<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">suspend<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">load<\/span><span style=\"color: #24292E\">(url:<\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0631\u0648\u0632:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Coil\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u062f\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Glide\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u067e\u0633\u200c\u0641\u0631\u062f\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Picasso\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">UI \u0647\u06cc\u0686 \u062a\u063a\u06cc\u06cc\u0631\u06cc \u0646\u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0647\u0645\u06cc\u0634\u0647 \u0628\u0631\u0627\u06cc \u062d\u0630\u0641 \u0622\u0645\u0627\u062f\u0647 \u0628\u0627\u0634<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u06cc\u0634\u062a\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627 \u0641\u0642\u0637 \u0628\u0647 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0646 \u0641\u06a9\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646. \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u062d\u0630\u0641 Feature \u0647\u0645 \u0627\u062a\u0641\u0627\u0642 \u0645\u06cc\u0641\u062a\u0647. \u0627\u06af\u0631 \u062d\u0630\u0641 \u06cc\u06a9 \u0642\u0627\u0628\u0644\u06cc\u062a \u0628\u0627\u0639\u062b \u062e\u0631\u0627\u0628 \u0634\u062f\u0646 \u067e\u0646\u062c\u0627\u0647 \u06a9\u0644\u0627\u0633 \u0628\u0634\u0647\u060c \u06cc\u0639\u0646\u06cc \u0645\u0639\u0645\u0627\u0631\u06cc \u0645\u0634\u06a9\u0644 \u062f\u0627\u0631\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0645\u0633\u062a\u0646\u062f\u0633\u0627\u0632\u06cc \u0645\u0639\u0645\u0627\u0631\u06cc<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0642\u0631\u0627\u0631 \u0646\u06cc\u0633\u062a \u0641\u0642\u0637 \u06a9\u062f \u0628\u0646\u0648\u06cc\u0633\u06cc. \u0686\u0646\u062f \u0641\u0627\u06cc\u0644 \u0633\u0627\u062f\u0647 \u0627\u0631\u0632\u0634 \u0641\u0648\u0642\u200c\u0627\u0644\u0639\u0627\u062f\u0647\u200c\u0627\u06cc \u062f\u0627\u0631\u0646. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Architecture.md\n\nFolder Structure.md\n\nAPI Contract.md\n\nNavigation.md\n\nModules.md\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u062a\u06cc\u0645 \u0628\u0632\u0631\u06af \u0628\u0634\u0647\u060c \u0627\u06cc\u0646 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627 \u0627\u0632 \u0647\u0632\u0627\u0631\u0627\u0646 \u062e\u0637 \u06a9\u062f \u0627\u0631\u0632\u0634\u0645\u0646\u062f\u062a\u0631 \u0645\u06cc\u0634\u0646.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0627\u0632 God Object \u0641\u0631\u0627\u0631 \u06a9\u0646<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u062e\u0637\u0631\u0646\u0627\u06a9\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>AppManager\n\nApplicationManager\n\nDataManager\n\nSystemManager\n\nMainManager\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u062f\u0627\u062e\u0644\u0634\u0648\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Authentication\n\nNetwork\n\nDatabase\n\nPush\n\nCache\n\nPreference\n\nAnalytics\n\nLocation\n\nPermission\n\nNotification\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0686\u0646\u062f \u0647\u0632\u0627\u0631 \u062e\u0637 \u0645\u06cc\u0634\u0646. \u0647\u06cc\u0686 \u0645\u0633\u0626\u0648\u0644\u06cc\u062a \u0645\u0634\u062e\u0635\u06cc \u0647\u0645 \u0646\u062f\u0627\u0631\u0646.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Dependency Injection \u0622\u06cc\u0646\u062f\u0647 \u0631\u0627 \u0627\u0631\u0632\u0627\u0646 \u0645\u06cc\u200c\u06a9\u0646\u062f<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0627\u0645\u0631\u0648\u0632:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val repository =\n    ProductRepository()\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> repository <\/span><span style=\"color: #D73A49\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #6F42C1\">ProductRepository<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u062c\u0627 \u0627\u06cc\u0646 \u0631\u0648 \u0633\u0627\u062e\u062a\u06cc. \u0628\u0639\u062f\u0627\u064b: Repository \u067e\u0646\u062c \u0648\u0627\u0628\u0633\u062a\u06af\u06cc \u062c\u062f\u06cc\u062f \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u0647. \u062a\u0645\u0627\u0645 \u067e\u0631\u0648\u0698\u0647 \u0628\u0627\u06cc\u062f \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647. \u0627\u0645\u0627 \u0627\u06af\u0631 DI \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class ProductViewModel(\n\n    private val repository:\n        ProductRepository\n\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ProductViewModel<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> repository:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        ProductRepository<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0646\u0647\u0627 Container \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u06a9\u062f\u0647\u0627\u06cc \u0642\u0627\u0628\u0644 \u062d\u0630\u0641 \u0628\u0646\u0648\u06cc\u0633<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0639\u06cc\u0627\u0631\u0647\u0627\u06cc \u0645\u0639\u0645\u0627\u0631\u06cc \u062e\u0648\u0628 \u0627\u06cc\u0646\u0647:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0627\u0645\u0631\u0648\u0632 \u0627\u06cc\u0646 Feature \u062d\u0630\u0641 \u0628\u0634\u0647&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0686\u0646\u062f \u0641\u0627\u06cc\u0644 \u0628\u0627\u06cc\u062f \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0646\u061f \u0627\u06af\u0631 \u062c\u0648\u0627\u0628: 120 \u0641\u0627\u06cc\u0644 \u0628\u0627\u0634\u0647&#8230; \u06cc\u0639\u0646\u06cc Coupling \u062e\u06cc\u0644\u06cc \u0632\u06cc\u0627\u062f\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">YAGNI \u0631\u0627 \u0641\u0631\u0627\u0645\u0648\u0634 \u0646\u06a9\u0646<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0639\u0631\u0648\u0641\u200c\u062a\u0631\u06cc\u0646 \u0642\u0648\u0627\u0646\u06cc\u0646 \u0645\u0647\u0646\u062f\u0633\u06cc \u0646\u0631\u0645\u200c\u0627\u0641\u0632\u0627\u0631:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>You Aren't Gonna Need It\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0639\u0646\u06cc:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0686\u06cc\u0632\u06cc \u0631\u0648 \u0641\u0642\u0637 \u0648\u0642\u062a\u06cc \u0628\u0633\u0627\u0632 \u06a9\u0647 \u0648\u0627\u0642\u0639\u0627\u064b \u0628\u0647\u0634 \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u06cc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0647 \u0627\u06cc\u0646\u06a9\u0647 \u0634\u0627\u06cc\u062f \u062f\u0648 \u0633\u0627\u0644 \u0628\u0639\u062f \u0644\u0627\u0632\u0645 \u0628\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0642\u0627\u0646\u0648\u0646 \u062f\u0642\u06cc\u0642\u0627\u064b \u062a\u0639\u0627\u062f\u0644 \u0628\u06cc\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Future Design\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Over Engineering\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u0648 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u200c\u06a9\u0646\u0647.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0645\u0639\u0645\u0627\u0631\u06cc \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0628\u0639\u062f \u0627\u0632 \u06cc\u06a9 \u0633\u0627\u0644<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u062f\u0641 \u0645\u0627 \u0627\u06cc\u0646 \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0622\u06cc\u0646\u062f\u0647 \u0631\u0648 \u067e\u06cc\u0634\u200c\u0628\u06cc\u0646\u06cc \u06a9\u0646\u06cc\u0645. \u0647\u062f\u0641 \u0627\u06cc\u0646\u0647 \u06a9\u0647 \u0627\u06af\u0631 \u0641\u0631\u062f\u0627 \u0627\u06cc\u0646 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627 \u0627\u0636\u0627\u0641\u0647 \u0634\u062f\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Amazon\n\nTorob\n\nDigikala\n\nNotification Center\n\nAI Price Prediction\n\nWidget\n\nWear OS\n\nDesktop\n\nPublic API\n\nAdmin Panel\n\nEmail Notification\n\nSMS Notification\n\nCoupon System\n\nUser Ranking\n\nPrice History\n\nCharts\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0642\u0631\u0627\u0631 \u0646\u0628\u0627\u0634\u0647 \u06a9\u0644 \u067e\u0631\u0648\u0698\u0647 \u0631\u0648 \u0627\u0632 \u0627\u0648\u0644 \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0644\u06a9\u0647 \u0641\u0642\u0637 Feature \u062c\u062f\u06cc\u062f \u0631\u0648 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0686\u06a9\u200c\u0644\u06cc\u0633\u062a \u0637\u0631\u0627\u062d\u06cc \u0628\u0631\u0627\u06cc \u0622\u06cc\u0646\u062f\u0647<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0642\u0628\u0644 \u0627\u0632 \u0627\u06cc\u0646\u06a9\u0647 \u0647\u0631 Feature \u062c\u062f\u06cc\u062f \u0631\u0648 \u062f\u0627\u062e\u0644 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u060c \u0627\u06cc\u0646 \u0633\u0624\u0627\u0644\u200c\u0647\u0627 \u0631\u0648 \u0627\u0632 \u062e\u0648\u062f\u062a \u0628\u067e\u0631\u0633:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u0627\u06af\u0631 API \u0639\u0648\u0636 \u0628\u0634\u0647\u060c \u0686\u0646\u062f \u0641\u0627\u06cc\u0644 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646\u061f<\/li>\n\n\n\n<li>\u0627\u06af\u0631 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0647\u060c UI \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u0634\u0647\u061f<\/li>\n\n\n\n<li>\u0627\u06af\u0631 \u06cc\u06a9 Feature \u062d\u0630\u0641 \u0628\u0634\u0647\u060c \u0686\u0646\u062f \u0628\u062e\u0634 \u067e\u0631\u0648\u0698\u0647 \u0622\u0633\u06cc\u0628 \u0645\u06cc\u200c\u0628\u06cc\u0646\u0646\u061f<\/li>\n\n\n\n<li>\u0622\u06cc\u0627 \u0627\u06cc\u0646 \u06a9\u0644\u0627\u0633 \u0641\u0642\u0637 \u06cc\u06a9 \u0645\u0633\u0626\u0648\u0644\u06cc\u062a \u062f\u0627\u0631\u0647\u061f<\/li>\n\n\n\n<li>\u0622\u06cc\u0627 \u0648\u0627\u0628\u0633\u062a\u06af\u06cc\u200c\u0647\u0627 \u0627\u0632 \u0637\u0631\u06cc\u0642 Interface \u062a\u0639\u0631\u06cc\u0641 \u0634\u062f\u0646\u061f<\/li>\n\n\n\n<li>\u0622\u06cc\u0627 Feature \u062c\u062f\u06cc\u062f \u0628\u062f\u0648\u0646 \u062a\u063a\u06cc\u06cc\u0631 Feature\u0647\u0627\u06cc \u0642\u0628\u0644\u06cc \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u0634\u0647\u061f<\/li>\n\n\n\n<li>\u0622\u06cc\u0627 Configuration \u0627\u0632 \u06a9\u062f \u062c\u062f\u0627 \u0634\u062f\u0647\u061f<\/li>\n\n\n\n<li>\u0622\u06cc\u0627 Magic Number \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0647\u061f<\/li>\n\n\n\n<li>\u0622\u06cc\u0627 String\u0647\u0627\u06cc \u062b\u0627\u0628\u062a \u0628\u0627\u06cc\u062f Enum \u0628\u0627\u0634\u0646\u061f<\/li>\n\n\n\n<li>\u0622\u06cc\u0627 \u0642\u0631\u0627\u0631\u062f\u0627\u062f\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647 \u0646\u0633\u062e\u0647\u200c\u0628\u0646\u062f\u06cc \u0634\u062f\u0646\u061f<\/li>\n\n\n\n<li>\u0622\u06cc\u0627 Feature\u0647\u0627 \u0645\u0633\u062a\u0642\u0644 \u0627\u0632 \u0647\u0645 \u0647\u0633\u062a\u0646\u061f<\/li>\n\n\n\n<li>\u0622\u06cc\u0627 Utility \u063a\u0648\u0644\u200c\u067e\u06cc\u06a9\u0631 \u0633\u0627\u062e\u062a\u06cc\u061f<\/li>\n\n\n\n<li>\u0622\u06cc\u0627 \u0627\u06cc\u0646 \u067e\u06cc\u0686\u06cc\u062f\u06af\u06cc \u0648\u0627\u0642\u0639\u0627\u064b \u0644\u0627\u0632\u0645\u0647 \u06cc\u0627 \u0641\u0642\u0637 \u062d\u062f\u0633 \u0645\u06cc\u200c\u0632\u0646\u06cc \u0634\u0627\u06cc\u062f \u06cc\u06a9 \u0631\u0648\u0632 \u0644\u0627\u0632\u0645 \u0628\u0634\u0647\u061f<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0637\u0631\u0627\u062d\u06cc \u0628\u0631\u0627\u06cc \u062a\u0648\u0633\u0639\u0647 \u0622\u06cc\u0646\u062f\u0647 \u06cc\u0639\u0646\u06cc \u0627\u0645\u0631\u0648\u0632 \u0637\u0648\u0631\u06cc \u06a9\u062f \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645 \u06a9\u0647 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a \u0641\u0631\u062f\u0627 \u0627\u0631\u0632\u0627\u0646 \u0628\u0627\u0634\u0646\u060c \u0646\u0647 \u0627\u06cc\u0646\u06a9\u0647 \u0622\u06cc\u0646\u062f\u0647 \u0631\u0648 \u067e\u06cc\u0634\u200c\u0628\u06cc\u0646\u06cc \u06a9\u0646\u06cc\u0645. \u0645\u0639\u0645\u0627\u0631\u06cc \u062e\u0648\u0628 \u0642\u0631\u0627\u0631 \u0646\u06cc\u0633\u062a \u0647\u0645\u0647 \u0633\u0646\u0627\u0631\u06cc\u0648\u0647\u0627\u06cc \u0645\u0645\u06a9\u0646 \u0631\u0648 \u0627\u0632 \u0642\u0628\u0644 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u0647\u061b \u0642\u0631\u0627\u0631 \u0627\u0633\u062a \u062f\u0631 \u0628\u0631\u0627\u0628\u0631 \u062a\u063a\u06cc\u06cc\u0631 \u0627\u0646\u0639\u0637\u0627\u0641 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0647. \u0647\u0631\u0686\u0647 \u0648\u0627\u0628\u0633\u062a\u06af\u06cc \u0628\u06cc\u0646 \u0628\u062e\u0634\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u06a9\u0645\u062a\u0631 \u0628\u0627\u0634\u0647\u060c \u0647\u0631 Feature \u0645\u0633\u062a\u0642\u0644\u200c\u062a\u0631 \u0628\u0627\u0634\u0647 \u0648 \u0642\u0631\u0627\u0631\u062f\u0627\u062f\u0647\u0627 \u0634\u0641\u0627\u0641\u200c\u062a\u0631 \u062a\u0639\u0631\u06cc\u0641 \u0634\u062f\u0647 \u0628\u0627\u0634\u0646\u060c \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0646 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f \u0628\u0627 \u0631\u06cc\u0633\u06a9 \u0648 \u0647\u0632\u06cc\u0646\u0647 \u06a9\u0645\u062a\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u0634\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0647\u0645 \u0645\u0645\u06a9\u0646\u0647 \u0627\u0645\u0631\u0648\u0632 \u0641\u0642\u0637 \u0686\u0646\u062f \u0641\u0631\u0648\u0634\u06af\u0627\u0647\u060c \u0686\u0646\u062f \u0635\u0641\u062d\u0647 \u0648 \u0686\u0646\u062f API \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645\u060c \u0627\u0645\u0627 \u0627\u06af\u0631 \u0627\u0632 \u0647\u0645\u06cc\u0646 \u062d\u0627\u0644\u0627 \u0645\u0631\u0632 \u0628\u06cc\u0646 Feature\u0647\u0627\u060c Repository\u0647\u0627\u060c \u0642\u0631\u0627\u0631\u062f\u0627\u062f\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647 \u0648 \u0644\u0627\u06cc\u0647\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u067e\u0631\u0648\u0698\u0647 \u0631\u0648 \u062f\u0631\u0633\u062a \u0637\u0631\u0627\u062d\u06cc \u06a9\u0646\u06cc\u0645\u060c \u0627\u0636\u0627\u0641\u0647 \u0634\u062f\u0646 \u0641\u0631\u0648\u0634\u06af\u0627\u0647\u200c\u0647\u0627\u06cc \u062c\u062f\u06cc\u062f\u060c \u0633\u06cc\u0633\u062a\u0645 \u0627\u0639\u0644\u0627\u0646\u200c\u0647\u0627\u06cc \u067e\u06cc\u0634\u0631\u0641\u062a\u0647\u060c \u0646\u0633\u062e\u0647 iOS\u060c \u067e\u0646\u0644 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06cc\u0627 \u062d\u062a\u06cc \u0633\u0631\u0648\u06cc\u0633\u200c\u0647\u0627\u06cc \u0647\u0648\u0634 \u0645\u0635\u0646\u0648\u0639\u06cc\u060c \u0628\u0647 \u0645\u0639\u0646\u06cc \u0628\u0627\u0632\u0646\u0648\u06cc\u0633\u06cc \u06a9\u0644 \u067e\u0631\u0648\u0698\u0647 \u0646\u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f. \u0627\u06cc\u0646 \u062f\u0642\u06cc\u0642\u0627\u064b \u0627\u0631\u0632\u0634 \u0648\u0627\u0642\u0639\u06cc \u0645\u0639\u0645\u0627\u0631\u06cc\u0647\u061b <strong>\u06a9\u0645 \u06a9\u0631\u062f\u0646 \u0647\u0632\u06cc\u0646\u0647 \u062a\u063a\u06cc\u06cc\u0631\u060c \u0646\u0647 \u0632\u06cc\u0627\u062f \u06a9\u0631\u062f\u0646 \u062a\u0639\u062f\u0627\u062f \u06a9\u0644\u0627\u0633\u200c\u0647\u0627.<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-15-1024x683.avif\" alt=\"\" class=\"wp-image-6176\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-15-1024x683.avif 1024w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-15-300x200.avif 300w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-15-768x512.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-15.avif 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u200c\u0648\u0647\u0641\u062a\u0645<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">Logging \u0648 Crash Reporting (\u0628\u062e\u0634 \u0627\u0648\u0644)<\/h1>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"986\" height=\"1024\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-16-1-986x1024.avif\" alt=\"\" class=\"wp-image-6177\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-16-1-986x1024.avif 986w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-16-1-289x300.avif 289w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-16-1-768x798.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-16-1.avif 1230w\" sizes=\"(max-width: 986px) 100vw, 986px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u0627\u06cc\u0646\u062c\u0627 \u067e\u0631\u0648\u0698\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0628\u0647 \u06cc\u06a9 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0648\u0627\u0642\u0639\u06cc \u062a\u0628\u062f\u06cc\u0644 \u0634\u062f\u0647 \u0627\u0633\u062a. \u0627\u0632 Room \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f\u06cc\u0645\u060c \u0628\u0627 Retrofit \u0628\u0647 \u0633\u0631\u0648\u0631 \u0648\u0635\u0644 \u0634\u062f\u06cc\u0645\u060c WorkManager \u0646\u0648\u0634\u062a\u06cc\u0645\u060c Push Notification \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u06cc\u0645\u060c \u0645\u0639\u0645\u0627\u0631\u06cc MVVM \u0633\u0627\u062e\u062a\u06cc\u0645\u060c State\u0647\u0627 \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0631\u062f\u06cc\u0645 \u0648 \u0631\u0648\u06cc Performance \u0647\u0645 \u06a9\u0627\u0631 \u06a9\u0631\u062f\u06cc\u0645. \u0627\u0645\u0627 \u06cc\u06a9 \u0633\u0624\u0627\u0644 \u0645\u0647\u0645 \u0628\u0627\u0642\u06cc \u0645\u0627\u0646\u062f\u0647 \u0627\u0633\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0641\u0631\u062f\u0627 \u0647\u0645\u06cc\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u062f\u0631 Google Play \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u06cc \u0648 \u0647\u0632\u0627\u0631\u0627\u0646 \u0646\u0641\u0631 \u0622\u0646 \u0631\u0627 \u0646\u0635\u0628 \u06a9\u0646\u0646\u062f\u060c \u0627\u0632 \u06a9\u062c\u0627 \u0645\u06cc\u200c\u0641\u0647\u0645\u06cc \u062f\u0627\u062e\u0644 \u06af\u0648\u0634\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0686\u0647 \u0627\u062a\u0641\u0627\u0642\u06cc \u0645\u06cc\u200c\u0627\u0641\u062a\u062f\u061f<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u062e\u0648\u062f\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u060c Android Studio \u0628\u0627\u0632 \u0627\u0633\u062a\u060c Logcat \u0631\u0627 \u0645\u06cc\u200c\u0628\u06cc\u0646\u06cc \u0648 \u0627\u06af\u0631 \u062e\u0637\u0627\u06cc\u06cc \u0631\u062e \u0628\u062f\u0647\u062f\u060c Stack Trace \u062c\u0644\u0648\u06cc \u0686\u0634\u0645\u062a \u0638\u0627\u0647\u0631 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0627\u0645\u0627 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 Android Studio \u0646\u062f\u0627\u0631\u0646\u062f. \u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0622\u0646\u200c\u0647\u0627 \u062e\u0631\u0627\u0628 \u0634\u0648\u062f\u060c \u062a\u0648 \u0647\u06cc\u0686 \u0686\u06cc\u0632\u06cc \u0646\u0645\u06cc\u200c\u0628\u06cc\u0646\u06cc. \u062a\u0646\u0647\u0627 \u0686\u06cc\u0632\u06cc \u06a9\u0647 \u0634\u0627\u06cc\u062f \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u06cc\u060c \u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u06a9\u0648\u062a\u0627\u0647 \u0628\u0627\u0634\u062f: \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0633\u062a\u0647 \u0634\u062f. \u0647\u0645\u06cc\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u0647 \u0645\u06cc\u200c\u062f\u0627\u0646\u06cc \u06a9\u0627\u0631\u0628\u0631 \u062f\u0627\u062e\u0644 \u06a9\u062f\u0627\u0645 \u0635\u0641\u062d\u0647 \u0628\u0648\u062f\u0647\u060c \u0646\u0647 \u0645\u06cc\u200c\u062f\u0627\u0646\u06cc \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u062f\u0627\u0634\u062a\u0647 \u06cc\u0627 \u0646\u0647\u060c \u0646\u0647 \u0645\u062f\u0644 \u06af\u0648\u0634\u06cc \u0631\u0627 \u0645\u06cc\u200c\u062f\u0627\u0646\u06cc\u060c \u0646\u0647 \u0646\u0633\u062e\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0631\u0627\u060c \u0646\u0647 \u0622\u062e\u0631\u06cc\u0646 \u0639\u0645\u0644\u06cc \u06a9\u0647 \u0627\u0646\u062c\u0627\u0645 \u062f\u0627\u062f\u0647 \u0627\u0633\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644\u060c \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u062a\u0641\u0627\u0648\u062a\u200c\u0647\u0627\u06cc \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0622\u0645\u0648\u0632\u0634\u06cc \u0628\u0627 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 Production \u0647\u0645\u06cc\u0646 Logging \u0648 Crash Reporting \u0627\u0633\u062a. \u0628\u0631\u0646\u0627\u0645\u0647 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0641\u0642\u0637 \u06a9\u062f\u06cc \u0646\u06cc\u0633\u062a \u06a9\u0647 \u062f\u0631\u0633\u062a \u06a9\u0627\u0631 \u06a9\u0646\u062f\u061b \u0628\u0631\u0646\u0627\u0645\u0647 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0628\u0627\u06cc\u062f \u0648\u0642\u062a\u06cc \u0645\u0634\u06a9\u0644\u06cc \u0647\u0645 \u067e\u06cc\u0634 \u0622\u0645\u062f\u060c \u0628\u062a\u0648\u0627\u0646\u062f \u0622\u0646 \u0645\u0634\u06a9\u0644 \u0631\u0627 \u0628\u0631\u0627\u06cc \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u062a\u0648\u0636\u06cc\u062d \u0628\u062f\u0647\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u062f\u0648\u0646 Logging \u0645\u062b\u0644 \u0631\u0627\u0646\u0646\u062f\u06af\u06cc \u062f\u0631 \u0634\u0628 \u0628\u062f\u0648\u0646 \u0686\u0631\u0627\u063a \u0627\u0633\u062a<\/h1>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-17-1-1024x683.avif\" alt=\"\" class=\"wp-image-6178\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-17-1-1024x683.avif 1024w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-17-1-300x200.avif 300w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-17-1-768x512.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-17-1.avif 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0634\u0628 \u062f\u0631 \u06cc\u06a9 \u062c\u0627\u062f\u0647 \u0646\u0627\u0634\u0646\u0627\u0633 \u0631\u0627\u0646\u0646\u062f\u06af\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc \u0648 \u0686\u0631\u0627\u063a\u200c\u0647\u0627\u06cc \u0645\u0627\u0634\u06cc\u0646 \u062e\u0627\u0645\u0648\u0634 \u0647\u0633\u062a\u0646\u062f. \u0627\u062d\u062a\u0645\u0627\u0644\u0627\u064b \u0686\u0646\u062f \u0645\u062a\u0631 \u0627\u0648\u0644 \u0631\u0627 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc \u0628\u0631\u0648\u06cc\u060c \u0627\u0645\u0627 \u062f\u06cc\u0631 \u06cc\u0627 \u0632\u0648\u062f \u0628\u0647 \u0645\u0627\u0646\u0639\u06cc \u0628\u0631\u062e\u0648\u0631\u062f \u0645\u06cc\u200c\u06a9\u0646\u06cc. \u062d\u0627\u0644\u0627 \u0641\u0631\u0636 \u06a9\u0646 \u0647\u0645\u0627\u0646 \u0645\u0633\u06cc\u0631 \u0631\u0627 \u0628\u0627 \u0686\u0631\u0627\u063a \u0631\u0648\u0634\u0646 \u0637\u06cc \u06a9\u0646\u06cc. \u062c\u0627\u062f\u0647 \u0647\u0645\u0627\u0646 \u062c\u0627\u062f\u0647 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u062d\u0627\u0644\u0627 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc \u0628\u0628\u06cc\u0646\u06cc \u0686\u0647 \u0627\u062a\u0641\u0627\u0642\u06cc \u062c\u0644\u0648\u06cc\u062a \u062f\u0631 \u062d\u0627\u0644 \u0631\u062e \u062f\u0627\u062f\u0646 \u0627\u0633\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Logging \u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u06cc\u0646 \u0686\u0631\u0627\u063a \u0627\u0633\u062a. \u0642\u0631\u0627\u0631 \u0646\u06cc\u0633\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u06a9\u0646\u062f. \u0642\u0631\u0627\u0631 \u0646\u06cc\u0633\u062a \u0642\u0627\u0628\u0644\u06cc\u062a \u062c\u062f\u06cc\u062f\u06cc \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u062f. \u0642\u0631\u0627\u0631 \u0627\u0633\u062a <strong>\u0627\u062a\u0641\u0627\u0642\u0627\u062a \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0642\u0627\u0628\u0644 \u0645\u0634\u0627\u0647\u062f\u0647 \u06a9\u0646\u062f.<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Logging \u0686\u06cc\u0633\u062a\u061f<\/h1>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-18-1-1024x683.avif\" alt=\"\" class=\"wp-image-6179\" srcset=\"https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-18-1-1024x683.avif 1024w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-18-1-300x200.avif 300w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-18-1-768x512.avif 768w, https:\/\/notes.yummybrands.studio\/wp-content\/uploads\/2026\/07\/Android-Learning-18-1.avif 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0632\u0628\u0627\u0646 \u0633\u0627\u062f\u0647\u060c Logging \u06cc\u0639\u0646\u06cc \u062b\u0628\u062a \u06a9\u0631\u062f\u0646 \u0627\u062a\u0641\u0627\u0642\u0627\u062a\u06cc \u06a9\u0647 \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062e \u0645\u06cc\u200c\u062f\u0647\u0646\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u06a9\u0627\u0631\u0628\u0631 \u0648\u0627\u0631\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0634\u062f.<\/li>\n\n\n\n<li>\u062f\u0631\u062e\u0648\u0627\u0633\u062a API \u0627\u0631\u0633\u0627\u0644 \u0634\u062f.<\/li>\n\n\n\n<li>\u067e\u0627\u0633\u062e \u0633\u0631\u0648\u0631 \u062f\u0631\u06cc\u0627\u0641\u062a \u0634\u062f.<\/li>\n\n\n\n<li>\u062f\u0627\u0646\u0644\u0648\u062f \u062a\u0635\u0648\u06cc\u0631 \u0634\u0631\u0648\u0639 \u0634\u062f.<\/li>\n\n\n\n<li>\u062f\u0627\u0646\u0644\u0648\u062f \u062a\u0635\u0648\u06cc\u0631 \u062a\u0645\u0627\u0645 \u0634\u062f.<\/li>\n\n\n\n<li>\u06a9\u0627\u0631\u0628\u0631 \u0645\u062d\u0635\u0648\u0644\u06cc \u0631\u0627 \u062d\u0630\u0641 \u06a9\u0631\u062f.<\/li>\n\n\n\n<li>\u062e\u0637\u0627\u06cc\u06cc \u0631\u062e \u062f\u0627\u062f.<\/li>\n\n\n\n<li>Worker \u0627\u062c\u0631\u0627 \u0634\u062f.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 \u0627\u06cc\u0646 \u0627\u062a\u0641\u0627\u0642\u200c\u0647\u0627 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0646\u062f \u062b\u0628\u062a \u0634\u0648\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0627\u0648\u0644\u06cc\u0646 \u0627\u0634\u062a\u0628\u0627\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0645\u0647 \u0645\u0627 \u062f\u0631 \u0627\u0628\u062a\u062f\u0627\u06cc \u06a9\u0627\u0631 Logging \u0631\u0627 \u0627\u06cc\u0646 \u0634\u06a9\u0644\u06cc \u06cc\u0627\u062f \u06af\u0631\u0641\u062a\u0647\u200c\u0627\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Log.d(\"TAG\", \"Button Clicked\")\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;TAG&quot;<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #032F62\">&quot;Button Clicked&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Log.d(\"API\", response.body().toString())\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;API&quot;<\/span><span style=\"color: #24292E\">, response.<\/span><span style=\"color: #6F42C1\">body<\/span><span style=\"color: #24292E\">().<\/span><span style=\"color: #6F42C1\">toString<\/span><span style=\"color: #24292E\">())<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627 \u062d\u062a\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>println(\"Success\")\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6F42C1\">println<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;Success&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06a9\u062f\u0647\u0627 \u0628\u0631\u0627\u06cc \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0622\u0645\u0648\u0632\u0634\u06cc \u0628\u062f \u0646\u06cc\u0633\u062a\u0646\u062f. \u0627\u0645\u0627 \u0627\u06af\u0631 \u0647\u0645\u06cc\u0646 \u0631\u0648\u0634 \u0631\u0627 \u062f\u0627\u062e\u0644 \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647 \u0628\u0632\u0631\u06af \u0627\u062f\u0627\u0645\u0647 \u0628\u062f\u0647\u06cc\u060c \u0628\u0639\u062f \u0627\u0632 \u0686\u0646\u062f \u0645\u0627\u0647 \u0635\u062f\u0647\u0627 Log \u062e\u0648\u0627\u0647\u06cc \u062f\u0627\u0634\u062a \u06a9\u0647 \u0647\u06cc\u0686 \u0627\u0631\u0632\u0634\u06cc \u0646\u062f\u0627\u0631\u0646\u062f. \u0645\u062b\u0644\u0627\u064b Logcat \u0686\u06cc\u0632\u06cc \u0634\u0628\u06cc\u0647 \u0627\u06cc\u0646 \u0645\u06cc\u200c\u0634\u0648\u062f:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Done\n\nClicked\n\nSuccess\n\nAPI Success\n\nError\n\nLoading\n\nLoading Finished\n\nResponse Received\n\nClicked Again\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 Log\u0647\u0627 \u0647\u06cc\u0686 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0641\u06cc\u062f\u06cc \u0628\u0647 \u062a\u0648 \u0646\u0645\u06cc\u200c\u062f\u0647\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u06cc\u06a9 Log \u062e\u0648\u0628 \u0686\u0647 \u0648\u06cc\u0698\u06af\u06cc\u200c\u0647\u0627\u06cc\u06cc \u062f\u0627\u0631\u062f\u061f<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u06a9\u0627\u0631\u0628\u0631\u06cc \u06af\u0632\u0627\u0631\u0634 \u062f\u0627\u062f\u0647 \u06a9\u0647 \u0647\u0646\u06af\u0627\u0645 \u062b\u0628\u062a \u0645\u062d\u0635\u0648\u0644\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u062e\u0637\u0627 \u0645\u06cc\u200c\u062f\u0647\u062f. \u06a9\u062f\u0627\u0645 Log \u0645\u0641\u06cc\u062f\u062a\u0631 \u0627\u0633\u062a\u061f<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Error\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Failed to save product\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Save Product Failed\n\nProductId = 281\n\nUserId = 54\n\nDatabase = Room\n\nReason = Duplicate Primary Key\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0627\u0636\u062d \u0627\u0633\u062a \u06a9\u0647 \u0645\u0648\u0631\u062f \u0633\u0648\u0645 \u0627\u0631\u0632\u0634 \u0648\u0627\u0642\u0639\u06cc \u062f\u0627\u0631\u062f. \u06cc\u06a9 Log \u062e\u0648\u0628 \u0628\u0627\u06cc\u062f \u0628\u062a\u0648\u0627\u0646\u062f \u0628\u0647 \u0627\u06cc\u0646 \u0633\u0624\u0627\u0644\u200c\u0647\u0627 \u067e\u0627\u0633\u062e \u0628\u062f\u0647\u062f:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u0686\u0647 \u0627\u062a\u0641\u0627\u0642\u06cc \u0627\u0641\u062a\u0627\u062f\u061f<\/li>\n\n\n\n<li>\u06a9\u062c\u0627 \u0627\u062a\u0641\u0627\u0642 \u0627\u0641\u062a\u0627\u062f\u061f<\/li>\n\n\n\n<li>\u0628\u0631\u0627\u06cc \u0686\u0647 \u06a9\u0633\u06cc \u0627\u062a\u0641\u0627\u0642 \u0627\u0641\u062a\u0627\u062f\u061f<\/li>\n\n\n\n<li>\u0686\u0631\u0627 \u0627\u062a\u0641\u0627\u0642 \u0627\u0641\u062a\u0627\u062f\u061f<\/li>\n\n\n\n<li>\u0646\u062a\u06cc\u062c\u0647 \u0686\u0647 \u0628\u0648\u062f\u061f<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Logging \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u062e\u0637\u0627 \u0646\u06cc\u0633\u062a<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0641\u06a9\u0631 \u06a9\u0646\u06cc\u0645 \u0641\u0642\u0637 \u0647\u0646\u06af\u0627\u0645 Exception \u0628\u0627\u06cc\u062f Log \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645. \u062f\u0631 \u0648\u0627\u0642\u0639 Logging \u0686\u0647\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631\u062f \u0627\u0635\u0644\u06cc \u062f\u0627\u0631\u062f.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u06f1. \u0628\u0631\u0631\u0633\u06cc \u0631\u0641\u062a\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0628\u0628\u06cc\u0646\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0648\u0627\u0642\u0639\u0627\u064b \u0648\u0627\u0631\u062f \u0635\u0641\u062d\u0647 \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0642\u06cc\u0645\u062a \u0634\u062f\u0647 \u06cc\u0627 \u0646\u0647.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Navigate -&gt; PriceHistory\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u06f2. \u0628\u0631\u0631\u0633\u06cc \u0639\u0645\u0644\u06a9\u0631\u062f<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0628\u0628\u06cc\u0646\u06cc \u062f\u0627\u0646\u0644\u0648\u062f \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0686\u0646\u062f \u0645\u06cc\u0644\u06cc\u200c\u062b\u0627\u0646\u06cc\u0647 \u0637\u0648\u0644 \u06a9\u0634\u06cc\u062f\u0647 \u0627\u0633\u062a.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Products Loaded\n\nTime = 482 ms\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u06f3. \u0628\u0631\u0631\u0633\u06cc \u062e\u0637\u0627<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u062f\u0631\u062e\u0648\u0627\u0633\u062a API \u0634\u06a9\u0633\u062a \u062e\u0648\u0631\u062f\u0647 \u0627\u0633\u062a.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Network Request Failed\n\nCode = 500\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u06f4. \u062a\u062d\u0644\u06cc\u0644 \u0631\u0641\u062a\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0628\u0641\u0647\u0645\u06cc \u0628\u06cc\u0634\u062a\u0631 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0627\u0632 \u06a9\u062f\u0627\u0645 \u0642\u0627\u0628\u0644\u06cc\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Search Executed\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0627\u0646\u0648\u0627\u0639 Log<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u067e\u0646\u062c \u0633\u0637\u062d \u0627\u0635\u0644\u06cc \u0628\u0631\u0627\u06cc Log \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verbose<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u06cc\u0632\u062a\u0631\u06cc\u0646 \u0633\u0637\u062d Log \u0627\u0633\u062a. \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0647\u0646\u06af\u0627\u0645 Debug \u06a9\u0631\u062f\u0646 \u0628\u062e\u0634 \u062e\u0627\u0635\u06cc \u0627\u0632 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>RecyclerView Item Created\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Debug<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0631\u0627\u06cc\u062c\u200c\u062a\u0631\u06cc\u0646 \u0646\u0648\u0639 Log. \u0628\u0631\u0627\u06cc \u062a\u0648\u0633\u0639\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>User Loaded From Room\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Info<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u06cc\u06a9 \u0627\u062a\u0641\u0627\u0642 \u0645\u0647\u0645 \u0648\u0644\u06cc \u0637\u0628\u06cc\u0639\u06cc \u0631\u062e \u062f\u0627\u062f\u0647 \u0627\u0633\u062a. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>User Logged In Successfully\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Warning<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0646\u0648\u0632 \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0627\u0645\u0627 \u06cc\u06a9 \u0648\u0636\u0639\u06cc\u062a \u063a\u06cc\u0631\u0639\u0627\u062f\u06cc \u0631\u062e \u062f\u0627\u062f\u0647 \u0627\u0633\u062a. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Image Not Found\n\nUsing Placeholder\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Error<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u062a\u0648\u0627\u0646\u0633\u062a\u0647 \u06a9\u0627\u0631\u06cc \u0631\u0627 \u0627\u0646\u062c\u0627\u0645 \u062f\u0647\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Database Insert Failed\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0622\u06cc\u0627 \u0628\u0627\u06cc\u062f \u0647\u0645\u0647 \u062c\u0627 Log \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645\u061f<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u06cc\u0631. \u0627\u06cc\u0646 \u06cc\u06a9\u06cc \u0627\u0632 \u0628\u062f\u062a\u0631\u06cc\u0646 \u06a9\u0627\u0631\u0647\u0627\u06cc\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646 \u0627\u0646\u062c\u0627\u0645 \u062f\u0627\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun addProduct(product: Product) {\n\n    Log.d(\"APP\",\"Step 1\")\n\n    Log.d(\"APP\",\"Step 2\")\n\n    Log.d(\"APP\",\"Step 3\")\n\n    Log.d(\"APP\",\"Step 4\")\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">addProduct<\/span><span style=\"color: #24292E\">(product: <\/span><span style=\"color: #6F42C1\">Product<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;APP&quot;<\/span><span style=\"color: #24292E\">,<\/span><span style=\"color: #032F62\">&quot;Step 1&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;APP&quot;<\/span><span style=\"color: #24292E\">,<\/span><span style=\"color: #032F62\">&quot;Step 2&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;APP&quot;<\/span><span style=\"color: #24292E\">,<\/span><span style=\"color: #032F62\">&quot;Step 3&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;APP&quot;<\/span><span style=\"color: #24292E\">,<\/span><span style=\"color: #032F62\">&quot;Step 4&quot;<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06a9\u062f \u0641\u0642\u0637 Logcat \u0631\u0627 \u0634\u0644\u0648\u063a \u0645\u06cc\u200c\u06a9\u0646\u062f. \u0628\u0647 \u062c\u0627\u06cc \u0622\u0646 \u0628\u0627\u06cc\u062f \u0641\u0642\u0637 \u0627\u062a\u0641\u0627\u0642\u200c\u0647\u0627\u06cc \u0645\u0647\u0645 \u062b\u0628\u062a \u0634\u0648\u0646\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Log.i(\n    \"ProductRepository\",\n    \"Saving Product ${product.id}\"\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Log.<\/span><span style=\"color: #6F42C1\">i<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;ProductRepository&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Saving Product ${product.id}&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Log.e(\n    \"Network\",\n    \"Request Failed\"\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Log.<\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Network&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Request Failed&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0645\u0634\u06a9\u0644 \u0628\u0632\u0631\u06af \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0627\u0632 Log<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u062f\u0631 \u06a9\u0644 \u067e\u0631\u0648\u0698\u0647 \u06f1\u06f8\u06f0\u06f0 \u0628\u0627\u0631 \u0627\u06cc\u0646 \u06a9\u062f \u0631\u0627 \u0646\u0648\u0634\u062a\u0647\u200c\u0627\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Log.d(...)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #D73A49\">..<\/span><span style=\"color: #24292E\">.)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0634\u0634 \u0645\u0627\u0647 \u0628\u0639\u062f \u062a\u0635\u0645\u06cc\u0645 \u0645\u06cc\u200c\u06af\u06cc\u0631\u06cc \u062f\u06cc\u06af\u0631 \u0627\u0632 Logcat \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u06a9\u0646\u06cc \u0648 \u0647\u0645\u0647 Log\u0647\u0627 \u0631\u0627 \u0628\u0647 Crashlytics \u0628\u0641\u0631\u0633\u062a\u06cc. \u0686\u0647 \u0627\u062a\u0641\u0627\u0642\u06cc \u0645\u06cc\u200c\u0627\u0641\u062a\u062f\u061f \u0628\u0627\u06cc\u062f \u06f1\u06f8\u06f0\u06f0 \u0641\u0627\u06cc\u0644 \u0631\u0627 \u0648\u06cc\u0631\u0627\u06cc\u0634 \u06a9\u0646\u06cc. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u06cc\u0686\u200c\u0648\u0642\u062a \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0627\u0632 Log \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u0645\u06cc\u200c\u06a9\u0646\u0646\u062f. \u0622\u0646\u200c\u0647\u0627 \u06cc\u06a9 \u0644\u0627\u06cc\u0647 \u0648\u0627\u0633\u0637 \u0645\u06cc\u200c\u0633\u0627\u0632\u0646\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>interface Logger {\n\n    fun d(tag: String, message: String)\n\n    fun i(tag: String, message: String)\n\n    fun w(tag: String, message: String)\n\n    fun e(\n        tag: String,\n        message: String,\n        throwable: Throwable? = null\n    )\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">interface<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Logger<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">, message: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">i<\/span><span style=\"color: #24292E\">(tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">, message: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">w<\/span><span style=\"color: #24292E\">(tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">, message: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        message: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        throwable: <\/span><span style=\"color: #6F42C1\">Throwable<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647 \u062c\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Log.d(...)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #D73A49\">..<\/span><span style=\"color: #24292E\">.)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u06cc\u200c\u0646\u0648\u06cc\u0633\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>logger.d(\n    \"Repository\",\n    \"Loading Products\"\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">logger.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Repository&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Loading Products&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0646\u06af\u0627\u0647 \u0627\u0648\u0644 \u062a\u0641\u0627\u0648\u062a \u0632\u06cc\u0627\u062f\u06cc \u0646\u062f\u0627\u0631\u062f. \u0627\u0645\u0627 \u062d\u0627\u0644\u0627 \u06a9\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0641\u0642\u0637 Logger \u0631\u0627 \u0645\u06cc\u200c\u0634\u0646\u0627\u0633\u062f. \u0646\u0647 Logcat \u0631\u0627. \u0646\u0647 Timber \u0631\u0627. \u0646\u0647 Crashlytics \u0631\u0627. \u0627\u06af\u0631 \u0641\u0631\u062f\u0627 \u062a\u0635\u0645\u06cc\u0645 \u0628\u06af\u06cc\u0631\u06cc Logger \u0631\u0627 \u0639\u0648\u0636 \u06a9\u0646\u06cc\u060c \u0641\u0642\u0637 \u06cc\u06a9 \u06a9\u0644\u0627\u0633 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u0628\u0642\u06cc\u0647 \u067e\u0631\u0648\u0698\u0647 \u0628\u062f\u0648\u0646 \u0647\u06cc\u0686 \u062a\u063a\u06cc\u06cc\u0631\u06cc \u0628\u0647 \u06a9\u0627\u0631\u0634 \u0627\u062f\u0627\u0645\u0647 \u0645\u06cc\u200c\u062f\u0647\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u0627\u0646 \u0627\u0635\u0644 \u0645\u0647\u0645\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0628\u0627\u0631\u0647\u0627 \u062f\u0631 \u0641\u0635\u0644\u200c\u0647\u0627\u06cc \u0642\u0628\u0644 \u062f\u0631\u0628\u0627\u0631\u0647 \u0622\u0646 \u0635\u062d\u0628\u062a \u06a9\u0631\u062f\u06cc\u0645: <strong>\u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u0628\u0627\u06cc\u062f \u0628\u0647 \u0627\u0646\u062a\u0632\u0627\u0639 (Interface) \u0648\u0627\u0628\u0633\u062a\u0647 \u0628\u0627\u0634\u0646\u062f\u060c \u0646\u0647 \u0628\u0647 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc.<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc AndroidLogger<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0627\u0648\u0644\u06cc\u0646 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc Logger \u0631\u0627 \u0645\u06cc\u200c\u0646\u0648\u06cc\u0633\u06cc\u0645.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class AndroidLogger : Logger {\n\n    override fun d(\n        tag: String,\n        message: String\n    ) {\n        Log.d(tag, message)\n    }\n\n    override fun i(\n        tag: String,\n        message: String\n    ) {\n        Log.i(tag, message)\n    }\n\n    override fun w(\n        tag: String,\n        message: String\n    ) {\n        Log.w(tag, message)\n    }\n\n    override fun e(\n        tag: String,\n        message: String,\n        throwable: Throwable?\n    ) {\n        Log.e(tag, message, throwable)\n    }\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">AndroidLogger<\/span><span style=\"color: #24292E\"> : <\/span><span style=\"color: #6F42C1\">Logger<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        message: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(tag, message)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">i<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        message: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Log.<\/span><span style=\"color: #6F42C1\">i<\/span><span style=\"color: #24292E\">(tag, message)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">w<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        message: <\/span><span style=\"color: #6F42C1\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Log.<\/span><span style=\"color: #6F42C1\">w<\/span><span style=\"color: #24292E\">(tag, message)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        message: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        throwable: <\/span><span style=\"color: #6F42C1\">Throwable<\/span><span style=\"color: #24292E\">?<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    ) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        Log.<\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(tag, message, throwable)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0632 \u0627\u06cc\u0646 \u0644\u062d\u0638\u0647 \u0628\u0647 \u0628\u0639\u062f \u0647\u06cc\u0686 \u06a9\u0644\u0627\u0633 \u062f\u06cc\u06af\u0631\u06cc \u0646\u0628\u0627\u06cc\u062f \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b <code>Log.d<\/code> \u06cc\u0627 <code>Log.e<\/code> \u0631\u0627 \u0635\u062f\u0627 \u0628\u0632\u0646\u062f. \u0647\u0645\u0647 \u06a9\u0644\u0627\u0633\u200c\u0647\u0627 \u0641\u0642\u0637 \u0628\u0627 <code>Logger<\/code> \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0686\u0631\u0627 \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0627\u0631\u0632\u0634 \u062f\u0627\u0631\u062f\u061f<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0641\u0631\u062f\u0627 \u0628\u062e\u0648\u0627\u0647\u06cc\u0645 \u0627\u0632 Timber \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645. \u0641\u0642\u0637 \u0647\u0645\u06cc\u0646 \u06a9\u0644\u0627\u0633 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f. \u06cc\u0627 \u0627\u06af\u0631 \u0628\u062e\u0648\u0627\u0647\u06cc\u0645 \u062a\u0645\u0627\u0645 Error\u0647\u0627 \u0631\u0627 \u0639\u0644\u0627\u0648\u0647 \u0628\u0631 Logcat \u0628\u0647 Firebase Crashlytics \u0647\u0645 \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u06cc\u0645\u060c \u0628\u0627\u0632 \u0647\u0645 \u0641\u0642\u0637 \u0647\u0645\u06cc\u0646 \u06a9\u0644\u0627\u0633 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f. Repository\u060c ViewModel\u060c Worker\u060c Service \u0648 \u0628\u0642\u06cc\u0647 \u0642\u0633\u0645\u062a\u200c\u0647\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062d\u062a\u06cc \u0645\u062a\u0648\u062c\u0647 \u0627\u06cc\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u0646\u0645\u06cc\u200c\u0634\u0648\u0646\u062f. \u0627\u06cc\u0646 \u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u0627\u0646 \u0645\u0639\u0645\u0627\u0631\u06cc\u200c\u0627\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0628\u0627\u0639\u062b \u0645\u06cc\u200c\u0634\u0648\u062f \u067e\u0631\u0648\u0698\u0647 \u0628\u0639\u062f \u0627\u0632 \u062f\u0648 \u06cc\u0627 \u0633\u0647 \u0633\u0627\u0644 \u0647\u0645 \u0642\u0627\u0628\u0644 \u0646\u06af\u0647\u062f\u0627\u0631\u06cc \u0628\u0627\u0642\u06cc \u0628\u0645\u0627\u0646\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc \u0628\u062e\u0634 \u0627\u0648\u0644<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0628\u062e\u0634 \u06cc\u0627\u062f \u06af\u0631\u0641\u062a\u06cc\u0645 \u06a9\u0647 Logging \u0641\u0642\u0637 \u0686\u0627\u067e \u0686\u0646\u062f \u0645\u062a\u0646 \u062f\u0627\u062e\u0644 Logcat \u0646\u06cc\u0633\u062a\u060c \u0628\u0644\u06a9\u0647 \u0628\u062e\u0634\u06cc \u0627\u0632 \u0645\u0639\u0645\u0627\u0631\u06cc \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 Production \u0627\u0633\u062a. \u062f\u06cc\u062f\u06cc\u0645 \u06a9\u0647 \u06cc\u06a9 Log \u062e\u0648\u0628 \u0628\u0627\u06cc\u062f \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0641\u06cc\u062f\u06cc \u062f\u0631\u0628\u0627\u0631\u0647 \u0627\u062a\u0641\u0627\u0642\u0627\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u062b\u0628\u062a \u06a9\u0646\u062f\u060c \u0646\u0647 \u0627\u06cc\u0646\u06a9\u0647 \u0641\u0642\u0637 \u0686\u0646\u062f \u06a9\u0644\u0645\u0647 \u0645\u0628\u0647\u0645 \u0686\u0627\u067e \u06a9\u0646\u062f. \u0647\u0645\u0686\u0646\u06cc\u0646 \u0641\u0647\u0645\u06cc\u062f\u06cc\u0645 \u0648\u0627\u0628\u0633\u062a\u0647 \u06a9\u0631\u062f\u0646 \u06a9\u0644 \u067e\u0631\u0648\u0698\u0647 \u0628\u0647 \u06a9\u0644\u0627\u0633 <code>Log<\/code> \u062a\u0635\u0645\u06cc\u0645 \u062f\u0631\u0633\u062a\u06cc \u0646\u06cc\u0633\u062a \u0648 \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0627\u0632 \u06cc\u06a9 Interface \u0645\u0627\u0646\u0646\u062f <code>Logger<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645 \u062a\u0627 \u0628\u0639\u062f\u0647\u0627 \u0628\u062a\u0648\u0627\u0646\u06cc\u0645 \u0628\u062f\u0648\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0644 \u067e\u0631\u0648\u0698\u0647\u060c \u0631\u0648\u0634 \u062b\u0628\u062a Log \u0631\u0627 \u0639\u0648\u0636 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 <strong>\u0628\u062e\u0634 \u062f\u0648\u0645<\/strong>\u060c Logger \u0631\u0627 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc\u200c\u062a\u0631 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645\u060c \u0628\u0627 <strong>Timber<\/strong> \u0622\u0634\u0646\u0627 \u0645\u06cc\u200c\u0634\u0648\u06cc\u0645\u060c \u06cc\u0627\u062f \u0645\u06cc\u200c\u06af\u06cc\u0631\u06cc\u0645 \u0686\u06af\u0648\u0646\u0647 Log\u0647\u0627\u06cc \u0633\u0627\u062e\u062a\u0627\u0631\u06cc\u0627\u0641\u062a\u0647 (Structured Logging) \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645\u060c Performance \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc \u06a9\u0646\u06cc\u0645 \u0648 Logging \u0634\u0628\u06a9\u0647 (Network Logging) \u0631\u0627 \u0628\u0647 \u0634\u06a9\u0644\u06cc \u0627\u0645\u0646 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u200c\u0648\u0647\u0641\u062a\u0645<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">Logging \u0648 Crash Reporting (\u0628\u062e\u0634 \u062f\u0648\u0645)<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0628\u062e\u0634 \u0642\u0628\u0644 \u0641\u0647\u0645\u06cc\u062f\u06cc\u0645 \u06a9\u0647 Logging \u0641\u0642\u0637 \u0686\u0646\u062f \u062a\u0627 <code>Log.d<\/code> \u0646\u06cc\u0633\u062a\u060c \u0628\u0644\u06a9\u0647 \u0628\u062e\u0634\u06cc \u0627\u0632 \u0645\u0639\u0645\u0627\u0631\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0633\u062a. \u0647\u0645\u0686\u0646\u06cc\u0646 \u06cc\u06a9 Interface \u0628\u0647 \u0646\u0627\u0645 <code>Logger<\/code> \u0633\u0627\u062e\u062a\u06cc\u0645 \u062a\u0627 \u06a9\u0644 \u067e\u0631\u0648\u0698\u0647 \u0628\u0647 \u062c\u0627\u06cc \u0648\u0627\u0628\u0633\u062a\u0647 \u0634\u062f\u0646 \u0628\u0647 \u06a9\u0644\u0627\u0633 <code>Log<\/code>\u060c \u0641\u0642\u0637 \u0628\u0627 \u06cc\u06a9 \u0627\u0646\u062a\u0632\u0627\u0639 \u06a9\u0627\u0631 \u06a9\u0646\u062f. \u062d\u0627\u0644\u0627 \u0645\u06cc\u200c\u062e\u0648\u0627\u0647\u06cc\u0645 \u0627\u06cc\u0646 Logger \u0631\u0627 \u06cc\u06a9 \u0642\u062f\u0645 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc\u200c\u062a\u0631 \u06a9\u0646\u06cc\u0645. \u0686\u0648\u0646 \u0647\u0646\u0648\u0632 \u06cc\u06a9 \u0645\u0634\u06a9\u0644 \u0628\u0632\u0631\u06af \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0645\u0634\u06a9\u0644 Logcat<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0631\u0627 \u0645\u0646\u062a\u0634\u0631 \u06a9\u0631\u062f\u0647\u200c\u0627\u06cc \u0648 \u06cc\u06a9\u06cc \u0627\u0632 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u06af\u0632\u0627\u0631\u0634 \u0645\u06cc\u200c\u062f\u0647\u062f \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0646\u06af\u0627\u0645 \u0645\u0634\u0627\u0647\u062f\u0647 \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0642\u06cc\u0645\u062a\u200c\u0647\u0627 \u06a9\u0631\u0634 \u0645\u06cc\u200c\u06a9\u0646\u062f. \u0627\u0648\u0644\u06cc\u0646 \u06a9\u0627\u0631\u06cc \u06a9\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc \u0686\u06cc\u0633\u062a\u061f \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc. \u0648\u0627\u0631\u062f Logcat \u0645\u06cc\u200c\u0634\u0648\u06cc. \u0627\u0645\u0627 \u0686\u06cc\u0632\u06cc \u0634\u0628\u06cc\u0647 \u0627\u06cc\u0646 \u0645\u06cc\u200c\u0628\u06cc\u0646\u06cc:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>RecyclerView Attached\n\nGC Freed 12MB\n\nInsets Changed\n\nSurface Updated\n\nActivity Resumed\n\nOpenGL Warning\n\nSkipped Frames\n\nDatabase Loaded\n\nWindow Focus Changed\n\nNetwork Callback\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0634\u06a9\u0644 \u0627\u06cc\u0646\u062c\u0627\u0633\u062a \u06a9\u0647 Logcat \u0641\u0642\u0637 Log\u0647\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u0648 \u0631\u0627 \u0646\u0634\u0627\u0646 \u0646\u0645\u06cc\u200c\u062f\u0647\u062f. \u06a9\u0644 \u0633\u06cc\u0633\u062a\u0645 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0647\u0645 \u062f\u0631 \u062d\u0627\u0644 Log \u0646\u0648\u0634\u062a\u0646 \u0627\u0633\u062a. \u0633\u0631\u0648\u06cc\u0633\u200c\u0647\u0627\u06cc \u06af\u0648\u06af\u0644 \u0647\u0645 Log \u0645\u06cc\u200c\u0646\u0648\u06cc\u0633\u0646\u062f. \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0647\u0645 Log \u0645\u06cc\u200c\u0646\u0648\u06cc\u0633\u0646\u062f. \u062f\u0631 \u0646\u062a\u06cc\u062c\u0647 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0646 Log\u0647\u0627\u06cc \u062e\u0648\u062f\u062a \u06a9\u0645\u200c\u06a9\u0645 \u0633\u062e\u062a \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Tag \u0686\u06cc\u0633\u062a\u061f<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0647\u0631 Log \u06cc\u06a9 Tag \u062f\u0627\u0631\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Log.d(\n    \"ProductRepository\",\n    \"Products Loaded\"\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Log.<\/span><span style=\"color: #6F42C1\">d<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;ProductRepository&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Products Loaded&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646\u062c\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ProductRepository\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tag \u0627\u0633\u062a. \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Tag \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc \u062f\u0627\u062e\u0644 Logcat \u0641\u0642\u0637 Log\u0647\u0627\u06cc \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 \u0647\u0645\u0627\u0646 \u0642\u0633\u0645\u062a \u0631\u0627 \u0628\u0628\u06cc\u0646\u06cc. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ProductRepository\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Network\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PriceHistory\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Tag\u0647\u0627\u06cc \u062e\u0648\u0628<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u062f\u062a\u0631\u06cc\u0646 Tag \u0645\u0645\u06a9\u0646:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TAG\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>APP\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TEST\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 Tag\u0647\u0627 \u0647\u06cc\u0686 \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u06cc \u0646\u0645\u06cc\u200c\u062f\u0647\u0646\u062f. \u0628\u0647\u062a\u0631 \u0627\u0633\u062a Tag \u062f\u0642\u06cc\u0642\u0627\u064b \u0646\u0627\u0645 \u0647\u0645\u0627\u0646 \u0628\u062e\u0634 \u0628\u0627\u0634\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ProductRepository\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>PriceHistoryWorker\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>NotificationManager\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>AuthApi\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0642\u062a\u06cc \u0634\u0634 \u0645\u0627\u0647 \u0628\u0639\u062f \u062f\u0648\u0628\u0627\u0631\u0647 Log\u0647\u0627 \u0631\u0627 \u0628\u0628\u06cc\u0646\u06cc\u060c \u0641\u0648\u0631\u0627\u064b \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u200c\u0634\u0648\u06cc \u0647\u0631 Log \u0645\u062a\u0639\u0644\u0642 \u0628\u0647 \u06a9\u062f\u0627\u0645 \u0642\u0633\u0645\u062a \u0627\u0633\u062a.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0645\u0634\u06a9\u0644 Logger \u0641\u0639\u0644\u06cc<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Logger \u0645\u0627 \u0647\u0646\u0648\u0632 \u0633\u0627\u062f\u0647 \u0627\u0633\u062a. \u0627\u06af\u0631 \u0627\u06cc\u0646 \u06a9\u062f \u0631\u0627 \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>logger.e(\n    \"Repository\",\n    \"Insert Failed\"\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">logger.<\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Repository&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Insert Failed&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0646\u0647\u0627 \u0686\u06cc\u0632\u06cc \u06a9\u0647 \u062b\u0628\u062a \u0645\u06cc\u200c\u0634\u0648\u062f \u0647\u0645\u06cc\u0646 \u0645\u062a\u0646 \u0627\u0633\u062a. \u0627\u0645\u0627 \u0627\u06af\u0631 Exception \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u0645 \u0686\u0647\u061f<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>try {\n\n    repository.save(product)\n\n} catch (e: Exception) {\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    repository.<\/span><span style=\"color: #6F42C1\">save<\/span><span style=\"color: #24292E\">(product)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">} <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (e: <\/span><span style=\"color: #6F42C1\">Exception<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0641\u0642\u0637 \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>logger.e(\n    \"Repository\",\n    \"Insert Failed\"\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">logger.<\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Repository&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Insert Failed&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0639\u0644\u062a \u0648\u0627\u0642\u0639\u06cc \u062e\u0637\u0627 \u0631\u0627 \u0627\u0632 \u062f\u0633\u062a \u0645\u06cc\u200c\u062f\u0647\u06cc\u0645. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0645\u062a\u062f <code>e()<\/code> \u06cc\u06a9 \u067e\u0627\u0631\u0627\u0645\u062a\u0631 \u062f\u06cc\u06af\u0631 \u0647\u0645 \u062f\u0627\u0631\u062f.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>override fun e(\n    tag: String,\n    message: String,\n    throwable: Throwable?\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">fun<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    tag: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    message: <\/span><span style=\"color: #6F42C1\">String<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    throwable: <\/span><span style=\"color: #6F42C1\">Throwable<\/span><span style=\"color: #24292E\">?<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062d\u0627\u0644\u0627 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u0645 Exception \u0631\u0627 \u0647\u0645 \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>catch (e: Exception) {\n\n    logger.e(\n        \"Repository\",\n        \"Insert Failed\",\n        e\n    )\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (e: <\/span><span style=\"color: #6F42C1\">Exception<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    logger.<\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;Repository&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;Insert Failed&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        e<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0646\u062a\u06cc\u062c\u0647 Stack Trace \u0647\u0645 \u062b\u0628\u062a \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0647\u0631 Exception \u0631\u0627 Catch \u0646\u06a9\u0646<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0631\u0627\u06cc\u062c \u0627\u06cc\u0646 \u0627\u0633\u062a:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>try {\n\n    ...\n\n} catch (e: Exception) {\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">try<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">..<\/span><span style=\"color: #24292E\">.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">} <\/span><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (e: <\/span><span style=\"color: #6F42C1\">Exception<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u062a\u0645\u0627\u0645. \u0647\u06cc\u0686 Log\u06cc \u0647\u0645 \u0646\u0648\u0634\u062a\u0647 \u0646\u0645\u06cc\u200c\u0634\u0648\u062f. \u062f\u0631 \u0646\u062a\u06cc\u062c\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u062e\u0631\u0627\u0628 \u0646\u0645\u06cc\u200c\u0634\u0648\u062f\u060c \u0627\u0645\u0627 \u062e\u0637\u0627 \u0647\u0645 \u0628\u0631\u0627\u06cc \u0647\u0645\u06cc\u0634\u0647 \u06af\u0645 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0627\u06af\u0631 \u0648\u0627\u0642\u0639\u0627\u064b \u0644\u0627\u0632\u0645 \u0627\u0633\u062a Exception \u0631\u0627 Catch \u06a9\u0646\u06cc\u060c \u062d\u062f\u0627\u0642\u0644 \u0622\u0646 \u0631\u0627 \u062b\u0628\u062a \u06a9\u0646.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>catch (e: Exception){\n\n    logger.e(\n        \"Repository\",\n        \"Unexpected Error\",\n        e\n    )\n\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">catch<\/span><span style=\"color: #24292E\"> (e: <\/span><span style=\"color: #6F42C1\">Exception<\/span><span style=\"color: #24292E\">){<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    logger.<\/span><span style=\"color: #6F42C1\">e<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;Repository&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;Unexpected Error&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        e<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    )<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Structured Logging<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0627\u06cc\u0646 Log \u0631\u0627 \u0628\u0628\u06cc\u0646\u06cc:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Login Failed\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u062e\u0648\u0628 \u0627\u0633\u062a\u061f \u0646\u0647.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0686\u0648\u0646 \u0633\u0624\u0627\u0644\u200c\u0647\u0627\u06cc \u0632\u06cc\u0627\u062f\u06cc \u0628\u0627\u0642\u06cc \u0645\u06cc\u200c\u0645\u0627\u0646\u062f. \u06a9\u062f\u0627\u0645 \u06a9\u0627\u0631\u0628\u0631\u061f \u06a9\u062f\u0627\u0645 \u0635\u0641\u062d\u0647\u061f \u06a9\u062f\u0627\u0645 API\u061f \u06a9\u062f\u0627\u0645 \u0646\u0633\u062e\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u061f \u0628\u0647 \u062c\u0627\u06cc \u0622\u0646 \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0628\u06cc\u0634\u062a\u0631\u06cc \u062b\u0628\u062a \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Screen = Login\n\nAction = Login\n\nUserId = 548\n\nApi = Auth\n\nReason = Unauthorized\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0627\u06cc\u0646 \u0631\u0648\u0634 Structured Logging \u0645\u06cc\u200c\u06af\u0648\u06cc\u0646\u062f. \u06cc\u0639\u0646\u06cc Log \u0641\u0642\u0637 \u06cc\u06a9 \u062c\u0645\u0644\u0647 \u0646\u06cc\u0633\u062a. \u0628\u0644\u06a9\u0647 \u0645\u062c\u0645\u0648\u0639\u0647\u200c\u0627\u06cc \u0627\u0632 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0631\u062a\u0628\u0637 \u0627\u0633\u062a. \u0627\u06cc\u0646 \u0645\u062f\u0644 \u0628\u0627\u0639\u062b \u0645\u06cc\u200c\u0634\u0648\u062f \u0628\u0639\u062f\u0627\u064b \u0628\u062a\u0648\u0627\u0646\u06cc \u0631\u0627\u062d\u062a\u200c\u062a\u0631 \u0645\u0634\u06a9\u0644 \u0631\u0627 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Performance Logging<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Logging \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u062e\u0637\u0627 \u0646\u06cc\u0633\u062a. \u06af\u0627\u0647\u06cc \u0645\u06cc\u200c\u062e\u0648\u0627\u0647\u06cc\u0645 \u0633\u0631\u0639\u062a \u0642\u0633\u0645\u062a\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0627\u0646\u062f\u0627\u0632\u0647 \u0628\u06af\u06cc\u0631\u06cc\u0645. \u0645\u062b\u0644\u0627\u064b: \u0627\u0631\u0633\u0627\u0644 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0634\u0628\u06a9\u0647. \u0644\u0648\u062f \u0634\u062f\u0646 Room. \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u062a\u0635\u0648\u06cc\u0631. \u0628\u0627\u0632 \u0634\u062f\u0646 \u0635\u0641\u062d\u0647. \u0647\u0645\u0647 \u0627\u06cc\u0646\u200c\u0647\u0627 \u0642\u0627\u0628\u0644 \u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc \u0647\u0633\u062a\u0646\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val start = System.currentTimeMillis()\n\nrepository.loadProducts()\n\nval end = System.currentTimeMillis()\n\nlogger.i(\n    \"Performance\",\n    \"Loading took ${end-start} ms\"\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> start <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> System.<\/span><span style=\"color: #6F42C1\">currentTimeMillis<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">repository.<\/span><span style=\"color: #6F42C1\">loadProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> end <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> System.<\/span><span style=\"color: #6F42C1\">currentTimeMillis<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">logger.<\/span><span style=\"color: #6F42C1\">i<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Performance&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Loading took ${end<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #032F62\">start} ms&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u062e\u0631\u0648\u062c\u06cc \u0627\u06cc\u0646 \u0628\u0627\u0634\u062f:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Loading took 185 ms\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u0634\u06a9\u0644\u06cc \u0646\u06cc\u0633\u062a. \u0627\u0645\u0627 \u0627\u06af\u0631 \u0628\u0646\u0648\u06cc\u0633\u062f:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Loading took 6120 ms\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0648\u0631\u0627\u064b \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u200c\u0634\u0648\u06cc \u06cc\u06a9 \u062c\u0627\u06cc \u06a9\u0627\u0631 \u0645\u0634\u06a9\u0644 \u062f\u0627\u0631\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc API<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b \u0647\u0646\u06af\u0627\u0645 \u062f\u0631\u06cc\u0627\u0641\u062a \u0642\u06cc\u0645\u062a\u200c\u0647\u0627.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val start = System.currentTimeMillis()\n\napi.getProducts()\n\nval end = System.currentTimeMillis()\n\nlogger.i(\n\n    \"Network\",\n\n    \"Products API = ${end-start} ms\"\n\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> start <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> System.<\/span><span style=\"color: #6F42C1\">currentTimeMillis<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">api.<\/span><span style=\"color: #6F42C1\">getProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> end <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> System.<\/span><span style=\"color: #6F42C1\">currentTimeMillis<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">logger.<\/span><span style=\"color: #6F42C1\">i<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Network&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Products API = ${end<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #032F62\">start} ms&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u062f \u0627\u0632 \u0645\u062f\u062a\u06cc \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u200c\u0634\u0648\u06cc:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Products API\n\n185 ms\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648\u0644\u06cc:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Price History API\n\n4200 ms\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u067e\u0633 \u0645\u0634\u06a9\u0644 \u0627\u062d\u062a\u0645\u0627\u0644\u0627\u064b \u0627\u0632 \u0647\u0645\u0627\u0646 API \u0627\u0633\u062a.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc Room<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0642\u0637 \u0634\u0628\u06a9\u0647 \u0646\u06cc\u0633\u062a. Database \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u062f \u06a9\u0646\u062f \u0628\u0627\u0634\u062f. \u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>val start = System.currentTimeMillis()\n\ndao.getProducts()\n\nval end = System.currentTimeMillis()\n\nlogger.i(\n\n    \"Room\",\n\n    \"Query = ${end-start} ms\"\n\n)\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> start <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> System.<\/span><span style=\"color: #6F42C1\">currentTimeMillis<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">dao.<\/span><span style=\"color: #6F42C1\">getProducts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">val<\/span><span style=\"color: #24292E\"> end <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> System.<\/span><span style=\"color: #6F42C1\">currentTimeMillis<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">logger.<\/span><span style=\"color: #6F42C1\">i<\/span><span style=\"color: #24292E\">(<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Room&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #032F62\">&quot;Query = ${end<\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #032F62\">start} ms&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u06cc\u06a9 Query \u067e\u0646\u062c \u062b\u0627\u0646\u06cc\u0647 \u0637\u0648\u0644 \u0628\u06a9\u0634\u062f\u060c \u0642\u0628\u0644 \u0627\u0632 \u0627\u06cc\u0646\u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0634\u06a9\u0627\u06cc\u062a \u06a9\u0646\u062f \u062e\u0648\u062f\u062a \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u200c\u0634\u0648\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Logging \u0634\u0628\u06a9\u0647<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u0642\u0633\u0645\u062a\u200c\u0647\u0627\u06cc \u0647\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u0634\u0628\u06a9\u0647 \u0627\u0633\u062a. \u0641\u0631\u0636 \u06a9\u0646 API \u062c\u0648\u0627\u0628 \u0646\u0645\u06cc\u200c\u062f\u0647\u062f. \u0622\u06cc\u0627 \u0645\u0634\u06a9\u0644 \u0627\u0632 \u0633\u0631\u0648\u0631 \u0627\u0633\u062a\u061f \u06cc\u0627 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a\u061f \u06cc\u0627 Timeout\u061f \u06cc\u0627 JSON\u061f \u06cc\u0627 Authentication\u061f \u0628\u0631\u0627\u06cc \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0646 \u0627\u06cc\u0646 \u0645\u0634\u06a9\u0644\u0627\u062a\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u0632 Logging Interceptor \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0645\u062b\u0644\u0627\u064b \u0647\u0646\u06af\u0627\u0645 \u0627\u0631\u0633\u0627\u0644 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u06cc \u0645\u062b\u0644 \u0627\u06cc\u0646 \u062b\u0628\u062a \u0645\u06cc\u200c\u0634\u0648\u062f:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET\n\n\/api\/products\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0648 \u0628\u0639\u062f:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Response\n\n200 OK\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>404\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>500\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u06cc\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u06af\u0627\u0647\u06cc \u062f\u0631 \u0686\u0646\u062f \u062f\u0642\u06cc\u0642\u0647 \u0645\u0634\u06a9\u0644\u06cc \u0631\u0627 \u062d\u0644 \u0645\u06cc\u200c\u06a9\u0646\u062f \u06a9\u0647 \u0628\u062f\u0648\u0646 \u0622\u0646 \u0634\u0627\u06cc\u062f \u0633\u0627\u0639\u062a\u200c\u0647\u0627 \u0632\u0645\u0627\u0646 \u0628\u0628\u0631\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0627\u0645\u0627 \u06cc\u06a9 \u0627\u0634\u062a\u0628\u0627\u0647 \u0628\u0633\u06cc\u0627\u0631 \u062e\u0637\u0631\u0646\u0627\u06a9<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0639\u0636\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627 \u0647\u0645\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a Request \u0631\u0627 Log \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Authorization:\n\nBearer eyJhb...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Refresh Token\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Password\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>OTP\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u06a9\u0627\u0631 \u06cc\u06a9\u06cc \u0627\u0632 \u0628\u062f\u062a\u0631\u06cc\u0646 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc \u0627\u0645\u0646\u06cc\u062a\u06cc \u0627\u0633\u062a. \u0641\u0631\u0636 \u06a9\u0646 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0631\u0627\u06cc \u062a\u0639\u0645\u06cc\u0631 \u06af\u0648\u0634\u06cc\u060c \u062f\u0633\u062a\u06af\u0627\u0647\u0634 \u0631\u0627 \u0628\u0647 \u06cc\u06a9 \u062a\u0639\u0645\u06cc\u0631\u06a9\u0627\u0631 \u0628\u062f\u0647\u062f \u0648 Log\u0647\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u0628\u0627\u0642\u06cc \u0645\u0627\u0646\u062f\u0647 \u0628\u0627\u0634\u0646\u062f. \u06cc\u0627 \u06cc\u06a9\u06cc \u0627\u0632 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627 Log\u0647\u0627 \u0631\u0627 \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0646\u062f. \u062f\u0631 \u0627\u06cc\u0646 \u0635\u0648\u0631\u062a \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u06a9\u0627\u0631\u0628\u0631 \u0641\u0627\u0634 \u0634\u0648\u062f.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u0686\u0647 \u0686\u06cc\u0632\u0647\u0627\u06cc\u06cc \u0631\u0627 \u0647\u0631\u06af\u0632 \u0646\u0628\u0627\u06cc\u062f Log \u06a9\u0646\u06cc\u0645\u061f<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u0644\u06cc\u0633\u062a \u0631\u0627 \u0647\u0645\u06cc\u0634\u0647 \u0628\u0647 \u062e\u0627\u0637\u0631 \u0628\u0633\u067e\u0627\u0631. \u0647\u06cc\u0686\u200c\u0648\u0642\u062a \u0627\u06cc\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0627 \u062f\u0627\u062e\u0644 Log \u0646\u0646\u0648\u06cc\u0633:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Password<\/li>\n\n\n\n<li>Access Token<\/li>\n\n\n\n<li>Refresh Token<\/li>\n\n\n\n<li>JWT<\/li>\n\n\n\n<li>OTP<\/li>\n\n\n\n<li>\u0634\u0645\u0627\u0631\u0647 \u06a9\u0627\u0631\u062a<\/li>\n\n\n\n<li>CVV2<\/li>\n\n\n\n<li>Cookie<\/li>\n\n\n\n<li>Session ID<\/li>\n\n\n\n<li>\u06a9\u0644\u06cc\u062f\u0647\u0627\u06cc API<\/li>\n\n\n\n<li>\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u067e\u0632\u0634\u06a9\u06cc<\/li>\n\n\n\n<li>\u0622\u062f\u0631\u0633 \u062f\u0642\u06cc\u0642 \u06a9\u0627\u0631\u0628\u0631<\/li>\n\n\n\n<li>\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0634\u062e\u0635\u06cc \u0645\u062d\u0631\u0645\u0627\u0646\u0647<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0647\u0645 \u0645\u062c\u0628\u0648\u0631 \u0634\u062f\u06cc \u0686\u06cc\u0632\u06cc \u0631\u0627 \u062b\u0628\u062a \u06a9\u0646\u06cc\u060c \u0622\u0646 \u0631\u0627 Mask \u06a9\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0645\u062b\u0644\u0627\u064b:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u062c\u0627\u06cc:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>AccessToken:\n\neyJhbGciOi...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0646\u0648\u06cc\u0633:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>AccessToken:\n\n*************\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u0627 \u0641\u0642\u0637 \u0686\u0646\u062f \u06a9\u0627\u0631\u0627\u06a9\u062a\u0631 \u0627\u0648\u0644 \u0631\u0627 \u0646\u0634\u0627\u0646 \u0628\u062f\u0647.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>eyJh******\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">BuildConfig.DEBUG<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0647 Log\u0647\u0627 \u0646\u0628\u0627\u06cc\u062f \u062f\u0627\u062e\u0644 \u0646\u0633\u062e\u0647 Release \u0627\u062c\u0631\u0627 \u0634\u0648\u0646\u062f. \u0641\u0631\u0636 \u06a9\u0646 \u062f\u0631 \u0647\u0631 \u0635\u0641\u062d\u0647 \u062f\u0647\u200c\u0647\u0627 Log \u0646\u0648\u0634\u062a\u0647\u200c\u0627\u06cc. \u0627\u06af\u0631 \u0647\u0645\u06cc\u0646\u200c\u0647\u0627 \u062f\u0627\u062e\u0644 \u0646\u0633\u062e\u0647 \u0646\u0647\u0627\u06cc\u06cc \u0647\u0645 \u0627\u062c\u0631\u0627 \u0634\u0648\u0646\u062f:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u0633\u0631\u0639\u062a \u06a9\u0645\u06cc \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u062f.<\/li>\n\n\n\n<li>\u062d\u062c\u0645 Log\u0647\u0627 \u0632\u06cc\u0627\u062f \u0645\u06cc\u200c\u0634\u0648\u062f.<\/li>\n\n\n\n<li>\u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0627\u0636\u0627\u0641\u0647 \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc\u200c\u0634\u0648\u062f.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0645\u0639\u0645\u0648\u0644\u0627\u064b Logger \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u062f \u06a9\u0647 \u0622\u06cc\u0627 \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 \u062d\u0627\u0644\u062a Debug \u0627\u0633\u062a \u06cc\u0627 \u062e\u06cc\u0631. \u0627\u06af\u0631 Debug \u0628\u0627\u0634\u062f\u060c Log \u0686\u0627\u067e \u0645\u06cc\u200c\u0634\u0648\u062f. \u0627\u06af\u0631 Release \u0628\u0627\u0634\u062f\u060c \u0628\u0633\u06cc\u0627\u0631\u06cc \u0627\u0632 Log\u0647\u0627 \u0627\u0635\u0644\u0627\u064b \u0627\u062c\u0631\u0627 \u0646\u0645\u06cc\u200c\u0634\u0648\u0646\u062f. \u062f\u0631 \u0646\u062a\u06cc\u062c\u0647 \u0646\u0633\u062e\u0647\u200c\u0627\u06cc \u06a9\u0647 \u062f\u0633\u062a \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0645\u06cc\u200c\u0631\u0633\u062f \u0647\u0645 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u0627\u0633\u062a \u0648 \u0647\u0645 \u0627\u0645\u0646\u200c\u062a\u0631.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Timber\u061b \u0645\u062d\u0628\u0648\u0628\u200c\u062a\u0631\u06cc\u0646 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 Logging<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u0627\u06cc\u0646\u062c\u0627 \u0627\u0632 \u06a9\u0644\u0627\u0633 \u0627\u0633\u062a\u0627\u0646\u062f\u0627\u0631\u062f <code>Log<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f\u06cc\u0645\u060c \u0627\u0645\u0627 \u062f\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 <strong>Timber<\/strong> \u062c\u0627\u06cc \u0622\u0646 \u0631\u0627 \u0645\u06cc\u200c\u06af\u06cc\u0631\u062f. \u062f\u0644\u06cc\u0644 \u0645\u062d\u0628\u0648\u0628\u06cc\u062a Timber \u0627\u06cc\u0646 \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0641\u0642\u0637 \u0686\u0646\u062f \u0645\u062a\u062f \u062c\u062f\u06cc\u062f \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f\u060c \u0628\u0644\u06a9\u0647 \u06a9\u0627\u0631\u0647\u0627\u06cc\u06cc \u0631\u0627 \u0633\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f \u06a9\u0647 \u0628\u0627 <code>Log<\/code> \u062e\u0627\u0645 \u0628\u0627\u06cc\u062f \u062e\u0648\u062f\u062a \u0627\u0646\u062c\u0627\u0645 \u0628\u062f\u0647\u06cc. \u0645\u062b\u0644\u0627\u064b Tag \u0645\u0646\u0627\u0633\u0628 \u0631\u0627 \u062e\u0648\u062f\u0634 \u062a\u0634\u062e\u06cc\u0635 \u0645\u06cc\u200c\u062f\u0647\u062f\u060c \u0646\u0648\u0634\u062a\u0646 Log\u0647\u0627 \u062e\u0648\u0627\u0646\u0627\u062a\u0631 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc \u0631\u0641\u062a\u0627\u0631 Logging \u0631\u0627 \u0628\u0631\u0627\u06cc \u0646\u0633\u062e\u0647 Debug \u0648 Release \u0628\u0647 \u0634\u06a9\u0644 \u0645\u062a\u0641\u0627\u0648\u062a\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u06a9\u062a\u0647 \u0645\u0647\u0645 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0627\u06af\u0631 \u0627\u0632 \u0647\u0645\u0627\u0646 Interface <code>Logger<\/code> \u06a9\u0647 \u062f\u0631 \u0628\u062e\u0634 \u0642\u0628\u0644 \u0633\u0627\u062e\u062a\u06cc\u0645 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u06cc\u060c \u0645\u0647\u0627\u062c\u0631\u062a \u0627\u0632 <code>Log<\/code> \u0628\u0647 Timber \u0628\u0633\u06cc\u0627\u0631 \u0633\u0627\u062f\u0647 \u0627\u0633\u062a. \u0641\u0642\u0637 \u06a9\u0627\u0641\u06cc \u0627\u0633\u062a \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc <code>AndroidLogger<\/code> \u0631\u0627 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u062f\u0647\u06cc \u0648 \u0647\u06cc\u0686\u200c\u06cc\u06a9 \u0627\u0632 Repository\u0647\u0627\u060c ViewModel\u0647\u0627 \u06cc\u0627 Worker\u0647\u0627\u06cc \u067e\u0631\u0648\u0698\u0647 \u0646\u06cc\u0627\u0632 \u0628\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u0646\u062e\u0648\u0627\u0647\u0646\u062f \u062f\u0627\u0634\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06cc\u0646 \u062f\u0642\u06cc\u0642\u0627\u064b \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0632\u06cc\u062a\u200c\u0647\u0627\u06cc \u0637\u0631\u0627\u062d\u06cc \u0645\u0628\u062a\u0646\u06cc \u0628\u0631 Interface \u0627\u0633\u062a\u061b \u0648\u0627\u0628\u0633\u062a\u06af\u06cc\u200c\u0647\u0627 \u0631\u0627 \u067e\u0634\u062a \u06cc\u06a9 \u0644\u0627\u06cc\u0647 \u0627\u0646\u062a\u0632\u0627\u0639 \u067e\u0646\u0647\u0627\u0646 \u0645\u06cc\u200c\u06a9\u0646\u06cc \u062a\u0627 \u062f\u0631 \u0622\u06cc\u0646\u062f\u0647 \u0628\u062a\u0648\u0627\u0646\u06cc \u0641\u0646\u0627\u0648\u0631\u06cc\u200c\u0647\u0627\u06cc \u0632\u06cc\u0631\u0633\u0627\u062e\u062a\u06cc \u0631\u0627 \u0628\u062f\u0648\u0646 \u062f\u0633\u062a \u0632\u062f\u0646 \u0628\u0647 \u0645\u0646\u0637\u0642 \u0628\u0631\u0646\u0627\u0645\u0647 \u0639\u0648\u0636 \u06a9\u0646\u06cc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u062c\u0645\u0639\u200c\u0628\u0646\u062f\u06cc \u0628\u062e\u0634 \u062f\u0648\u0645<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0627\u06cc\u0646 \u0628\u062e\u0634 \u06cc\u0627\u062f \u06af\u0631\u0641\u062a\u06cc\u0645 \u06a9\u0647 \u06cc\u06a9 \u0633\u06cc\u0633\u062a\u0645 Logging \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0641\u0642\u0637 \u0686\u0627\u067e \u0686\u0646\u062f \u067e\u06cc\u0627\u0645 \u062f\u0627\u062e\u0644 Logcat \u0646\u06cc\u0633\u062a. \u062f\u06cc\u062f\u06cc\u0645 \u06a9\u0647 \u0627\u0646\u062a\u062e\u0627\u0628 Tag \u0645\u0646\u0627\u0633\u0628\u060c \u062b\u0628\u062a Exception\u0647\u0627\u060c \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Structured Logging\u060c \u0627\u0646\u062f\u0627\u0632\u0647\u200c\u06af\u06cc\u0631\u06cc Performance\u060c \u062b\u0628\u062a \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647 \u0648 \u0645\u062d\u0627\u0641\u0638\u062a \u0627\u0632 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633\u060c \u0647\u0645\u06af\u06cc \u0628\u062e\u0634\u06cc \u0627\u0632 \u06cc\u06a9 \u0633\u06cc\u0633\u062a\u0645 Logging \u0627\u0633\u062a\u0627\u0646\u062f\u0627\u0631\u062f \u0647\u0633\u062a\u0646\u062f. \u0647\u0645\u0686\u0646\u06cc\u0646 \u0628\u0627 \u0646\u0642\u0634 <code>BuildConfig.DEBUG<\/code> \u0648 \u0645\u0632\u06cc\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc\u06cc \u0645\u062b\u0644 Timber \u0622\u0634\u0646\u0627 \u0634\u062f\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 <strong>\u0628\u062e\u0634 \u0633\u0648\u0645<\/strong> \u0648\u0627\u0631\u062f Crash Reporting \u0645\u06cc\u200c\u0634\u0648\u06cc\u0645\u061b \u062a\u0641\u0627\u0648\u062a Crash \u0648 ANR \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645\u060c Firebase Crashlytics \u0631\u0627 \u0628\u0647 \u067e\u0631\u0648\u0698\u0647 \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645\u060c Non-Fatal Exception\u0647\u0627\u060c Breadcrumb\u0647\u0627\u060c \u06af\u0632\u0627\u0631\u0634 \u062e\u0637\u0627\u0647\u0627\u06cc Coroutine\u060c Worker \u0648 FirebaseMessagingService \u0631\u0627 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0648 \u06cc\u0627\u062f \u0645\u06cc\u200c\u06af\u06cc\u0631\u06cc\u0645 \u0686\u0637\u0648\u0631 \u0628\u0639\u062f \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u0639\u0644\u062a \u06a9\u0631\u0634 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0631\u0627 \u0627\u0632 \u0631\u0627\u0647 \u062f\u0648\u0631 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u200c\u0648\u0647\u0641\u062a\u0645<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">Logging \u0648 Crash Reporting (\u0628\u062e\u0634 \u0633\u0648\u0645)<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u0627\u06cc\u0646\u062c\u0627 \u06cc\u0627\u062f \u06af\u0631\u0641\u062a\u06cc\u0645 \u0686\u0637\u0648\u0631 \u06cc\u06a9 \u0633\u06cc\u0633\u062a\u0645 Logging \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0637\u0631\u0627\u062d\u06cc \u06a9\u0646\u06cc\u0645\u061b \u0641\u0647\u0645\u06cc\u062f\u06cc\u0645 \u0686\u0631\u0627 \u0646\u0628\u0627\u06cc\u062f \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0627\u0632 <code>Log<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645\u060c \u0686\u0631\u0627 \u0648\u062c\u0648\u062f \u06cc\u06a9 <code>Logger<\/code> \u0645\u0633\u062a\u0642\u0644 \u0627\u0647\u0645\u06cc\u062a \u062f\u0627\u0631\u062f \u0648 \u0686\u0637\u0648\u0631 Log\u0647\u0627\u06cc\u06cc \u0628\u0646\u0648\u06cc\u0633\u06cc\u0645 \u06a9\u0647 \u0628\u0639\u062f\u0627\u064b \u0648\u0627\u0642\u0639\u0627\u064b \u0628\u0647 \u062f\u0631\u062f \u0628\u062e\u0648\u0631\u0646\u062f. \u0627\u0645\u0627 \u0647\u0646\u0648\u0632 \u06cc\u06a9 \u0633\u0624\u0627\u0644 \u0645\u0647\u0645 \u0628\u0627\u0642\u06cc \u0645\u0627\u0646\u062f\u0647 \u0627\u0633\u062a. \u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648\u0627\u0642\u0639\u0627\u064b Crash \u06a9\u0646\u062f \u0686\u0647\u061f<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u0642\u0628\u0644 \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u062c\u0648\u0627\u0628 \u0627\u06cc\u0646 \u0633\u0624\u0627\u0644 \u0633\u0627\u062f\u0647 \u0627\u0633\u062a. \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u062f\u0627\u062e\u0644 Android Studio \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u060c \u0631\u0648\u06cc \u062f\u06a9\u0645\u0647 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u0632\u0646\u06cc \u0648 \u0627\u06af\u0631 Exception \u0631\u062e \u0628\u062f\u0647\u062f\u060c \u0647\u0645\u0627\u0646 \u0644\u062d\u0638\u0647 Stack Trace \u0631\u0627 \u0645\u06cc\u200c\u0628\u06cc\u0646\u06cc. \u0627\u0645\u0627 \u0628\u0639\u062f \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631\u060c \u062f\u06cc\u06af\u0631 \u0647\u06cc\u0686 \u062f\u0633\u062a\u0631\u0633\u06cc \u0645\u0633\u062a\u0642\u06cc\u0645\u06cc \u0628\u0647 \u06af\u0648\u0634\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0646\u062f\u0627\u0631\u06cc. \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648\u06cc \u062f\u0647 \u0647\u0632\u0627\u0631 \u06af\u0648\u0634\u06cc \u0628\u062f\u0648\u0646 \u0645\u0634\u06a9\u0644 \u06a9\u0627\u0631 \u06a9\u0646\u062f\u060c \u0627\u0645\u0627 \u0631\u0648\u06cc \u067e\u0646\u062c\u0627\u0647 \u06af\u0648\u0634\u06cc \u062e\u0627\u0635 \u0628\u0647 \u062f\u0644\u06cc\u0644 \u06cc\u06a9 \u0634\u0631\u0627\u06cc\u0637 \u062e\u0627\u0635 \u06a9\u0631\u0634 \u06a9\u0646\u062f. \u0627\u06af\u0631 \u0646\u062a\u0648\u0627\u0646\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0622\u0646 Crash\u0647\u0627 \u0631\u0627 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u06cc\u060c \u0639\u0645\u0644\u0627\u064b \u0631\u0627\u0647\u06cc \u0628\u0631\u0627\u06cc \u0628\u0631\u0637\u0631\u0641 \u06a9\u0631\u062f\u0646 \u0645\u0634\u06a9\u0644 \u0646\u062e\u0648\u0627\u0647\u06cc \u062f\u0627\u0634\u062a. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646\u200c\u0647\u0627\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u062f\u0646\u06cc\u0627 \u0627\u0632 \u06cc\u06a9 \u0633\u06cc\u0633\u062a\u0645 Crash Reporting \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0648\u0644 \u0627\u0632 \u0647\u0645\u0647 \u0628\u0627\u06cc\u062f \u062a\u0641\u0627\u0648\u062a Crash \u0648 Exception \u0631\u0627 \u0628\u062f\u0627\u0646\u06cc\u0645. \u062e\u06cc\u0644\u06cc \u0627\u0632 Exception\u0647\u0627 \u0627\u0635\u0644\u0627\u064b \u0628\u0627\u0639\u062b \u0628\u0633\u062a\u0647 \u0634\u062f\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0645\u06cc\u200c\u0634\u0648\u0646\u062f. \u0641\u0631\u0636 \u06a9\u0646 \u0647\u0646\u06af\u0627\u0645 \u062e\u0648\u0627\u0646\u062f\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0627\u0632 \u0633\u0631\u0648\u0631\u060c \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u06a9\u0627\u0631\u0628\u0631 \u0642\u0637\u0639 \u0634\u062f\u0647 \u0628\u0627\u0634\u062f \u0648 Retrofit \u06cc\u06a9 Exception \u062a\u0648\u0644\u06cc\u062f \u06a9\u0646\u062f. \u0627\u06af\u0631 \u0627\u06cc\u0646 Exception \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc \u0648 \u067e\u06cc\u0627\u0645 \u0645\u0646\u0627\u0633\u0628\u06cc \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0646\u0634\u0627\u0646 \u0628\u062f\u0647\u06cc\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0645\u0686\u0646\u0627\u0646 \u0628\u0647 \u06a9\u0627\u0631\u0634 \u0627\u062f\u0627\u0645\u0647 \u0645\u06cc\u200c\u062f\u0647\u062f. \u0627\u0645\u0627 \u0627\u06af\u0631 \u0647\u0645\u0627\u0646 Exception \u0628\u062f\u0648\u0646 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0628\u0627\u0642\u06cc \u0628\u0645\u0627\u0646\u062f\u060c Thread \u0645\u0631\u0628\u0648\u0637\u0647 \u0645\u062a\u0648\u0642\u0641 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0627\u06af\u0631 \u0631\u0648\u06cc Thread \u0627\u0635\u0644\u06cc \u0628\u0627\u0634\u062f\u060c \u0628\u0631\u0646\u0627\u0645\u0647 Crash \u0645\u06cc\u200c\u06a9\u0646\u062f. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0647\u0631 Crash \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0645\u06cc\u0634\u0647 \u0646\u062a\u06cc\u062c\u0647 \u06cc\u06a9 Exception \u0645\u062f\u06cc\u0631\u06cc\u062a\u200c\u0646\u0634\u062f\u0647 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u0647\u0631 Exception \u0627\u0644\u0632\u0627\u0645\u0627\u064b Crash \u0646\u06cc\u0633\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9 \u0645\u0641\u0647\u0648\u0645 \u0645\u0647\u0645 \u062f\u06cc\u06af\u0631 \u0647\u0645 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f \u06a9\u0647 \u062e\u06cc\u0644\u06cc \u0627\u0632 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627 \u0622\u0646 \u0631\u0627 \u0628\u0627 Crash \u0627\u0634\u062a\u0628\u0627\u0647 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0646\u062f \u0648 \u0622\u0646 ANR \u06cc\u0627 <strong>Application Not Responding<\/strong> \u0627\u0633\u062a. \u062f\u0631 Crash\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0627\u06af\u0647\u0627\u0646 \u0628\u0633\u062a\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f\u060c \u0627\u0645\u0627 \u062f\u0631 ANR \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0633\u062a\u0647 \u0646\u0645\u06cc\u200c\u0634\u0648\u062f\u061b \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647 \u0647\u06cc\u0686 \u067e\u0627\u0633\u062e\u06cc \u0628\u0647 \u0644\u0645\u0633 \u06a9\u0627\u0631\u0628\u0631 \u0646\u0645\u06cc\u200c\u062f\u0647\u062f. \u0641\u0631\u0636 \u06a9\u0646 \u062f\u0627\u062e\u0644 Thread \u0627\u0635\u0644\u06cc \u06cc\u06a9 \u0641\u0627\u06cc\u0644 \u0628\u0633\u06cc\u0627\u0631 \u0628\u0632\u0631\u06af \u0631\u0627 \u0628\u062e\u0648\u0627\u0646\u06cc \u06cc\u0627 \u06cc\u06a9 Query \u0633\u0646\u06af\u06cc\u0646 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u0627\u062c\u0631\u0627 \u06a9\u0646\u06cc. \u062f\u0631 \u0627\u06cc\u0646 \u0645\u062f\u062a \u0635\u0641\u062d\u0647 \u0641\u0631\u06cc\u0632 \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0628\u0639\u062f \u0627\u0632 \u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647 \u067e\u06cc\u063a\u0627\u0645 \u0645\u0639\u0631\u0648\u0641 \u00abApplication isn&#8217;t responding\u00bb \u0631\u0627 \u0646\u0634\u0627\u0646 \u0645\u06cc\u200c\u062f\u0647\u062f. \u0627\u0632 \u0646\u06af\u0627\u0647 \u06a9\u0627\u0631\u0628\u0631\u060c ANR \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0628\u0647 \u0627\u0646\u062f\u0627\u0632\u0647 Crash \u0622\u0632\u0627\u0631\u062f\u0647\u0646\u062f\u0647 \u0627\u0633\u062a\u060c \u062d\u062a\u06cc \u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0633\u062a\u0647 \u0646\u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0631\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0628\u0639\u062f \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u062a\u0648\u0627\u0646\u06cc\u0645 \u0627\u06cc\u0646 \u0645\u0634\u06a9\u0644\u0627\u062a \u0631\u0627 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc\u0645\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0627\u0632 <strong>Firebase Crashlytics<\/strong> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645. Crashlytics \u062a\u0645\u0627\u0645 Crash\u0647\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u062c\u0645\u0639\u200c\u0622\u0648\u0631\u06cc \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u062f\u0627\u062e\u0644 \u067e\u0646\u0644 Firebase \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc\u200c\u062f\u0647\u062f. \u0647\u0631 \u0628\u0627\u0631 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0648\u06cc \u06af\u0648\u0634\u06cc \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 Crash \u06a9\u0646\u062f\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u06cc \u0645\u062b\u0644 \u0645\u062f\u0644 \u06af\u0648\u0634\u06cc\u060c \u0646\u0633\u062e\u0647 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f\u060c \u0646\u0633\u062e\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u060c Stack Trace\u060c \u062a\u0639\u062f\u0627\u062f \u062f\u0641\u0639\u0627\u062a \u0631\u062e \u062f\u0627\u062f\u0646 \u062e\u0637\u0627 \u0648 \u0632\u0645\u0627\u0646 \u0648\u0642\u0648\u0639 \u0622\u0646 \u0628\u0631\u0627\u06cc \u0645\u0627 \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0628\u0647 \u0627\u06cc\u0646 \u062a\u0631\u062a\u06cc\u0628 \u062f\u06cc\u06af\u0631 \u0644\u0627\u0632\u0645 \u0646\u06cc\u0633\u062a \u0627\u0632 \u06a9\u0627\u0631\u0628\u0631 \u0628\u062e\u0648\u0627\u0647\u06cc\u0645 \u0627\u0633\u06a9\u0631\u06cc\u0646\u200c\u0634\u0627\u062a Logcat \u0628\u06af\u06cc\u0631\u062f \u06cc\u0627 \u0645\u0631\u0627\u062d\u0644 \u0631\u062e \u062f\u0627\u062f\u0646 \u062e\u0637\u0627 \u0631\u0627 \u0628\u0627 \u062c\u0632\u0626\u06cc\u0627\u062a \u062a\u0648\u0636\u06cc\u062d \u0628\u062f\u0647\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u0645\u0627 \u0642\u062f\u0631\u062a \u0648\u0627\u0642\u0639\u06cc Crashlytics \u0641\u0642\u0637 \u062b\u0628\u062a Crash \u0646\u06cc\u0633\u062a. \u0641\u0631\u0636 \u06a9\u0646 \u06cc\u06a9\u06cc \u0627\u0632 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u06af\u0632\u0627\u0631\u0634 \u062f\u0627\u062f\u0647 \u06a9\u0647 \u0647\u0646\u06af\u0627\u0645 \u0630\u062e\u06cc\u0631\u0647 \u0645\u062d\u0635\u0648\u0644\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0633\u062a\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0627\u06af\u0631 \u0641\u0642\u0637 Stack Trace \u0631\u0627 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u060c \u0634\u0627\u06cc\u062f \u0628\u0641\u0647\u0645\u06cc \u062e\u0637\u0627 \u062f\u0627\u062e\u0644 Repository \u0631\u062e \u062f\u0627\u062f\u0647 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u0647\u0646\u0648\u0632 \u0646\u0645\u06cc\u200c\u062f\u0627\u0646\u06cc \u06a9\u0627\u0631\u0628\u0631 \u062f\u0642\u06cc\u0642\u0627\u064b \u062f\u0631 \u06a9\u062f\u0627\u0645 \u0635\u0641\u062d\u0647 \u0628\u0648\u062f\u0647\u060c \u0631\u0648\u06cc \u06a9\u062f\u0627\u0645 \u0645\u062d\u0635\u0648\u0644 \u06a9\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0631\u062f\u0647 \u06cc\u0627 \u0622\u062e\u0631\u06cc\u0646 \u0639\u0645\u0644\u06cc \u06a9\u0647 \u0627\u0646\u062c\u0627\u0645 \u062f\u0627\u062f\u0647 \u0686\u0647 \u0628\u0648\u062f\u0647 \u0627\u0633\u062a. \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 Crashlytics \u0627\u062c\u0627\u0632\u0647 \u0645\u06cc\u200c\u062f\u0647\u062f \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0627\u0636\u0627\u0641\u06cc \u0647\u0645 \u0647\u0645\u0631\u0627\u0647 Crash \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0641\u0631\u0636 \u06a9\u0646 \u0642\u0628\u0644 \u0627\u0632 \u0630\u062e\u06cc\u0631\u0647 \u0645\u062d\u0635\u0648\u0644 \u0627\u06cc\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0627 \u062b\u0628\u062a \u06a9\u0631\u062f\u0647\u200c\u0627\u06cc:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#fff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Screen = AddProduct\n\nProductId = 281\n\nCategory = Mobile\n\nUserId = 154\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #24292E\">Screen <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> AddProduct<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">ProductId <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">281<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">Category <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> Mobile<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">UserId <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">154<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647 \u0628\u0639\u062f \u0628\u0631\u0646\u0627\u0645\u0647 Crash \u06a9\u0646\u062f\u060c \u062a\u0645\u0627\u0645 \u0627\u06cc\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u06a9\u0646\u0627\u0631 Stack Trace \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u0646\u062f. \u062d\u0627\u0644\u0627 \u062f\u06cc\u06af\u0631 \u0641\u0642\u0637 \u0646\u0645\u06cc\u200c\u062f\u0627\u0646\u06cc \u06a9\u0647 NullPointerException \u0631\u062e \u062f\u0627\u062f\u0647\u060c \u0628\u0644\u06a9\u0647 \u0645\u06cc\u200c\u062f\u0627\u0646\u06cc \u0627\u06cc\u0646 \u062e\u0637\u0627 \u0647\u0646\u06af\u0627\u0645 \u0630\u062e\u06cc\u0631\u0647 \u0645\u062d\u0635\u0648\u0644 \u0634\u0645\u0627\u0631\u0647 \u06f2\u06f8\u06f1 \u0648 \u062f\u0627\u062e\u0644 \u0635\u0641\u062d\u0647 \u0627\u0641\u0632\u0648\u062f\u0646 \u0645\u062d\u0635\u0648\u0644 \u0627\u062a\u0641\u0627\u0642 \u0627\u0641\u062a\u0627\u062f\u0647 \u0627\u0633\u062a. \u0647\u0645\u06cc\u0646 \u0686\u0646\u062f \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0633\u0627\u062f\u0647 \u06af\u0627\u0647\u06cc \u0633\u0627\u0639\u062a\u200c\u0647\u0627 \u0632\u0645\u0627\u0646 Debug \u0631\u0627 \u06a9\u0627\u0647\u0634 \u0645\u06cc\u200c\u062f\u0647\u0646\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u062f\u06cc\u06af\u0631 \u0627\u0632 \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc \u0628\u0633\u06cc\u0627\u0631 \u0645\u0647\u0645 Crashlytics \u062b\u0628\u062a <strong>Non-Fatal Exception<\/strong> \u0627\u0633\u062a. \u0647\u0645\u06cc\u0634\u0647 \u0644\u0627\u0632\u0645 \u0646\u06cc\u0633\u062a \u0628\u0631\u0646\u0627\u0645\u0647 Crash \u06a9\u0646\u062f \u062a\u0627 \u0645\u062a\u0648\u062c\u0647 \u0648\u062c\u0648\u062f \u06cc\u06a9 \u0645\u0634\u06a9\u0644 \u0634\u0648\u06cc. \u0641\u0631\u0636 \u06a9\u0646 \u0647\u0646\u06af\u0627\u0645 \u0647\u0645\u06af\u0627\u0645\u200c\u0633\u0627\u0632\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0628\u0627 \u0633\u0631\u0648\u0631\u060c JSON \u062f\u0631\u06cc\u0627\u0641\u062a\u06cc \u062e\u0631\u0627\u0628 \u0628\u0627\u0634\u062f. \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc Exception \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc\u060c \u067e\u06cc\u0627\u0645 \u0645\u0646\u0627\u0633\u0628\u06cc \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0646\u0634\u0627\u0646 \u0628\u062f\u0647\u06cc \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0628\u0627\u0632 \u0646\u06af\u0647 \u062f\u0627\u0631\u06cc\u060c \u0627\u0645\u0627 \u062f\u0631 \u0639\u06cc\u0646 \u062d\u0627\u0644 \u0647\u0645\u0627\u0646 Exception \u0631\u0627 \u0628\u0631\u0627\u06cc Crashlytics \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u06cc \u062a\u0627 \u0628\u0639\u062f\u0627\u064b \u0628\u0631\u0631\u0633\u06cc\u200c\u0627\u0634 \u06a9\u0646\u06cc. \u0628\u0647 \u0627\u06cc\u0646 \u062e\u0637\u0627\u0647\u0627 Non-Fatal \u06af\u0641\u062a\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f\u060c \u0686\u0648\u0646 \u0628\u0627\u0639\u062b \u0628\u0633\u062a\u0647 \u0634\u062f\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0634\u062f\u0647\u200c\u0627\u0646\u062f\u060c \u0627\u0645\u0627 \u0647\u0645\u0686\u0646\u0627\u0646 \u0627\u0631\u0632\u0634 \u0628\u0631\u0631\u0633\u06cc \u062f\u0627\u0631\u0646\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u067e\u0631\u0648\u0698\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0627\u06cc\u0646 \u0642\u0627\u0628\u0644\u06cc\u062a \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u062f \u0628\u0633\u06cc\u0627\u0631 \u0645\u0641\u06cc\u062f \u0628\u0627\u0634\u062f. \u0641\u0631\u0636 \u06a9\u0646 WorkManager \u0647\u0631 \u0634\u0628 \u0642\u06cc\u0645\u062a \u0645\u062d\u0635\u0648\u0644\u0627\u062a \u0631\u0627 \u0628\u0647\u200c\u0631\u0648\u0632\u0631\u0633\u0627\u0646\u06cc \u0645\u06cc\u200c\u06a9\u0646\u062f. \u0627\u06af\u0631 \u06cc\u06a9\u06cc \u0627\u0632 API\u0647\u0627 \u067e\u0627\u0633\u062e \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u0628\u0631\u06af\u0631\u062f\u0627\u0646\u062f\u060c \u0636\u0631\u0648\u0631\u062a\u06cc \u0646\u062f\u0627\u0631\u062f \u0628\u0631\u0646\u0627\u0645\u0647 Crash \u06a9\u0646\u062f\u060c \u0686\u0648\u0646 \u06a9\u0627\u0631\u0628\u0631 \u062d\u062a\u06cc \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u06cc\u0633\u062a. \u0627\u0645\u0627 \u0627\u06af\u0631 \u0627\u06cc\u0646 \u062e\u0637\u0627 \u0631\u0627 \u062b\u0628\u062a \u0646\u06a9\u0646\u06cc\u060c \u0634\u0627\u06cc\u062f \u0647\u0641\u062a\u0647\u200c\u0647\u0627 \u0645\u062a\u0648\u062c\u0647 \u0646\u0634\u0648\u06cc \u06a9\u0647 \u0647\u0645\u06af\u0627\u0645\u200c\u0633\u0627\u0632\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0631\u0648\u06cc \u0628\u0639\u0636\u06cc \u06af\u0648\u0634\u06cc\u200c\u0647\u0627 \u0634\u06a9\u0633\u062a \u0645\u06cc\u200c\u062e\u0648\u0631\u062f. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 Worker \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u062f Exception \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u062f\u060c \u0639\u0645\u0644\u06cc\u0627\u062a \u0631\u0627 \u0645\u062a\u0648\u0642\u0641 \u06a9\u0646\u062f \u0648 \u0647\u0645\u0632\u0645\u0627\u0646 \u06af\u0632\u0627\u0631\u0634 \u0622\u0646 \u0631\u0627 \u0628\u0631\u0627\u06cc Crashlytics \u0628\u0641\u0631\u0633\u062a\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u06cc\u0646 \u0645\u0648\u0636\u0648\u0639 \u062f\u0631\u0628\u0627\u0631\u0647 FirebaseMessagingService \u0647\u0645 \u0635\u062f\u0642 \u0645\u06cc\u200c\u06a9\u0646\u062f. \u0641\u0631\u0636 \u06a9\u0646 \u06cc\u06a9 Push Notification \u062c\u062f\u06cc\u062f \u062f\u0631\u06cc\u0627\u0641\u062a \u0634\u062f\u0647 \u0627\u0645\u0627 \u0633\u0627\u062e\u062a\u0627\u0631 JSON \u0622\u0646 \u0628\u0627 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0633\u0627\u0632\u06af\u0627\u0631 \u0646\u06cc\u0633\u062a. \u0627\u06af\u0631 Exception \u0645\u062f\u06cc\u0631\u06cc\u062a \u0646\u0634\u0648\u062f\u060c \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0633\u0631\u0648\u06cc\u0633 Push \u06a9\u0631\u0634 \u06a9\u0646\u062f \u0648 \u06a9\u0627\u0631\u0628\u0631 \u062f\u06cc\u06af\u0631 \u0647\u06cc\u0686 \u0627\u0639\u0644\u0627\u0646 \u062c\u062f\u06cc\u062f\u06cc \u062f\u0631\u06cc\u0627\u0641\u062a \u0646\u06a9\u0646\u062f. \u062f\u0631 \u0686\u0646\u06cc\u0646 \u0634\u0631\u0627\u06cc\u0637\u06cc \u0628\u0647\u062a\u0631 \u0627\u0633\u062a Exception \u0631\u0627 \u062b\u0628\u062a \u06a9\u0646\u06cc\u0645\u060c Push \u0631\u0627 \u0646\u0627\u062f\u06cc\u062f\u0647 \u0628\u06af\u06cc\u0631\u06cc\u0645 \u0648 \u0627\u062c\u0627\u0632\u0647 \u0628\u062f\u0647\u06cc\u0645 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647 \u06a9\u0627\u0631 \u062e\u0648\u062f\u0634 \u0627\u062f\u0627\u0645\u0647 \u062f\u0647\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u06cc\u06a9\u06cc \u0627\u0632 \u0627\u0645\u06a9\u0627\u0646\u0627\u062a \u062c\u0627\u0644\u0628 Crashlytics \u0642\u0627\u0628\u0644\u06cc\u062a\u06cc \u0628\u0647 \u0646\u0627\u0645 <strong>Breadcrumb<\/strong> \u0627\u0633\u062a. Breadcrumb \u0631\u0627 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646 \u0631\u062f\u067e\u0627\u06cc \u062d\u0631\u06a9\u062a \u06a9\u0627\u0631\u0628\u0631 \u0642\u0628\u0644 \u0627\u0632 Crash \u062f\u0631 \u0646\u0638\u0631 \u06af\u0631\u0641\u062a. \u0641\u0631\u0636 \u06a9\u0646 \u06a9\u0627\u0631\u0628\u0631 \u0627\u06cc\u0646 \u0645\u0633\u06cc\u0631 \u0631\u0627 \u0637\u06cc \u06a9\u0631\u062f\u0647 \u0627\u0633\u062a:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">Home<br>\u2193<br>Search<br>\u2193<br>Product Details<br>\u2193<br>Price History<br>\u2193<br>Add Alert<br>\u2193<br>Crash<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0641\u0642\u0637 Stack Trace \u0631\u0627 \u0628\u0628\u06cc\u0646\u06cc\u060c \u0634\u0627\u06cc\u062f \u0645\u062a\u0648\u062c\u0647 \u0634\u0648\u06cc \u062e\u0637\u0627 \u062f\u0627\u062e\u0644 \u0635\u0641\u062d\u0647 \u0647\u0634\u062f\u0627\u0631 \u0642\u06cc\u0645\u062a \u0631\u062e \u062f\u0627\u062f\u0647 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u0646\u0645\u06cc\u200c\u062f\u0627\u0646\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0686\u0637\u0648\u0631 \u0628\u0647 \u0622\u0646\u062c\u0627 \u0631\u0633\u06cc\u062f\u0647 \u0627\u0633\u062a. Breadcrumb \u062f\u0642\u06cc\u0642\u0627\u064b \u0627\u06cc\u0646 \u0645\u0633\u06cc\u0631 \u0631\u0627 \u062b\u0628\u062a \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u0647\u0646\u06af\u0627\u0645 \u0628\u0631\u0631\u0633\u06cc Crash \u0646\u0634\u0627\u0646 \u0645\u06cc\u200c\u062f\u0647\u062f. \u0627\u06cc\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u062e\u0635\u0648\u0635\u0627\u064b \u0628\u0631\u0627\u06cc \u0628\u0627\u06af\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0641\u0642\u0637 \u0628\u0639\u062f \u0627\u0632 \u0686\u0646\u062f \u0645\u0631\u062d\u0644\u0647 \u062e\u0627\u0635 \u0631\u062e \u0645\u06cc\u200c\u062f\u0647\u0646\u062f \u0641\u0648\u0642\u200c\u0627\u0644\u0639\u0627\u062f\u0647 \u0627\u0631\u0632\u0634\u0645\u0646\u062f \u0647\u0633\u062a\u0646\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u067e\u0631\u0648\u0698\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u0645 \u0642\u0628\u0644 \u0627\u0632 \u0647\u0631 Navigation \u0645\u0647\u0645 \u06cc\u06a9 Breadcrumb \u062b\u0628\u062a \u06a9\u0646\u06cc\u0645. \u0645\u062b\u0644\u0627\u064b \u0647\u0646\u06af\u0627\u0645 \u0648\u0631\u0648\u062f \u0628\u0647 \u0635\u0641\u062d\u0647 \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0642\u06cc\u0645\u062a\u060c \u0647\u0646\u06af\u0627\u0645 \u0628\u0627\u0632 \u0634\u062f\u0646 \u0635\u0641\u062d\u0647 \u0627\u0641\u0632\u0648\u062f\u0646 \u0645\u062d\u0635\u0648\u0644 \u06cc\u0627 \u0647\u0646\u06af\u0627\u0645 \u0634\u0631\u0648\u0639 \u0647\u0645\u06af\u0627\u0645\u200c\u0633\u0627\u0632\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a. \u0627\u06af\u0631 \u0628\u0639\u062f\u0627\u064b Crash \u0631\u062e \u0628\u062f\u0647\u062f\u060c \u06a9\u0644 \u0645\u0633\u06cc\u0631 \u062d\u0631\u06a9\u062a \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631\u0645\u0627\u0646 \u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u06a9\u062a\u0647 \u0645\u0647\u0645 \u062f\u06cc\u06af\u0631\u06cc \u06a9\u0647 \u0646\u0628\u0627\u06cc\u062f \u0641\u0631\u0627\u0645\u0648\u0634 \u06a9\u0646\u06cc\u0645 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062d\u0633\u0627\u0633 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0646\u0628\u0627\u06cc\u062f \u0648\u0627\u0631\u062f \u06af\u0632\u0627\u0631\u0634\u200c\u0647\u0627\u06cc Crash \u0634\u0648\u0646\u062f. \u0647\u0645\u0627\u0646\u200c\u0637\u0648\u0631 \u06a9\u0647 \u0642\u0628\u0644\u0627\u064b \u06af\u0641\u062a\u06cc\u0645\u060c Password\u060c Access Token\u060c Refresh Token\u060c Cookie\u060c OTP\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0628\u0627\u0646\u06a9\u06cc \u06cc\u0627 \u0647\u0631 \u062f\u0627\u062f\u0647 \u0645\u062d\u0631\u0645\u0627\u0646\u0647 \u062f\u06cc\u06af\u0631\u06cc \u0646\u0628\u0627\u06cc\u062f \u062f\u0627\u062e\u0644 Log \u06cc\u0627 Crash Report \u062b\u0628\u062a \u0634\u0648\u062f. \u0627\u06af\u0631 \u0646\u06cc\u0627\u0632 \u0628\u0647 \u0634\u0646\u0627\u0633\u0627\u06cc\u06cc \u06a9\u0627\u0631\u0628\u0631 \u062f\u0627\u0631\u06cc\u060c \u0641\u0642\u0637 \u06cc\u06a9 \u0634\u0646\u0627\u0633\u0647 \u062f\u0627\u062e\u0644\u06cc \u06cc\u0627 \u06cc\u06a9 UserId \u06a9\u0627\u0641\u06cc \u0627\u0633\u062a. \u0647\u062f\u0641 Crash Reporting \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0646 \u0639\u0644\u062a \u062e\u0637\u0627\u0633\u062a\u060c \u0646\u0647 \u0630\u062e\u06cc\u0631\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062e\u0635\u0648\u0635\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u0646\u0647\u0627\u06cc\u062a \u0628\u0627\u06cc\u062f \u0627\u06cc\u0646 \u0630\u0647\u0646\u06cc\u062a \u0631\u0627 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc \u06a9\u0647 \u0628\u0639\u062f \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u062f\u06cc\u06af\u0631 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u0627\u0628\u0632\u0627\u0631 Debug \u062a\u0648 Android Studio \u0646\u06cc\u0633\u062a\u061b \u0628\u0644\u06a9\u0647 Logging \u0648 Crash Reporting \u0647\u0633\u062a\u0646\u062f. \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 Production \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0627\u06cc \u0646\u06cc\u0633\u062a \u06a9\u0647 \u0647\u06cc\u0686\u200c\u0648\u0642\u062a Crash \u0646\u06a9\u0646\u062f\u060c \u0686\u0648\u0646 \u0686\u0646\u06cc\u0646 \u0686\u06cc\u0632\u06cc \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u063a\u06cc\u0631\u0645\u0645\u06a9\u0646 \u0627\u0633\u062a. \u0628\u0631\u0646\u0627\u0645\u0647 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0627\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0627\u06af\u0631 Crash \u0647\u0645 \u06a9\u0631\u062f\u060c \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0628\u062a\u0648\u0627\u0646\u062f \u0638\u0631\u0641 \u0686\u0646\u062f \u062f\u0642\u06cc\u0642\u0647 \u0639\u0644\u062a \u0622\u0646 \u0631\u0627 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u062f\u060c \u0622\u0646 \u0631\u0627 \u0628\u0627\u0632\u062a\u0648\u0644\u06cc\u062f \u06a9\u0646\u062f \u0648 \u062f\u0631 \u0646\u0633\u062e\u0647 \u0628\u0639\u062f\u06cc \u0628\u0631\u0637\u0631\u0641\u0634 \u06a9\u0646\u062f. \u062f\u0642\u06cc\u0642\u0627\u064b \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0627\u0633\u062a \u06a9\u0647 Logging \u0648 Crash Reporting \u0631\u0627 \u0628\u0627\u06cc\u062f \u0628\u062e\u0634\u06cc \u0627\u0632 \u0645\u0639\u0645\u0627\u0631\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0627\u0646\u0633\u062a\u060c \u0646\u0647 \u0635\u0631\u0641\u0627\u064b \u0686\u0646\u062f \u0627\u0628\u0632\u0627\u0631 \u06a9\u0645\u06a9\u06cc \u0628\u0631\u0627\u06cc Debug \u06a9\u0631\u062f\u0646.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u062f\u0631\u0633 \u0634\u0635\u062a\u200c\u0648\u0647\u0641\u062a\u0645<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">Logging \u0648 Crash Reporting (\u0628\u062e\u0634 \u0686\u0647\u0627\u0631\u0645)<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\u062a\u0627 \u0627\u06cc\u0646\u062c\u0627 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u0627\u062c\u0632\u0627\u06cc \u06cc\u06a9 \u0633\u06cc\u0633\u062a\u0645 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc Logging \u0648 Crash Reporting \u0631\u0627 \u0634\u0646\u0627\u062e\u062a\u06cc\u0645. \u0627\u0645\u0627 \u0647\u0646\u0648\u0632 \u06cc\u06a9 \u0633\u0624\u0627\u0644 \u0645\u0647\u0645 \u0628\u0627\u0642\u06cc \u0645\u0627\u0646\u062f\u0647 \u0627\u0633\u062a\u061b \u0627\u06cc\u0646 \u0627\u0628\u0632\u0627\u0631\u0647\u0627 \u062f\u0642\u06cc\u0642\u0627\u064b \u0628\u0627\u06cc\u062f \u06a9\u062c\u0627\u06cc \u0645\u0639\u0645\u0627\u0631\u06cc \u067e\u0631\u0648\u0698\u0647 \u0642\u0631\u0627\u0631 \u0628\u06af\u06cc\u0631\u0646\u062f\u061f \u0627\u06af\u0631 \u0647\u0631 \u06a9\u0644\u0627\u0633 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b Log \u0628\u0646\u0648\u06cc\u0633\u062f \u06cc\u0627 \u062e\u0648\u062f\u0634 \u0628\u0627 Crashlytics \u0627\u0631\u062a\u0628\u0627\u0637 \u0628\u0631\u0642\u0631\u0627\u0631 \u06a9\u0646\u062f\u060c \u0628\u0639\u062f \u0627\u0632 \u0645\u062f\u062a\u06cc \u067e\u0631\u0648\u0698\u0647 \u0628\u0647 \u0647\u0645\u0627\u0646 \u0622\u0634\u0641\u062a\u06af\u06cc\u200c\u0627\u06cc \u062f\u0686\u0627\u0631 \u0645\u06cc\u200c\u0634\u0648\u062f \u06a9\u0647 \u062f\u0631 \u0641\u0635\u0644\u200c\u0647\u0627\u06cc \u0642\u0628\u0644\u06cc \u062f\u0631\u0628\u0627\u0631\u0647 \u0622\u0646 \u0635\u062d\u0628\u062a \u06a9\u0631\u062f\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u067e\u0631\u0648\u0698\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0647\u0645\u0647 \u0686\u06cc\u0632 \u0627\u0632 \u06cc\u06a9 \u0646\u0642\u0637\u0647 \u0645\u0631\u06a9\u0632\u06cc \u0639\u0628\u0648\u0631 \u06a9\u0646\u062f. ViewModel\u060c Repository\u060c Worker\u060c Service \u06cc\u0627 \u062d\u062a\u06cc \u06a9\u0644\u0627\u0633\u200c\u0647\u0627\u06cc \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 \u0634\u0628\u06a9\u0647 \u0646\u0628\u0627\u06cc\u062f \u0628\u062f\u0627\u0646\u0646\u062f \u06a9\u0647 \u067e\u0634\u062a \u0635\u062d\u0646\u0647 \u0627\u0632 Logcat\u060c Timber \u06cc\u0627 Firebase Crashlytics \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0622\u0646\u200c\u0647\u0627 \u0641\u0642\u0637 \u0628\u0627\u06cc\u062f \u06cc\u06a9 Interface \u0628\u0647 \u0646\u0627\u0645 <code>Logger<\/code> \u0631\u0627 \u0628\u0634\u0646\u0627\u0633\u0646\u062f. \u062f\u0631 \u0646\u062a\u06cc\u062c\u0647 \u0627\u06af\u0631 \u0631\u0648\u0632\u06cc \u062a\u0635\u0645\u06cc\u0645 \u0628\u06af\u06cc\u0631\u06cc Timber \u0631\u0627 \u062d\u0630\u0641 \u06a9\u0646\u06cc\u060c \u06cc\u0627 \u0628\u0647 \u062c\u0627\u06cc Crashlytics \u0627\u0632 \u0633\u0631\u0648\u06cc\u0633 \u062f\u06cc\u06af\u0631\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u060c \u0641\u0642\u0637 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc Logger \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u0628\u0642\u06cc\u0647 \u067e\u0631\u0648\u0698\u0647 \u062d\u062a\u06cc \u0645\u062a\u0648\u062c\u0647 \u0627\u06cc\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u0646\u062e\u0648\u0627\u0647\u062f \u0634\u062f. \u0627\u06cc\u0646 \u062f\u0642\u06cc\u0642\u0627\u064b \u0647\u0645\u0627\u0646 \u0645\u0632\u06cc\u062a\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0642\u0628\u0644\u0627\u064b \u062f\u0631\u0628\u0627\u0631\u0647 \u0648\u0627\u0628\u0633\u062a\u06af\u06cc \u0628\u0647 Interface \u0648 \u06a9\u0627\u0647\u0634 Coupling \u06cc\u0627\u062f \u06af\u0631\u0641\u062a\u06cc\u0645.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0647 \u0645\u0631\u0648\u0631 \u0632\u0645\u0627\u0646 \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u200c\u0634\u0648\u06cc Logging \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0646 \u0628\u0627\u06af \u0646\u06cc\u0633\u062a\u060c \u0628\u0644\u06a9\u0647 \u0628\u0647 \u062a\u0635\u0645\u06cc\u0645\u200c\u06af\u06cc\u0631\u06cc\u200c\u0647\u0627\u06cc \u0641\u0646\u06cc \u0647\u0645 \u06a9\u0645\u06a9 \u0645\u06cc\u200c\u06a9\u0646\u062f. \u0641\u0631\u0636 \u06a9\u0646 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0645\u0631\u062a\u0628 \u06af\u0632\u0627\u0631\u0634 \u0645\u06cc\u200c\u062f\u0647\u0646\u062f \u06a9\u0647 \u0635\u0641\u062d\u0647 \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u0642\u06cc\u0645\u062a \u062f\u06cc\u0631 \u0628\u0627\u0632 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0627\u06af\u0631 \u0647\u06cc\u0686 Log\u06cc \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u060c \u0628\u0627\u06cc\u062f \u062d\u062f\u0633 \u0628\u0632\u0646\u06cc \u0645\u0634\u06a9\u0644 \u0627\u0632 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0627\u0633\u062a\u060c \u06cc\u0627 \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633\u060c \u06cc\u0627 \u0631\u0646\u062f\u0631 \u0634\u062f\u0646 Compose. \u0627\u0645\u0627 \u0627\u06af\u0631 \u0627\u0632 \u0642\u0628\u0644 \u0632\u0645\u0627\u0646 \u0627\u062c\u0631\u0627\u06cc \u0642\u0633\u0645\u062a\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0631\u0627 \u062b\u0628\u062a \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u06cc\u060c \u062e\u06cc\u0644\u06cc \u0633\u0631\u06cc\u0639 \u0645\u062a\u0648\u062c\u0647 \u0645\u06cc\u200c\u0634\u0648\u06cc \u06a9\u0647 \u0645\u062b\u0644\u0627\u064b \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0634\u0628\u06a9\u0647 \u0641\u0642\u0637 \u06f1\u06f8\u06f0 \u0645\u06cc\u0644\u06cc\u200c\u062b\u0627\u0646\u06cc\u0647 \u0637\u0648\u0644 \u06a9\u0634\u06cc\u062f\u0647\u060c Query \u062f\u06cc\u062a\u0627\u0628\u06cc\u0633 \u06f4\u06f0 \u0645\u06cc\u0644\u06cc\u200c\u062b\u0627\u0646\u06cc\u0647 \u0628\u0648\u062f\u0647\u060c \u0627\u0645\u0627 \u062a\u0628\u062f\u06cc\u0644 \u062f\u0627\u062f\u0647\u200c\u0647\u0627 \u0628\u0647 \u0645\u062f\u0644\u200c\u0647\u0627\u06cc \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0628\u06cc\u0634 \u0627\u0632 \u062f\u0648 \u062b\u0627\u0646\u06cc\u0647 \u0632\u0645\u0627\u0646 \u0628\u0631\u062f\u0647 \u0627\u0633\u062a. \u062d\u0627\u0644\u0627 \u0628\u0647 \u062c\u0627\u06cc \u062d\u062f\u0633 \u0632\u062f\u0646\u060c \u062f\u0642\u06cc\u0642\u0627\u064b \u0645\u06cc\u200c\u062f\u0627\u0646\u06cc \u0628\u0627\u06cc\u062f \u06a9\u062f\u0627\u0645 \u0642\u0633\u0645\u062a \u0631\u0627 \u0628\u0647\u06cc\u0646\u0647 \u06a9\u0646\u06cc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u06cc\u0646 \u0645\u0648\u0636\u0648\u0639 \u062f\u0631\u0628\u0627\u0631\u0647 Crash\u0647\u0627 \u0647\u0645 \u0635\u0627\u062f\u0642 \u0627\u0633\u062a. \u0641\u0631\u0636 \u06a9\u0646 \u0628\u0639\u062f \u0627\u0632 \u0627\u0646\u062a\u0634\u0627\u0631 \u0646\u0633\u062e\u0647 \u062c\u062f\u06cc\u062f\u060c Crashlytics \u0646\u0634\u0627\u0646 \u0645\u06cc\u200c\u062f\u0647\u062f \u06a9\u0647 \u0647\u0632\u0627\u0631\u0627\u0646 \u06a9\u0627\u0631\u0628\u0631 \u0628\u0627 \u06cc\u06a9 NullPointerException \u0645\u0648\u0627\u062c\u0647 \u0634\u062f\u0647\u200c\u0627\u0646\u062f. \u0627\u06af\u0631 \u0641\u0642\u0637 Stack Trace \u0631\u0627 \u0628\u0628\u06cc\u0646\u06cc\u060c \u0634\u0627\u06cc\u062f \u0686\u0646\u062f \u0633\u0627\u0639\u062a \u0637\u0648\u0644 \u0628\u06a9\u0634\u062f \u062a\u0627 \u0639\u0644\u062a \u0631\u0627 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc\u060c \u0627\u0645\u0627 \u0627\u06af\u0631 \u06a9\u0646\u0627\u0631 \u0622\u0646 Breadcrumb\u0647\u0627\u060c \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0635\u0641\u062d\u0647 \u0641\u0639\u0644\u06cc\u060c \u0646\u0633\u062e\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648 \u0686\u0646\u062f Custom Key \u0647\u0645 \u062b\u0628\u062a \u0634\u062f\u0647 \u0628\u0627\u0634\u0646\u062f\u060c \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0638\u0631\u0641 \u0686\u0646\u062f \u062f\u0642\u06cc\u0642\u0647 \u0645\u062a\u0648\u062c\u0647 \u0634\u0648\u06cc \u0627\u06cc\u0646 \u062e\u0637\u0627 \u0641\u0642\u0637 \u0631\u0648\u06cc \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u06f1\u06f3 \u0648 \u0641\u0642\u0637 \u0647\u0646\u06af\u0627\u0645 \u0628\u0627\u0632 \u06a9\u0631\u062f\u0646 \u0635\u0641\u062d\u0647 \u0647\u0634\u062f\u0627\u0631 \u0642\u06cc\u0645\u062a \u0631\u062e \u0645\u06cc\u200c\u062f\u0647\u062f. \u062a\u0641\u0627\u0648\u062a \u0628\u06cc\u0646 \u06cc\u06a9 \u062a\u06cc\u0645 \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0648 \u06cc\u06a9 \u062a\u06cc\u0645 \u0622\u0645\u0627\u062a\u0648\u0631 \u062f\u0642\u06cc\u0642\u0627\u064b \u062f\u0631 \u0647\u0645\u06cc\u0646 \u0633\u0631\u0639\u062a \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0646 \u0648 \u0631\u0641\u0639 \u0645\u0634\u06a9\u0644\u0627\u062a \u0627\u0633\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0646\u06a9\u062a\u0647 \u062f\u06cc\u06af\u0631\u06cc \u06a9\u0647 \u0628\u0627\u06cc\u062f \u0647\u0645\u06cc\u0634\u0647 \u0628\u0647 \u062e\u0627\u0637\u0631 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u060c \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 Logging \u0647\u0645 \u0647\u0632\u06cc\u0646\u0647 \u062f\u0627\u0631\u062f. \u0647\u0631 Log \u0645\u0642\u062f\u0627\u0631\u06cc \u062d\u0627\u0641\u0638\u0647 \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u062f\u060c \u0631\u0648\u06cc \u062f\u06cc\u0633\u06a9 \u0646\u0648\u0634\u062a\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f \u06cc\u0627 \u0627\u0632 \u0637\u0631\u06cc\u0642 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f. \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0646\u0628\u0627\u06cc\u062f \u0627\u0632 \u0622\u0646 \u0628\u06cc\u200c\u0631\u0648\u06cc\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f. \u0627\u06af\u0631 \u062f\u0627\u062e\u0644 \u06cc\u06a9 \u062d\u0644\u0642\u0647 \u06a9\u0647 \u0647\u0632\u0627\u0631 \u0628\u0627\u0631 \u0627\u062c\u0631\u0627 \u0645\u06cc\u200c\u0634\u0648\u062f Log \u0628\u0646\u0648\u06cc\u0633\u06cc\u060c \u0647\u0645 \u0639\u0645\u0644\u06a9\u0631\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u06a9\u0627\u0647\u0634 \u067e\u06cc\u062f\u0627 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u0647\u0645 Log\u0647\u0627\u06cc \u0627\u0631\u0632\u0634\u0645\u0646\u062f \u0628\u06cc\u0646 \u0635\u062f\u0647\u0627 \u067e\u06cc\u0627\u0645 \u0628\u06cc\u200c\u0627\u0647\u0645\u06cc\u062a \u06af\u0645 \u0645\u06cc\u200c\u0634\u0648\u0646\u062f. \u0647\u0645\u06cc\u0634\u0647 \u0633\u0639\u06cc \u06a9\u0646 \u0641\u0642\u0637 \u0627\u062a\u0641\u0627\u0642\u200c\u0647\u0627\u06cc\u06cc \u0631\u0627 \u062b\u0628\u062a \u06a9\u0646\u06cc \u06a9\u0647 \u0628\u0639\u062f\u0627\u064b \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0628\u0631\u0627\u06cc \u062a\u062d\u0644\u06cc\u0644 \u06cc\u0627 \u0631\u0641\u0639 \u0645\u0634\u06a9\u0644 \u0645\u0641\u06cc\u062f \u0628\u0627\u0634\u0646\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0647\u0645\u0686\u0646\u06cc\u0646 \u0647\u06cc\u0686\u200c\u0648\u0642\u062a \u0627\u0632 Logging \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u0645\u062f\u06cc\u0631\u06cc\u062a \u062e\u0637\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u06a9\u0646. \u0628\u0639\u0636\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u200c\u0647\u0627 \u0647\u0631 Exception \u0631\u0627 Catch \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f\u060c \u062f\u0627\u062e\u0644 Log \u0645\u06cc\u200c\u0646\u0648\u06cc\u0633\u0646\u062f \u0648 \u0628\u0639\u062f \u0647\u06cc\u0686 \u06a9\u0627\u0631 \u062f\u06cc\u06af\u0631\u06cc \u0627\u0646\u062c\u0627\u0645 \u0646\u0645\u06cc\u200c\u062f\u0647\u0646\u062f. \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0641\u0642\u0637 \u0628\u0627\u0639\u062b \u0645\u06cc\u200c\u0634\u0648\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u0638\u0627\u0647\u0631\u0627\u064b \u0633\u0627\u0644\u0645 \u0628\u0647 \u0646\u0638\u0631 \u0628\u0631\u0633\u062f\u060c \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u0628\u062e\u0634\u06cc \u0627\u0632 \u0622\u0646 \u062f\u06cc\u06af\u0631 \u062f\u0631\u0633\u062a \u06a9\u0627\u0631 \u0646\u0645\u06cc\u200c\u06a9\u0646\u062f. Logging \u0628\u0627\u06cc\u062f \u0645\u06a9\u0645\u0644 \u0645\u062f\u06cc\u0631\u06cc\u062a \u062e\u0637\u0627 \u0628\u0627\u0634\u062f\u060c \u0646\u0647 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u0622\u0646. \u0627\u06af\u0631 \u06cc\u06a9 \u0639\u0645\u0644\u06cc\u0627\u062a \u0642\u0627\u0628\u0644 \u0628\u0627\u0632\u06cc\u0627\u0628\u06cc \u0627\u0633\u062a\u060c \u0628\u0627\u06cc\u062f \u0645\u062f\u06cc\u0631\u06cc\u062a \u0634\u0648\u062f \u0648 \u062f\u0631 \u06a9\u0646\u0627\u0631 \u0622\u0646 \u06af\u0632\u0627\u0631\u0634 \u0647\u0645 \u062b\u0628\u062a \u0634\u0648\u062f. \u0627\u06af\u0631 \u0642\u0627\u0628\u0644 \u0628\u0627\u0632\u06cc\u0627\u0628\u06cc \u0646\u06cc\u0633\u062a\u060c \u0628\u0627\u06cc\u062f \u0627\u062c\u0627\u0632\u0647 \u062f\u0647\u06cc Crashlytics \u0622\u0646 \u0631\u0627 \u062b\u0628\u062a \u06a9\u0646\u062f \u062a\u0627 \u062f\u0631 \u0646\u0633\u062e\u0647 \u0628\u0639\u062f\u06cc \u0628\u0631\u0637\u0631\u0641 \u0634\u0648\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u067e\u0631\u0648\u0698\u0647 \u0642\u06cc\u0645\u062a\u200c\u0628\u0627\u0646 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062a\u0645\u0627\u0645 \u0628\u062e\u0634\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u062a\u0627\u06a9\u0646\u0648\u0646 \u0633\u0627\u062e\u062a\u0647\u200c\u0627\u06cc\u0645 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0646\u062f \u0627\u0632 Logger \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0646\u062f. \u0647\u0646\u06af\u0627\u0645 \u0627\u062c\u0631\u0627\u06cc WorkManager \u0645\u06cc\u200c\u062a\u0648\u0627\u0646 \u0634\u0631\u0648\u0639 \u0648 \u067e\u0627\u06cc\u0627\u0646 \u0647\u0645\u06af\u0627\u0645\u200c\u0633\u0627\u0632\u06cc \u0631\u0627 \u062b\u0628\u062a \u06a9\u0631\u062f. \u0647\u0646\u06af\u0627\u0645 \u062f\u0631\u06cc\u0627\u0641\u062a Push Notification \u0645\u06cc\u200c\u062a\u0648\u0627\u0646 \u0646\u0648\u0639 \u0627\u0639\u0644\u0627\u0646 \u0631\u0627 \u062b\u0628\u062a \u06a9\u0631\u062f. Repository\u0647\u0627 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0646\u062f \u0645\u062f\u062a \u0632\u0645\u0627\u0646 \u0627\u062c\u0631\u0627\u06cc Query\u0647\u0627 \u0631\u0627 \u062b\u0628\u062a \u06a9\u0646\u0646\u062f. ViewModel\u0647\u0627 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0646\u062f \u0631\u0648\u06cc\u062f\u0627\u062f\u0647\u0627\u06cc \u0645\u0647\u0645 \u0631\u0627\u0628\u0637 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0631\u0627 \u062b\u0628\u062a \u06a9\u0646\u0646\u062f \u0648 \u0644\u0627\u06cc\u0647 \u0634\u0628\u06a9\u0647 \u0647\u0645 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u062f \u0641\u0642\u0637 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0636\u0631\u0648\u0631\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u0648 \u067e\u0627\u0633\u062e\u200c\u0647\u0627 \u0631\u0627 \u062b\u0628\u062a \u06a9\u0646\u062f\u060c \u0628\u062f\u0648\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0647\u06cc\u0686 \u062f\u0627\u062f\u0647 \u0645\u062d\u0631\u0645\u0627\u0646\u0647\u200c\u0627\u06cc \u0648\u0627\u0631\u062f Log \u0634\u0648\u062f. \u0648\u0642\u062a\u06cc \u0647\u0645\u0647 \u0627\u06cc\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u06a9\u0646\u0627\u0631 \u0647\u0645 \u0642\u0631\u0627\u0631 \u0628\u06af\u06cc\u0631\u0646\u062f\u060c \u062a\u0635\u0648\u06cc\u0631\u06cc \u06a9\u0627\u0645\u0644 \u0627\u0632 \u0631\u0641\u062a\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 \u062e\u0648\u0627\u0647\u06cc \u062f\u0627\u0634\u062a.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0627\u06af\u0631 \u0628\u062e\u0648\u0627\u0647\u0645 \u0641\u0642\u0637 \u06cc\u06a9 \u062a\u0648\u0635\u06cc\u0647 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0646\u0648\u06cc\u0633\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc \u0628\u062f\u0647\u0645\u060c \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0647\u06cc\u0686\u200c\u0648\u0642\u062a \u0645\u0646\u062a\u0638\u0631 \u06af\u0632\u0627\u0631\u0634 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0646\u0645\u0627\u0646. \u0633\u0639\u06cc \u06a9\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u062e\u0648\u062f\u0634 \u0642\u0628\u0644 \u0627\u0632 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0628\u0647 \u062a\u0648 \u0628\u06af\u0648\u06cc\u062f \u0686\u0647 \u0645\u0634\u06a9\u0644\u06cc \u062f\u0627\u0631\u062f. Logging \u0648 Crash Reporting \u062f\u0642\u06cc\u0642\u0627\u064b \u0628\u0631\u0627\u06cc \u0647\u0645\u06cc\u0646 \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647\u200c\u0627\u0646\u062f. \u0647\u0631\u0686\u0647 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u062f\u0642\u06cc\u0642\u200c\u062a\u0631 \u0648 \u0645\u0646\u0638\u0645\u200c\u062a\u0631\u06cc \u062b\u0628\u062a \u06a9\u0646\u06cc\u060c \u0632\u0645\u0627\u0646 \u06a9\u0645\u062a\u0631\u06cc \u0635\u0631\u0641 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0646 \u0628\u0627\u06af\u200c\u0647\u0627 \u062e\u0648\u0627\u0647\u06cc \u06a9\u0631\u062f \u0648 \u06a9\u06cc\u0641\u06cc\u062a \u0646\u0633\u062e\u0647\u200c\u0647\u0627\u06cc \u0628\u0639\u062f\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u06cc\u0634\u062a\u0631 \u062e\u0648\u0627\u0647\u062f \u0634\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u062f\u0631 \u067e\u0627\u06cc\u0627\u0646 \u0627\u06cc\u0646 \u0641\u0635\u0644\u060c \u0628\u062f \u0646\u06cc\u0633\u062a \u0686\u0646\u062f \u0627\u0634\u062a\u0628\u0627\u0647 \u0631\u0627\u06cc\u062c \u0631\u0627 \u0647\u0645 \u0645\u0631\u0648\u0631 \u06a9\u0646\u06cc\u0645. \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0627\u0632 <code>Log.d<\/code> \u062f\u0631 \u0633\u0631\u0627\u0633\u0631 \u067e\u0631\u0648\u0698\u0647\u060c \u062b\u0628\u062a Password \u06cc\u0627 Token \u062f\u0627\u062e\u0644 Log\u060c \u0646\u0648\u0634\u062a\u0646 \u0635\u062f\u0647\u0627 Log \u0628\u06cc\u200c\u0627\u0631\u0632\u0634\u060c Catch \u06a9\u0631\u062f\u0646 Exception \u0628\u062f\u0648\u0646 \u062b\u0628\u062a \u06cc\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0622\u0646\u060c \u0627\u0631\u0633\u0627\u0644 \u062a\u0645\u0627\u0645 Log\u0647\u0627 \u062f\u0631 \u0646\u0633\u062e\u0647 Release\u060c \u0648\u0627\u0628\u0633\u062a\u0647 \u06a9\u0631\u062f\u0646 \u06a9\u0644 \u067e\u0631\u0648\u0698\u0647 \u0628\u0647 Crashlytics \u0648 \u0646\u062f\u0627\u0634\u062a\u0646 \u06cc\u06a9 \u0644\u0627\u06cc\u0647 \u0645\u0631\u06a9\u0632\u06cc \u0628\u0631\u0627\u06cc Logging\u060c \u0627\u0632 \u0631\u0627\u06cc\u062c\u200c\u062a\u0631\u06cc\u0646 \u0627\u0634\u062a\u0628\u0627\u0647\u200c\u0647\u0627\u06cc\u06cc \u0647\u0633\u062a\u0646\u062f \u06a9\u0647 \u062f\u0631 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u0642\u0639\u06cc \u062f\u06cc\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u0646\u062f. \u0627\u06af\u0631 \u0627\u0632 \u0647\u0645\u0627\u0646 \u0627\u0628\u062a\u062f\u0627 \u06cc\u06a9 \u0645\u0639\u0645\u0627\u0631\u06cc \u062a\u0645\u06cc\u0632 \u0628\u0631\u0627\u06cc Logging \u0637\u0631\u0627\u062d\u06cc \u06a9\u0646\u06cc\u060c \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u0647\u0645\u0647 \u0627\u06cc\u0646 \u0645\u0634\u06a9\u0644\u0627\u062a \u0628\u0647\u200c\u0635\u0648\u0631\u062a \u062e\u0648\u062f\u06a9\u0627\u0631 \u0628\u0631\u0637\u0631\u0641 \u062e\u0648\u0627\u0647\u0646\u062f \u0634\u062f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0628\u0627 \u067e\u0627\u06cc\u0627\u0646 \u0627\u06cc\u0646 \u0641\u0635\u0644\u060c \u06cc\u06a9\u06cc \u0627\u0632 \u0645\u0647\u0645\u200c\u062a\u0631\u06cc\u0646 \u062a\u0641\u0627\u0648\u062a\u200c\u0647\u0627\u06cc \u0628\u06cc\u0646 \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647 \u0622\u0645\u0648\u0632\u0634\u06cc \u0648 \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647 Production \u0631\u0627 \u06cc\u0627\u062f \u06af\u0631\u0641\u062a\u06cc. \u062a\u0627 \u0642\u0628\u0644 \u0627\u0632 \u0627\u06cc\u0646 \u0634\u0627\u06cc\u062f \u0641\u06a9\u0631 \u0645\u06cc\u200c\u06a9\u0631\u062f\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u067e\u0627\u06cc\u0627\u0646 \u06a9\u0627\u0631 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u062f\u0631 \u0648\u0627\u0642\u0639 \u0627\u0646\u062a\u0634\u0627\u0631\u060c \u062a\u0627\u0632\u0647 \u0622\u063a\u0627\u0632 \u0645\u0631\u062d\u0644\u0647 \u0627\u0635\u0644\u06cc \u062a\u0648\u0633\u0639\u0647 \u0627\u0633\u062a. \u0627\u0632 \u0627\u06cc\u0646 \u0644\u062d\u0638\u0647 \u0628\u0647 \u0628\u0639\u062f\u060c \u06a9\u06cc\u0641\u06cc\u062a \u0628\u0631\u0646\u0627\u0645\u0647 \u062f\u06cc\u06af\u0631 \u0641\u0642\u0637 \u0628\u0627 \u062a\u0639\u062f\u0627\u062f \u0642\u0627\u0628\u0644\u06cc\u062a\u200c\u0647\u0627\u06cc \u0622\u0646 \u0633\u0646\u062c\u06cc\u062f\u0647 \u0646\u0645\u06cc\u200c\u0634\u0648\u062f\u061b \u0628\u0644\u06a9\u0647 \u0628\u0627 \u0627\u06cc\u0646 \u0633\u0646\u062c\u06cc\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f \u06a9\u0647 \u0647\u0646\u06af\u0627\u0645 \u0631\u062e \u062f\u0627\u062f\u0646 \u0645\u0634\u06a9\u0644\u060c \u0686\u0642\u062f\u0631 \u0633\u0631\u06cc\u0639 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc \u0639\u0644\u062a \u0631\u0627 \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc\u060c \u0622\u0646 \u0631\u0627 \u062a\u062d\u0644\u06cc\u0644 \u06a9\u0646\u06cc \u0648 \u0646\u0633\u062e\u0647\u200c\u0627\u06cc \u067e\u0627\u06cc\u062f\u0627\u0631\u062a\u0631 \u0645\u0646\u062a\u0634\u0631 \u06a9\u0646\u06cc. Logging \u0648 Crash Reporting \u062f\u0642\u06cc\u0642\u0627\u064b \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc\u06cc \u0647\u0633\u062a\u0646\u062f \u06a9\u0647 \u0627\u06cc\u0646 \u0686\u0631\u062e\u0647 \u0631\u0627 \u0645\u0645\u06a9\u0646 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f \u0648 \u0628\u0647 \u0647\u0645\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u062a\u0642\u0631\u06cc\u0628\u0627\u064b \u062f\u0631 \u062a\u0645\u0627\u0645 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646\u200c\u0647\u0627\u06cc \u062d\u0631\u0641\u0647\u200c\u0627\u06cc\u060c \u0627\u0632 \u0633\u0627\u062f\u0647\u200c\u062a\u0631\u06cc\u0646 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627 \u06af\u0631\u0641\u062a\u0647 \u062a\u0627 \u0628\u0632\u0631\u06af\u200c\u062a\u0631\u06cc\u0646 \u0634\u0628\u06a9\u0647\u200c\u0647\u0627\u06cc \u0627\u062c\u062a\u0645\u0627\u0639\u06cc \u062f\u0646\u06cc\u0627\u060c \u062c\u0627\u06cc\u06af\u0627\u0647\u06cc \u062b\u0627\u0628\u062a \u0648 \u062d\u06cc\u0627\u062a\u06cc \u062f\u0627\u0631\u0646\u062f.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0628\u062e\u0634 \u0647\u0634\u062a\u0645 \u2014 \u0639\u0645\u0644\u06a9\u0631\u062f \u062f\u0631\u0633 \u067e\u0646\u062c\u0627\u0647\u200c\u0648\u0686\u0647\u0627\u0631\u0645 Memory Memory \u062f\u0631 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u062f\u0642\u06cc\u0642\u0627\u064b \u0628\u0647 \u0686\u06cc \u0627\u0634\u0627\u0631\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0647\u061f \u0648\u0642\u062a\u06cc \u062f\u0631 \u0627\u0646\u062f\u0631\u0648\u06cc\u062f \u0627\u0632 Memory \u062d\u0631\u0641 \u0645\u06cc\u200c\u0632\u0646\u06cc\u0645\u060c \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0645\u0646\u0638\u0648\u0631\u0645\u0648\u0646 \u062d\u0627\u0641\u0638\u0647 RAM\u06cc\u0647 \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0646\u06af\u0627\u0645 \u0627\u062c\u0631\u0627 \u0645\u0635\u0631\u0641 \u0645\u06cc\u200c\u06a9\u0646\u0647\u061b \u06cc\u0639\u0646\u06cc \u062d\u0627\u0641\u0638\u0647\u200c\u0627\u06cc \u06a9\u0647 Object\u0647\u0627\u060c \u062a\u0635\u0648\u06cc\u0631\u0647\u0627\u060c \u0635\u0641\u062d\u0647\u200c\u0647\u0627\u06cc Compose\u060c \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0645\u0648\u0642\u062a\u060c Cache\u0647\u0627 \u0648 \u0646\u062a\u06cc\u062c\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0634\u0628\u06a9\u0647 \u062f\u0627\u062e\u0644\u0634 \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u0646. \u0627\u06cc\u0646 \u062d\u0627\u0641\u0638\u0647 \u0628\u0627 Storage \u0641\u0631\u0642 \u062f\u0627\u0631\u0647. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[15],"tags":[],"class_list":["post-6101","post","type-post","status-publish","format-standard","hentry","category-15"],"_links":{"self":[{"href":"https:\/\/notes.yummybrands.studio\/index.php?rest_route=\/wp\/v2\/posts\/6101","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/notes.yummybrands.studio\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/notes.yummybrands.studio\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/notes.yummybrands.studio\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/notes.yummybrands.studio\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6101"}],"version-history":[{"count":13,"href":"https:\/\/notes.yummybrands.studio\/index.php?rest_route=\/wp\/v2\/posts\/6101\/revisions"}],"predecessor-version":[{"id":6242,"href":"https:\/\/notes.yummybrands.studio\/index.php?rest_route=\/wp\/v2\/posts\/6101\/revisions\/6242"}],"wp:attachment":[{"href":"https:\/\/notes.yummybrands.studio\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6101"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/notes.yummybrands.studio\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6101"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/notes.yummybrands.studio\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6101"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}