{"id":44095,"date":"2020-05-05T22:19:32","date_gmt":"2020-05-05T13:19:32","guid":{"rendered":"https:\/\/www.charlezz.com\/?p=44095"},"modified":"2020-05-05T23:25:29","modified_gmt":"2020-05-05T14:25:29","slug":"%ec%95%a1%ed%8b%b0%eb%b9%84%ed%8b%b0-%ea%b2%b0%ea%b3%bc-%ec%b2%98%eb%a6%ac%ed%95%98%ea%b8%b0-good-bye-startactivityforresult-onactivityresult","status":"publish","type":"post","link":"https:\/\/charlezz.com\/?p=44095","title":{"rendered":"\uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc \ucc98\ub9ac\ud558\uae30 (Good bye&#8230; startActivityForResult, onActivityResult)"},"content":{"rendered":"<p><a href=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/g-gif-update.gif\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/g-gif-update.gif\" alt=\"\" width=\"528\" height=\"77\" class=\"aligncenter size-full wp-image-44098\" \/><\/a><\/p>\n<p>\uc561\ud2f0\ube44\ud2f0(Activity)\ub294 \uc548\ub4dc\ub85c\uc774\ub4dc\uc758 \uc8fc\uc694 \ucef4\ud3ec\ub10c\ud2b8 \uc911 \ud558\ub098\ub85c \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \ud544\uc218\uc801\uc73c\ub85c \uc0ac\uc6a9\ub41c\ub2e4. 2007\ub144, \uc548\ub4dc\ub85c\uc774\ub4dc\uac00 \ub4f1\uc7a5\ud55c \ub4a4\ub85c \uc561\ud2f0\ube44\ud2f0\uac04\uc5d0 \ub370\uc774\ud130(\uc778\ud150\ud2b8)\ub97c \uc804\ub2ec\ud558\uace0, \uacb0\uacfc\ub97c \ucc98\ub9ac\ud560 \ub54c \uac1c\ubc1c\uc790\ub294 startActivityForResult()\uc758 \ud638\ucd9c\uacfc onActivityResult(requestCode, resultCode, data) \ucf5c\ubc31\ud638\ucd9c\uc744 \ub2e4\ub904\uc654\ub2e4.<\/p>\n<p>\uc0c8\ub85c\uc6b4 \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc(Activity Result) API\ub294 \uc9c0\uae08\uae4c\uc9c0 \ud574\uc624\ub358 \ubc29\ubc95\uc744 \uac1c\uc120\ud558\uc5ec \uc644\uc804\ud788 \uc0c8\ub85c\uc6b4 \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc \ucc98\ub9ac \ubc29\ubc95\uc744 \uc81c\uacf5\ud55c\ub2e4.<\/p>\n<p><iframe loading=\"lazy\" width=\"480\" height=\"270\" src=\"https:\/\/giphy.com\/embed\/11thnyggFkrmmc\" frameborder=\"0\" class=\"giphy-embed\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<h2>\uae30\uc874 \ubc29\ubc95\uc73c\ub85c \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc \uc804\ub2ec\ubc1b\uae30<\/h2>\n<p>\uc608\ub97c \ub4e4\uc5b4 \uce74\uba54\ub77c\ub098 \uac24\ub7ec\ub9ac \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uac8c \uc0ac\uc9c4\uc744 \uc694\uccad\ud558\uace0 \ud574\ub2f9 \uc571\uc73c\ub85c\ubd80\ud130 \uacb0\uacfc\ub97c \ubc1b\uc544 \ucc98\ub9ac\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc561\ud2f0\ube44\ud2f0 \ub610\ub294 \ud504\ub808\uadf8\uba3c\ud2b8\ub0b4\uc758 onActivityResult() \uba54\uc11c\ub4dc\ub97c \ub2e4\uc74c\uacfc \uac19\uc774 \ub2e4\ub8e8\uac8c \ub41c\ub2e4.<\/p>\n<pre class=\"lang: decode:true\">\/\/ \ub2e4\ub978 \uc561\ud2f0\ube44\ud2f0 \ud638\ucd9c\r\nstartActivityForResult(Intent(...))\r\n\r\n\/\/ \ub2e4\ub978 \uc561\ud2f0\ube44\ud2f0\ub85c\ubd80\ud130 \uc628 \uacb0\uacfc \ub2e4\ub8e8\uae30\r\nclass MainActivity : AppCompatActivity() {\r\n\r\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\r\n        super.onActivityResult(requestCode, resultCode, data)\r\n        if(requestCode == REQ_PHOTO &amp;&amp; resultCode == RESULT_OK){\r\n            ...\r\n        }else if(requestCode == REQ_VIDEO &amp;&amp; resultCode == RESULT_OK){\r\n            ...\r\n        }\r\n    }\r\n}<\/pre>\n<p>startAcitivtyForResult \ud638\ucd9c\uc5d0 \uc758\ud574 \uc0c8\ub85c\uc6b4 \uc561\ud2f0\ube44\ud2f0\uac00 \uc2dc\uc791\ub41c \ud6c4 \uba54\ubaa8\ub9ac \ubd80\uc871(\uc608: \uce74\uba54\ub77c) \ubb38\uc81c \ub4f1\uc73c\ub85c \uc774\uc804 \uc561\ud2f0\ube44\ud2f0\uac00 \uc885\ub8cc(Destroyed)\ub420 \uc218 \uc788\ub2e4. \uc548\ub4dc\ub85c\uc774\ub4dc\ub294 \uc774\ub7f0 \ud2b9\uc9d5\uc744 \uac00\uc9c0\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0 startActivityForResult(&#8230;) \uba54\uc11c\ub4dc\uc758 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ucf5c\ubc31 \uc778\uc790\ub97c \ub118\uae30\uc9c0 \uc54a\uace0 \uc774\ub97c \ub514\ucee4\ud50c\ub9c1\ud558\uc5ec \uc561\ud2f0\ube44\ud2f0 \ub0b4\uc758 onActivityResult(&#8230;) \uc5d0\uc11c \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc\ub97c \ucc98\ub9ac\ud558\ub3c4\ub85d \ud558\uace0 \uc788\ub2e4.<\/p>\n<h2>\uc0c8\ub85c\uc6b4 API\ub85c \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc \ucc98\ub9ac\ud558\uae30<\/h2>\n<p>AndroidX\uc758 <a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/activity#1.2.0-alpha02\">Activity 1.2.0-alpha02<\/a> \uc640 <a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/fragment#1.3.0-alpha02\">Fragment 1.3.0-alpha02<\/a> \ubd80\ud130\ub294 \uc0c8\ub85c\uc6b4 \ubc29\uc2dd\uc758 \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc API\ub97c \uc81c\uacf5\ud55c\ub2e4.\u00a0<\/p>\n<h3>\uc758\uc874\uc131 \ucd94\uac00\ud558\uae30<\/h3>\n<p>\uae00\uc744 \uc791\uc131\ud558\ub294 \uc9c0\uae08 \uc2dc\uc810\uc5d0\ub294 alpha04\uac00 \ucd5c\uc2e0 \ubc84\uc804\uc774\ub2e4.<\/p>\n<pre class=\"lang: decode:true\">implementation \"androidx.activity:activity:1.2.0-alpha04\"\r\nimplementation \"androidx.fragment:fragment:1.3.0-alpha04\"<\/pre>\n<p><em><strong>\ud604\uc7ac\ub294 alpha \uc2a4\ud14c\uc774\uc9c0\uc774\uae30 \ub54c\ubb38\uc5d0 \ud504\ub85c\ub355\ud2b8\uc5d0 \uc801\uc6a9\ud558\ub294 \uac83\uc740 \ucd94\ucc9c\ud558\uc9c0 \uc54a\ub294\ub2e4.<\/strong><\/em><\/p>\n<p>\uc0c8\ub85c\uc6b4 \ubc84\uc804\uc744 \ud655\uc778\ud558\uace0 \uc2f6\ub2e4\uba74 \uacf5\uc2dd \ub9b4\ub9ac\uc988 \ubb38\uc11c\ub97c \ucc38\uace0\ud558\uc790.<\/p>\n<ul>\n<li><a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/activity#version_120_2\">androidX activity \uacf5\uc2dd release \ubb38\uc11c<\/a><\/li>\n<li><a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/fragment#version_130_2\">androidX fragment \uacf5\uc2dd release \ubb38\uc11c<\/a><\/li>\n<\/ul>\n<h3>\uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc \ucc98\ub9ac\ud558\uae30<\/h3>\n<p><a href=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/MonthActivity.png\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/MonthActivity-512x1024.png\" alt=\"\" width=\"512\" height=\"1024\" class=\"aligncenter size-large wp-image-44097\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/MonthActivity-512x1024.png 512w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/MonthActivity-150x300.png 150w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/MonthActivity-768x1536.png 768w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/><\/a><\/p>\n<p>NumberActivity\uc5d0\uc11c \uc785\ub825\ubc1b\uc740 \uc815\uc218\ub97c MonthActivity\ub85c \uc804\ub2ec\ud558\uc5ec \uc6d4(month)\uc744 \ub098\ud0c0\ub0b4\uace0,<br \/>\nMonthActivity\ub97c \uc885\ub8cc\ud560 \ub54c \uc6d4 \ubb38\uc790\uc5f4\uc744 NumberActivity\ub85c \uc804\ub2ec\ud558\uc5ec \ud1a0\uc2a4\ud2b8\ub85c \ud654\uba74\uc5d0 \ub744\uc6b0\ub294 \uc608\uc81c\ub97c \uc0c8\ub85c\uc6b4 API\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub9cc\ub4e4\uc5b4\ubcf4\uc790.\u00a0<\/p>\n<p>\uc608\uc81c\ucf54\ub4dc\ub294 <a href=\"https:\/\/github.com\/Charlezz\/ActivityLaunchSample\">github<\/a>\uc5d0\uc11c \ub2e4\uc6b4\ub85c\ub4dc \uac00\ub2a5<\/p>\n<p>\uc0c8\ub85c\uc6b4 \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc \ucc98\ub9ac \ud504\ub85c\uc138\uc2a4\ub294 \ub2e4\uc74c\uacfc \uac19\uc774 3\ub2e8\uacc4\ub85c \uc694\uc57d\ud560 \uc218 \uc788\ub2e4.<\/p>\n<p><a href=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/ActivityResult_API_Process.png\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/ActivityResult_API_Process-1024x183.png\" alt=\"\" width=\"750\" height=\"134\" class=\"aligncenter wp-image-44096 size-large\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/ActivityResult_API_Process-1024x183.png 1024w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/ActivityResult_API_Process-300x54.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/ActivityResult_API_Process-768x137.png 768w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2020\/05\/ActivityResult_API_Process.png 1704w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/a><\/p>\n<h4>Contract \uc815\uc758\ud558\uae30<\/h4>\n<p>Contract\ub97c \ub9cc\ub4e4\uae30 \uc704\ud574\uc11c\ub294 ActivityResultContract&lt;I, O&gt;\ub77c\ub294 \ucd94\uc0c1 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ud55c \uc11c\ube0c\ud074\ub798\uc2a4\ub97c \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4. ActivityResultContract\ub294 \ub2e4\uc74c \ub450\uac00\uc9c0 \ucd94\uc0c1 \uba54\uc11c\ub4dc\ub97c \uac00\uc9c0\uace0 \uc788\ub2e4.<\/p>\n<pre class=\"lang:null decode:true lang:\">abstract class ActivityResultContract&lt;I, O&gt; {\r\n\r\n    abstract Intent createIntent(@NonNull Context context, I input);\r\n\r\n    abstract O parseResult(int resultCode, @Nullable Intent intent);\r\n\r\n}<\/pre>\n<ul>\n<li><strong>createIntent \uba54\uc11c\ub4dc<\/strong> : \ub2e4\ub978 \uc561\ud2f0\ube44\ud2f0\ub97c \ud638\ucd9c\ud558\uae30 \uc704\ud55c Intent\ub97c \uc0dd\uc131\ud55c\ub2e4. \uc81c\ub124\ub9ad \ud0c0\uc785 I\uac00 intent\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud55c \ub9e4\uac1c\ubcc0\uc218 \ud0c0\uc785\uc73c\ub85c \uc804\ub2ec\ub41c\ub2e4. <strong>(startActivityForResult \uba54\uc11c\ub4dc \ud638\ucd9c\uc744 \ub300\uccb4\ud55c\ub2e4.)<\/strong><\/li>\n<li><strong>parseResult \uba54\uc11c\ub4dc<\/strong> : \uc561\ud2f0\ube44\ud2f0\ub85c \uc804\ub2ec\ubc1b\uc740 \uacb0\uacfc \ub370\uc774\ud130\ub97c \uc81c\ub108\ub9ad O\ud0c0\uc785\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4. <strong>(onActivityResult \ucf5c\ubc31 \uba54\uc11c\ub4dc \ucc98\ub9ac\ub97c \ub300\uccb4\ud55c\ub2e4.)<\/strong><\/li>\n<\/ul>\n<p>MonthActivity\ub97c \uc2e4\ud589\ud558\uae30 \uc704\ud55c Contract\ub294 \ub2e4\uc74c\uacfc \uac19\uc774 \ub9cc\ub4e4\uc218 \uc788\ub2e4.<\/p>\n<pre class=\"lang: decode:true\">class MonthActivityContract : ActivityResultContract&lt;Int, String&gt;() {\r\n\r\n    override fun createIntent(context: Context, input: Int): Intent {\r\n        val intent = Intent(context, MonthActivity::class.java)\r\n        intent.putExtra(\"input\", input)\r\n        return intent\r\n    }\r\n\r\n\r\n    override fun parseResult(resultCode: Int, intent: Intent?): String? {\r\n        return when (resultCode) {\r\n            Activity.RESULT_OK -&gt; intent?.getStringExtra(\"result\")\r\n            else -&gt; null\r\n        }\r\n    }\r\n\r\n}<\/pre>\n<h4>Contract \ub4f1\ub85d\ud558\uae30<\/h4>\n<p>Contract\ub97c \uc815\uc758\ud588\ub2e4\uba74 resgisterForActivityResult \uba54\uc11c\ub4dc \ud638\ucd9c\uc744 \ud1b5\ud574 \ub2e4\uc74c\uacfc \uac19\uc774 \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc \ucf5c\ubc31\uc744 \ub4f1\ub85d \ud560 \uc218 \uc788\ub2e4.<\/p>\n<pre class=\"lang: decode:true\">private val launcher: ActivityResultLauncher&lt;Int&gt; = \r\nregisterForActivityResult(MonthActivityContract()) { result: String? -&gt;\r\n    result?.let {\r\n        Toast.makeText(this, it, Toast.LENGTH_LONG).show()\r\n    }\r\n}<\/pre>\n<p>registerForActivityResult \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\uba74 ActivityResultLauncher\ub97c \uc778\uc2a4\ud134\uc2a4\ub97c \ubc18\ud658\ud558\uac8c \ub41c\ub2e4.<\/p>\n<h4>Launcher\ub85c \uc561\ud2f0\ube44\ud2f0 \uc2e4\ud589\ud558\uae30<\/h4>\n<p>\uc774\uc81c Contract\ub97c \ub4f1\ub85d\ud558\uace0 \ub09c \ub4a4 \uc5bb\uc740 ActivityResultLauncher \uc778\uc2a4\ud134\uc2a4\ub85c \uc561\ud2f0\ube44\ud2f0\ub97c \uc2e4\ud589\ud560 \uc218 \uc788\uac8c \ub41c\ub2e4. ActivityResultLauncher\uc758 launch \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\uc5ec Contract\uc5d0 \uc815\uc758\ub41c \uc778\ud150\ud2b8\ub97c \ud1b5\ud574 Activity\ub97c \ud638\ucd9c\ud558\uac8c \ub418\ub294\ub370, \ub2e4\uc74c\uc758 \uc608\uc81c\ucf54\ub4dc\uc5d0\uc11c\ub294 EditText\uc5d0\uc11c \uc785\ub825\ubc1b\uc740 \uc815\uc218\ub97c Intent\uc758 Extra\ub85c \uc804\ub2ec\ud558\uae30 \uc704\ud574 launch \uba54\uc11c\ub4dc\uc758 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc804\ub2ec\ud558\uace0 \uc788\ub2e4.<\/p>\n<pre class=\"lang: decode:true\">val input = findViewById&lt;EditText&gt;(R.id.input)\r\nbtn.setOnClickListener {\r\n    var number: Int\r\n    try {\r\n        number = input.text.toString().toInt()\r\n        launcher.launch(number)\r\n    } catch (e: NumberFormatException) {\r\n        Toast.makeText(this, \"Please enter a number between 1 and 12\", Toast.LENGTH_SHORT).show()\r\n    }\r\n}<\/pre>\n<p><em>Note : \ud504\ub808\uadf8\uba3c\ud2b8 \ub610\ub294 \uc561\ud2f0\ube44\ud2f0\uac00 \uc0dd\uc131\ub418\uae30 \uc804\uc5d0 registerForActivityResult()\ub97c \ud638\ucd9c\ud574\ub3c4 \uc548\uc804\ud558\uc9c0\ub9cc, \ud504\ub798\uadf8\uba3c\ud2b8 \ub610\ub294 \uc561\ud2f0\ube44\ud2f0\uc758 Lifecycle \uc0c1\ud0dc\uac00 CREATED\uac00 \ub418\uae30 \uc804\uae4c\uc9c0\ub294 ActivityResultLauncher\ub97c \uc2dc\uc791\ud560 \uc218 \uc5c6\ub2e4.<\/em><\/p>\n<h3>\uae30 \uc815\uc758\ub41c Contract \uc0ac\uc6a9\ud558\uae30<\/h3>\n<p>ActivityResultContracts\ub97c \uc0ac\uc6a9\ud558\uba74 \uc774\ubbf8 \uc815\uc758\ub41c Contract\ub4e4\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.<\/p>\n<p>\uc608\ub97c \ub4e4\uc5b4 \uc0ac\uc9c4\uc744 \ubd88\ub7ec\uc640 ImageView\uc5d0 \uc801\uc6a9\ud558\uace0 \uc2f6\ub2e4\uba74, ActivityResultContracts.GetContent()\ub97c \ud638\ucd9c\ud560 \uc218 \uc788\ub2e4.<\/p>\n<pre class=\"lang: decode:true\">class PictureActivity : AppCompatActivity() {\r\n\r\n    lateinit var image: ImageView\r\n\r\n    private val launcher =\r\n        registerForActivityResult(ActivityResultContracts.GetContent()) { result: Uri? -&gt;\r\n            Glide.with(image).load(result).into(image)\r\n        }\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(R.layout.activity_picture)\r\n        image = findViewById(R.id.image)\r\n        findViewById&lt;Button&gt;(R.id.choose).setOnClickListener {\r\n            launcher.launch(\"image\/*\")\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>GetContent \uc774\uc678\uc5d0 \ud604\uc7ac \uae30 \uc815\uc758\ub41c Contract\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n<ul>\n<li>GetContent : \uc0ac\uc6a9\uc790\uac00 \uc120\ud0dd\ud55c \ucf58\ud150\ud2b8\uc758 Uri\ub97c \ubc18\ud658\ud55c\ub2e4.<\/li>\n<li>GetMultipleContent : \uc0ac\uc6a9\uc790\uac00 \uc120\ud0dd\ud55c 1\uac1c \uc774\uc0c1\uc758 \ucf58\ud150\uce20\ub4e4\uc774 List&lt;Uri&gt;\ud615\ud0dc\ub85c \ubc18\ud658\ub41c\ub2e4.<\/li>\n<li>TakePicturePreview : \uc0ac\uc9c4\uc744 \ucc0d\uace0 Bitmap\uc744 \ubc18\ud658\ud55c\ub2e4.<\/li>\n<li>TakePicture :\u00a0 \ucd2c\uc601\ud55c \uc0ac\uc9c4\uc744 \uc9c0\uc815\ud55c \uacbd\ub85c\uc5d0 \uc800\uc7a5\ud558\uace0 Bitmap\uc744 \ubc18\ud658\ud55c\ub2e4.<\/li>\n<li>TakeVideo : \ucd2c\uc601\ud55c \ube44\ub514\uc624\ub97c \uc9c0\uc815\ud55c \uacbd\ub85c\uc5d0 \uc800\uc7a5\ud558\uace0 \uc378\ub124\uc77c\uc744 Bitmap\uc73c\ub85c \ubc18\ud658\ud55c\ub2e4.<\/li>\n<li>CreateDocument : \uc0c8\ub85c\uc6b4 \ubb38\uc11c \uc791\uc131\ud558\uace0 \ud574\ub2f9 \uacbd\ub85c\ub97c Uri\ud615\ud0dc\ub85c \ubc18\ud658\ud55c\ub2e4.<\/li>\n<li>OpenDocument : \uc0ac\uc6a9\uc790\uac00 \uc120\ud0dd\ud55c \ubb38\uc11c\uc758 Uri\ub97c \ubc18\ud658\ud55c\ub2e4.<\/li>\n<li>OpenMultipleDocuments : \uc0ac\uc6a9\uc790\uac00 \uc120\ud0dd\ud55c 1\uac1c \uc774\uc0c1\uc758 \ubb38\uc11c\ub4e4\uc774 List&lt;Uri&gt; \ud615\ud0dc\ub85c \ubc18\ud658\ub41c\ub2e4.<\/li>\n<li>OpenDocumentTree : \uc0ac\uc6a9\uc790\uac00 \uc120\ud0dd\ud55c \ub514\ub809\ud1a0\ub9ac\uc758 Uri\ub97c \ubc18\ud658\ud55c\ub2e4.<\/li>\n<li>PickContact : \uc0ac\uc6a9\uc790\uac00 \uc120\ud0dd\ud55c \uc5f0\ub77d\ucc98\uc758 Uri\ub97c \ubc18\ud658\ud55c\ub2e4.<\/li>\n<li>RequestPermission : \ub2e8\uc77c \uad8c\ud55c\uc744 \uc694\uccad\ud558\uace0, \uc2b9\uc778 \uc5ec\ubd80\ub97c \ubc18\ud658\ud55c\ub2e4.<\/li>\n<li>RequestMultiplePermissions :\u00a0 \ub2e4\uc911 \uad8c\ud55c\uc744 \uc694\uccad\ud558\uace0, \uc2b9\uc778 \uc5ec\ubd80\ub97c Map&lt;String,Boolean&gt;\ud615\ud0dc\ub85c \ubc18\ud658\ud55c\ub2e4.<\/li>\n<li>StartActivityForResult : \uc694\uccad\ud55c \uc778\ud150\ud2b8\ub97c \ud1b5\ud574 \uc561\ud2f0\ube44\ud2f0\ub97c \uc2e4\ud589\ud558\uace0, \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc\ub97c ActivityResult\ub85c \ub798\ud551\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4.<\/li>\n<\/ul>\n<h2>\uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc API \ub0b4\ubd80 \uc0b4\ud3b4\ubcf4\uae30<\/h2>\n<p>\uc561\ud2f0\ube44\ud2f0\uac00 \uacb0\uacfc\ucc98\ub9ac\uac00 \uc5b4\ub5a4\uc2dd\uc73c\ub85c \ub0b4\ubd80\uc5d0\uc11c \uc77c\uc5b4\ub098\ub294\uc9c0 \uac04\ub2e8\ud788 \uc0b4\ud3b4\ubcf4\uc790.<\/p>\n<p>\uac00\uc7a5 \uba3c\uc800 registerForActivityResult \uba54\uc11c\ub4dc\uc758 \ud638\ucd9c\uc774 \uc5b4\ub5a4\uc2dd\uc73c\ub85c \ud504\ub808\uc784\uc6cc\ud06c \ub0b4\ubd80\uc5d0\uc11c \uc0b4\ud3b4\ubcf4\uc558\ub2e4.<\/p>\n<pre class=\"lang:null decode:true lang:\">public class ComponentActivity extends androidx.core.app.ComponentActivity implements\r\n        LifecycleOwner,\r\n        ViewModelStoreOwner,\r\n        HasDefaultViewModelProviderFactory,\r\n        SavedStateRegistryOwner,\r\n        OnBackPressedDispatcherOwner,\r\n        ActivityResultRegistryOwner,\r\n        ActivityResultCaller {\r\n\r\n    private ActivityResultRegistry mActivityResultRegistry = new ActivityResultRegistry() {\r\n        ...\r\n    };\r\n\r\n    @NonNull\r\n    @Override\r\n    public final &lt;I, O&gt; ActivityResultLauncher&lt;I&gt; registerForActivityResult(\r\n            @NonNull final ActivityResultContract&lt;I, O&gt; contract,\r\n            @NonNull final ActivityResultRegistry registry,\r\n            @NonNull final ActivityResultCallback&lt;O&gt; callback) {\r\n        return registry.register(\r\n                \"activity_rq#\" + mNextLocalRequestCode.getAndIncrement(), this, contract, callback);\r\n    }\r\n   \r\n    @NonNull\r\n    @Override\r\n    public final &lt;I, O&gt; ActivityResultLauncher&lt;I&gt; registerForActivityResult(\r\n            @NonNull ActivityResultContract&lt;I, O&gt; contract,\r\n            @NonNull ActivityResultCallback&lt;O&gt; callback) {\r\n        return registerForActivityResult(contract, mActivityResultRegistry, callback);\r\n    }\r\n    ...\r\n}<\/pre>\n<p>\ud574\ub2f9 \uba54\uc11c\ub4dc\ub294 <span>ActivityResultCaller \uc778\ud130\ud398\uc774\uc2a4\uc758 \uba54\uc11c\ub4dc\ub85c ComponentActivity\uac00 \uc774\ub97c \uad6c\ud604\ud558\uc600\ub2e4. <\/span>registerForActivityResult(ActivityResultContract, ActivityResultCallback) \ub97c \ud638\ucd9c\ud558\uac8c \ub418\uba74 ComponentActivity \ub0b4\ubd80\uc5d0 \uc788\ub294 ActivityResultRegistry \uc778\uc2a4\ud134\uc2a4\uc5d0 Contract\uac00 \ub4f1\ub85d\ub418\ub294 \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.\u00a0<\/p>\n<pre class=\"lang: decode:true\">    @NonNull\r\n    public final &lt;I, O&gt; ActivityResultLauncher&lt;I&gt; register(\r\n            @NonNull final String key,\r\n            @NonNull final LifecycleOwner lifecycleOwner,\r\n            @NonNull final ActivityResultContract&lt;I, O&gt; contract,\r\n            @NonNull final ActivityResultCallback&lt;O&gt; callback) {\r\n\r\n        final int requestCode = registerKey(key);\r\n        mKeyToCallback.put(key, new CallbackAndContract&lt;&gt;(callback, contract));\r\n\r\n        Lifecycle lifecycle = lifecycleOwner.getLifecycle();\r\n\r\n        final ActivityResult pendingResult = mPendingResults.getParcelable(key);\r\n        if (pendingResult != null) {\r\n            mPendingResults.remove(key);\r\n            if (lifecycle.getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {\r\n                callback.onActivityResult(contract.parseResult(\r\n                        pendingResult.getResultCode(),\r\n                        pendingResult.getData()));\r\n            } else {\r\n                lifecycle.addObserver(new LifecycleEventObserver() {\r\n                    @Override\r\n                    public void onStateChanged(\r\n                            @NonNull LifecycleOwner lifecycleOwner,\r\n                            @NonNull Lifecycle.Event event) {\r\n                        if (Lifecycle.Event.ON_CREATE.equals(event)) {\r\n                            callback.onActivityResult(contract.parseResult(\r\n                                    pendingResult.getResultCode(),\r\n                                    pendingResult.getData()));\r\n                        }\r\n                    }\r\n                });\r\n            }\r\n        }\r\n\r\n        lifecycle.addObserver(new LifecycleEventObserver() {\r\n            @Override\r\n            public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,\r\n                    @NonNull Lifecycle.Event event) {\r\n                if (Lifecycle.Event.ON_DESTROY.equals(event)) {\r\n                    unregister(key);\r\n                }\r\n            }\r\n        });\r\n\r\n        return new ActivityResultLauncher&lt;I&gt;() {\r\n            @Override\r\n            public void launch(I input, @Nullable ActivityOptionsCompat options) {\r\n                invoke(requestCode, contract, input, options);\r\n            }\r\n\r\n            @Override\r\n            public void unregister() {\r\n                ActivityResultRegistry.this.unregister(key);\r\n            }\r\n        };\r\n    }<\/pre>\n<p>\uadf8\ub9ac\uace0 ActivityResultRegistry.registry \uba54\uc11c\ub4dc \ub0b4\ubd80\ub97c \ub2e4\uc2dc \ud55c\ubc88 \uc0b4\ud3b4\ubcf4\ub2c8 mKeyToCallback\uc774\ub77c\ub294 HashMap\uc744 \uac00\uc9c0\uace0 \uc788\uace0, \uc790\ub3d9 \uc0dd\uc131\ub41c \uc720\ub2c8\ud06c\ud55c \ud0a4\uac12\uc73c\ub85c ActivityResultContract\uc640\u00a0 ActivityResultCallback\ub97c \ud558\ub098\ub85c \ubb36\uc740 CallbackAndContract \uc778\uc2a4\ud134\uc2a4\ub97c \ub9e4\ud551\ud55c\uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.\u00a0<\/p>\n<p>ComponentActivity \ub0b4\ubd80\uc5d0\uc11c \uc774\ub7f0\ubc29\uc2dd\uc73c\ub85c CallbackAndContract\ub97c \uad00\ub9ac\ud558\uace0 \uc788\ub2e4\uac00 \uc2e4\uc81c\ub85c \ub2e4\ub978 \uc561\ud2f0\ube44\ud2f0\ub85c \ubd80\ud130 \ub3cc\uc544\uc640 \uc561\ud2f0\ube44\ud2f0\uac00 \uc7ac\uac1c\ub418\uae30 \uc804\uc5d0 onActivityResult\uac00 \ud638\ucd9c\ub418\uba74 \uc801\uc808\ud55c \uc720\ud6a8\uc131 \uac80\uc0ac\ub97c \ud1b5\ud574 CallbackAndContract \uc778\uc2a4\ud134\uc2a4\ub97c \ucc38\uc870\ud558\uac8c \ub41c\ub2e4. ComponentActivity\uc758 onActivityResult\ubd80\ubd84\uc744 \ud655\uc778\ud574\ubcf4\uc790.<\/p>\n<pre class=\"lang:null decode:true lang:\">public class ComponentActivity extends androidx.core.app.ComponentActivity \r\n    implements ...{\r\n    \r\n    ...\r\n\r\n    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {\r\n        if (!mActivityResultRegistry.dispatchResult(requestCode, resultCode, data)) {\r\n            super.onActivityResult(requestCode, resultCode, data);\r\n        }\r\n    }\r\n\r\n    ...\r\n\r\n}<\/pre>\n<p>ComponentActivity \ub0b4\ubd80\uc5d0\uc11c \uac00\uc9c0\uace0 \uc788\ub294 ActivityResultRegistry\uc758 dispatchResult \uba54\uc11c\ub4dc \ud638\ucd9c\uc744 \ud1b5\ud574 \uc0c8\ub85c\uc6b4 API\ub85c \ub4f1\ub85d\ub41c \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc\uc778\uc9c0 \ud655\uc778\ud558\uac8c \ub41c\ub2e4. dispatchResult \ub0b4\ubd80\ub97c \uc880 \ub354 \uc0b4\ud3b4\ubcf4\uc790.<\/p>\n<pre class=\"lang:null decode:true lang:\">public abstract class ActivityResultRegistry {\r\n    \r\n    ...\r\n\r\n    @MainThread\r\n    public final boolean dispatchResult(int requestCode, int resultCode, @Nullable Intent data) {\r\n        String key = mRcToKey.get(requestCode);\r\n        if (key == null) {\r\n            return false;\r\n        }\r\n        doDispatch(key, resultCode, data, mKeyToCallback.get(key));\r\n        return true;\r\n    }\r\n\r\n    private &lt;O&gt; void doDispatch(String key, int resultCode, @Nullable Intent data,\r\n            @Nullable CallbackAndContract&lt;O&gt; callbackAndContract) {\r\n        if (callbackAndContract != null &amp;&amp; callbackAndContract.mCallback != null) {\r\n            ActivityResultCallback&lt;O&gt; callback = callbackAndContract.mCallback;\r\n            ActivityResultContract&lt;?, O&gt; contract = callbackAndContract.mContract;\r\n            callback.onActivityResult(contract.parseResult(resultCode, data));\r\n        } else {\r\n            mPendingResults.putParcelable(key, new ActivityResult(resultCode, data));\r\n        }\r\n    }\r\n\r\n    ...\r\n}<\/pre>\n<p>dispatchResult\uac00 \ud638\ucd9c\ub418\uc5c8\uc744 \ub54c mKeyToCallback\ub85c\ubd80\ud130 CallbackAndContract\ub97c \uac00\uc838\uc640 ActivityResultCallback\uc758 onActivityResult\ub97c \ud638\ucd9c\ud558\ub294 \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \uc774\ub294 \ucd5c\ucd08\uc5d0 \uc6b0\ub9ac\uac00 \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc \ucf5c\ubc31\uc774 \ud638\ucd9c\ub418\uae30\ub97c \uae30\ub300\ud558\uba70 registerForActivityResult\uc758 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc804\ub2ec\ud55c ActivityResultCallback\uc774\ub2e4.<\/p>\n<p>\ub9c8\ucc2c\uac00\uc9c0\ub85c \uad8c\ud55c \uc694\uccad \ucc98\ub9ac\uc5d0 \ub300\ud55c \uc751\ub2f5 \ub610\ud55c ComponetActivity\uc5d0\uc11c onActivityResult\uc640 \ub3d9\uc77c\ud55c \ubc29\uc2dd\uc73c\ub85c \ucc98\ub9ac\ud558\uace0 \uc788\ub2e4. \ub2e4\uc74c \ucf54\ub4dc\ub97c \ud655\uc778\ud574\ubcf4\uc790.<\/p>\n<pre class=\"lang:null decode:true lang:\">public class ComponentActivity extends androidx.core.app.ComponentActivity \r\n    implements ...{\r\n    public void onRequestPermissionsResult(\r\n            int requestCode,\r\n            @NonNull String[] permissions,\r\n            @NonNull int[] grantResults) {\r\n        if (!mActivityResultRegistry.dispatchResult(requestCode, Activity.RESULT_OK, new Intent()\r\n                .putExtra(EXTRA_PERMISSIONS, permissions)\r\n                .putExtra(EXTRA_PERMISSION_GRANT_RESULTS, grantResults))) {\r\n            if (Build.VERSION.SDK_INT &gt;= 23) {\r\n                super.onRequestPermissionsResult(requestCode, permissions, grantResults);\r\n            }\r\n        }\r\n    }\r\n}<\/pre>\n<h2>Conclusion<\/h2>\n<p>\uc815\ub9ac\ub97c \ud558\uc790\uba74, \uc0c8\ub85c\uc6b4 Activity Result API\ub97c \uc0ac\uc6a9\ud560 \ub54c \uc5bb\uc744 \uc218 \uc788\ub294 \uc7a5\uc810\uc740 \ud06c\uac8c 3\uac00\uc9c0\ub85c \uc694\uc57d\ud560 \uc218 \uc788\ub2e4.<\/p>\n<ul>\n<li><strong>\ub514\ucee4\ud50c\ub9c1 \ubc0f \uad00\uc2ec\uc0ac \ubd84\ub9ac<\/strong> : \uae30\uc874 \uc561\ud2f0\ube44\ud2f0 \ub610\ub294 \ud504\ub808\uadf8\uba3c\ud2b8\uc758 onActivityResult\uc5d0\uc11c if\uc640 else if\ub85c \ub3c4\ubc30\ub418\ub358 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\ub4e4\uc774 \ucf5c\ubc31\uba54\uc11c\ub4dc \ub610\ub294 <a href=\"https:\/\/developer.android.com\/training\/basics\/intents\/result#separate\">\ubd84\ub9ac\ub41c \ud074\ub798\uc2a4<\/a> \ub2e8\uc704\ub85c \ucabc\uac1c\uc5b4\uc838\uc11c \uad00\ub9ac\ub420 \uc218 \uc788\ub2e4. \uc774\ub294 \ucf54\ub4dc\uc758 \uac00\ub3c5\uc131\uc744 \ub192\uc774\uace0, \uc720\ub2db\ud14c\uc2a4\ud2b8\ub97c \uc218\uc6d4\ud558\uac8c \ud558\uba70, \uc720\uc9c0\ubcf4\uc218\uce21\uba74\uc5d0\uc11c\ub3c4 \ub9ce\uc740 \ub3c4\uc6c0\uc774 \ub41c\ub2e4.<\/li>\n<li><strong>Type-Safety<\/strong> : ActivityResultContract\ub294 \uc785\ub825 \ub370\uc774\ud130\uc640 \ucd9c\ub825 \ub370\uc774\ud130\uc758 \ud0c0\uc785\uc744 \uac15\uc81c\ud558\uae30 \ub54c\ubb38\uc5d0 \uc798\ubabb\ub41c \ud0c0\uc785\uc73c\ub85c \uce90\uc2a4\ud305\ud558\ub294 \uc0ac\uc18c\ud55c \uc2e4\uc218\ub97c \ubbf8\uc5f0\uc5d0 \ubc29\uc9c0\uc2dc\ucf1c\uc900\ub2e4.<\/li>\n<li><strong>NPE \ubc29\uc9c0<\/strong> : Intent\ub85c \ubd80\ud130 \ub370\uc774\ud130\ub97c \uc5bb\uc73c\ub824\uace0 \ud560 \ub54c NullPointerException\uc774 \ubc1c\uc0dd\ud558\ub294 \uacbd\ud5d8\uc744 \ub204\uad6c\ub098 \ud55c\ubc88\ucbe4\uc740 \ud574\ubcf4\uc558\uc744 \uac83\uc774\ub2e4. \uc0c8\ub85c\uc6b4 API\ub294 NPE\uac00 \ubc1c\uc0dd\ud560 \ud655\ub960\uc744 \uc904\uc5ec\uc904 \uac83\uc774\ub2e4.<\/li>\n<\/ul>\n<p>\uc548\ub4dc\ub85c\uc774\ub4dc \uac1c\ubc1c\uc5d0\uc11c \uac00\uc7a5 \uae30\ubcf8\uc774 \ub418\ub358 API\uc5d0 \ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d\uc774 \uc0dd\uae30\ub294 \uac83\uc73c\ub85c \ucd08\ubcf4 \uac1c\ubc1c\uc790\ub4e4\uc5d0\uac8c\ub294 \ud63c\ub780\uc744 \uc57c\uae30\ud558\uace0, \uc219\ub828\ub41c \uac1c\ubc1c\uc790\ub4e4\uc740 \ud658\ud638\uc131\uc744 \uc9c0\ub974\uac8c \ub420\uac83\uac19\ub2e4.\u00a0<\/p>\n<p>\uc544\uc9c1 \ub77c\uc774\ube0c\ub7ec\ub9ac\uac00 \uc54c\ud30c\uc2a4\ud14c\uc774\uc9c0 \uc774\ubbc0\ub85c startActivityForResult()\uc640 onActivityResult()\uc758 \uc874\ud3d0\uac00 \uc5b4\ub5a8\uc9c0\ub294 \ud655\uc2e4\ud558\uc9c0 \uc54a\uc73c\ub098, \ud604\uc7ac\uc2dc\uc810\uc5d0\uc11c @Deprecated \uc560\ub178\ud14c\uc774\uc158\uc774 \ubd99\uc740 \uac83\uc73c\ub85c \ubd24\uc744 \ub54c \uac1c\ubc1c\uc790\ub4e4\uc740 \ud544\uc218\uc801\uc73c\ub85c \uc774 \uc0c8\ub85c\uc6b4 \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc API\ub97c \ub2e4\ub8f0\uc904 \uc54c\uc544\uc57c \ud55c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.<\/p>\n<p>&nbsp;<\/p>\n<p><iframe loading=\"lazy\" width=\"480\" height=\"360\" src=\"https:\/\/giphy.com\/embed\/jfuKOYJ9vQiu4\" frameborder=\"0\" class=\"giphy-embed\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\uc561\ud2f0\ube44\ud2f0(Activity)\ub294 \uc548\ub4dc\ub85c\uc774\ub4dc\uc758 \uc8fc\uc694 \ucef4\ud3ec\ub10c\ud2b8 \uc911 \ud558\ub098\ub85c \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \ud544\uc218\uc801\uc73c\ub85c \uc0ac\uc6a9\ub41c\ub2e4. 2007\ub144, \uc548\ub4dc\ub85c\uc774\ub4dc\uac00 \ub4f1\uc7a5\ud55c \ub4a4\ub85c \uc561\ud2f0\ube44\ud2f0\uac04\uc5d0 \ub370\uc774\ud130(\uc778\ud150\ud2b8)\ub97c \uc804\ub2ec\ud558\uace0, \uacb0\uacfc\ub97c \ucc98\ub9ac\ud560 \ub54c \uac1c\ubc1c\uc790\ub294 startActivityForResult()\uc758 \ud638\ucd9c\uacfc onActivityResult(requestCode, resultCode, data) \ucf5c\ubc31\ud638\ucd9c\uc744 \ub2e4\ub904\uc654\ub2e4. \uc0c8\ub85c\uc6b4 \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc(Activity Result) API\ub294 \uc9c0\uae08\uae4c\uc9c0 \ud574\uc624\ub358 \ubc29\ubc95\uc744 \uac1c\uc120\ud558\uc5ec \uc644\uc804\ud788 \uc0c8\ub85c\uc6b4 \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc \ucc98\ub9ac \ubc29\ubc95\uc744 \uc81c\uacf5\ud55c\ub2e4. \uae30\uc874 \ubc29\ubc95\uc73c\ub85c \uc561\ud2f0\ube44\ud2f0 \uacb0\uacfc \uc804\ub2ec\ubc1b\uae30 \uc608\ub97c \ub4e4\uc5b4 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[5],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/44095"}],"collection":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=44095"}],"version-history":[{"count":3,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/44095\/revisions"}],"predecessor-version":[{"id":44102,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/44095\/revisions\/44102"}],"wp:attachment":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=44095"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=44095"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=44095"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}