[Android TIL] 240403 (ํŒ€ํ”„๋กœ์ ํŠธ ๊ตฌํ˜„, ๊ฐ์ข… ์˜ค๋ฅ˜ ์ผ€์ด์Šค)
๋ฐ˜์‘ํ˜•

 

 

 

 

 

 

 

๐ŸŒฑ Today I Learned (์ง‘์ค‘ ์‹œ๊ฐ„ : 11์‹œ๊ฐ„ 35๋ถ„)

  1. (10:00 ~ 11:00 / 1์‹œ๊ฐ„) ๋ฐ์ผ๋ฆฌ ํŒ€์Šคํฌ๋Ÿผ ๋ฐ ํ”„๋กœ์ ํŠธ ํšŒ์˜
  2. (11:00 ~ 13:10 / 2์‹œ๊ฐ„ 10๋ถ„) MyActivity ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ฐ ๋ฆฌํŒฉํ† ๋ง, GitHub PR
  3. (13:00 ~ 13:25 / 25๋ถ„) TIL ์ž‘์„ฑ
  4. (14:10 ~ 18:00 / 3์‹œ๊ฐ„ 50๋ถ„) ํŒ€ํ”„๋กœ์ ํŠธ ๊ตฌํ˜„ (MyActivity ๋ฆฌํŒฉํ† ๋ง ๋ฐ 
  5. (19:30 ~ 22:00 / 2์‹œ๊ฐ„ 30๋ถ„) ํŒ€ํ”„๋กœ์ ํŠธ ๊ตฌํ˜„ ๋ฐ ํšŒ์˜, Develop ๋ธŒ๋žœ์น˜์— ํ•ฉ์น˜๊ณ  ๊ณตํ†ต์‚ฌํ•ญ ์ ์šฉ
  6. (22:00 ~ 23:30 / 1์‹œ๊ฐ„ 30๋ถ„) TIL ์ž‘์„ฑ์ค‘
  7. (์–ธ์ œ ํ•˜๋ƒ) ์Šคํƒ ๋‹ค๋“œ๋ฐ˜ ์‹ฌํ™” ๊ตฌํ˜„, ์ž…๋ฌธ ๊ณผ์ œ ๋ฆฌ๋ทฐ, ์ •์ฐฝ๊ฒฝ ๋ฆฌ๋ทฐ

*** ์ ์‹ฌ 13:00 ~ 14:00 / ์ €๋… 18:00 ~ 19:00 ์ œ์™ธ

โ€‹

 

 

1. ํŒ€ ํ”„๋กœ์ ํŠธ (MyActivity ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ฐ ๋ฆฌํŒฉํ† ๋ง, GitHub PR)

 

  • ๊ฐœ์ธ์ ์œผ๋กœ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ์ด์Šˆ๋ฅผ ์ ‘ํ•˜๊ณ  ์ˆ˜์ •ํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์กŒ๋‹ค.
  • ์œ ์šฉํ•œ ๋‹จ์ถ•ํ‚ค๋กœ shift + F6์ด ์žˆ์—ˆ๋‹ค. ํŒŒ์ผ/ํด๋ž˜์Šค/๋ณ€์ˆ˜ ๋“ฑ์—์„œ ์ž…๋ ฅ ์‹œ ํ•œ ๋ฒˆ์— ๋ ˆํผ๋Ÿฐ์Šค ์ด๋ฆ„๋“ค์ด ๋‚˜์˜ค๋ฉฐ, ์ด๋ฆ„์„ ์ˆ˜์ •ํ•˜๋ฉด ๋‹ค๋ฅธ ์œ„์น˜์—์„œ ์‚ฌ์šฉ๋œ ํŒŒ์ผ/ํด๋ž˜์Šค/๋ณ€์ˆ˜๋ช…์ด ์ˆ˜์ •๋œ ์ด๋ฆ„์— ์•Œ๋งž๊ฒŒ ํ•œ ๋ฒˆ์— ์ˆ˜์ •๋œ๋‹ค.

 

 

 

โ— ์ด์Šˆ 1. AVD ๊ตฌ๋™ ์‹œ ํ•˜์–€ ํ™”๋ฉด์ด ๋œจ๋Š” ์˜ค๋ฅ˜ ์›์ธ ์ฐพ๊ธฐ

    ๊ธฐ์กด ์ฝ”๋“œ
    val user: User by lazy {
        MemoryStorage.getUser()
    }
    
    ์ž„์‹œ ์ž‘๋™ ์ฝ”๋“œ
    val user: User by lazy {
        MemoryStorage.setUser(PreviewProvider.users[0])
        MemoryStorage.getUser()
    }
  • ๊ธฐ๋ณธ์ ์ธ ์ฝ”๋“œ๋ฅผ ๋‹ค ์ž‘์„ฑํ•˜๊ณ  ๋‚˜์„œ, ๋นŒ๋“œ๋Š” ๋˜๋Š”๋ฐ ํ•˜์–€ ํ™”๋ฉด์—์„œ ๋‚˜๊ฐ€์ง€๋Š” ์˜ค๋ฅ˜๊ฐ€ ์žˆ์—ˆ๋‹ค.
  • ์•„์ง ๋‹ค๋ฅธ ํŒ€์›๋ถ„์ด ์ž‘์„ฑํ•œ ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์—†์–ด MemoryStorage์˜ User๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ•˜์—ฌ ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜์˜€๋‹ค.
  • ์ž„์‹œ๋กœ setUser๋ฅผ ์ด์šฉํ•ด PreviewProvider์— ๋„ฃ์–ด๋†“์€ ์ž„์˜์˜ user๊ฐ’์„ ์„ธํŒ…ํ•ด์คฌ๋”๋‹ˆ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค.

 

 

 

โ— ์ด์Šˆ 2. ๋งค๋‹ˆํŽ˜์ŠคํŠธ ๊ถŒํ•œ ๋ถ€์—ฌ ์—ฌ๋ถ€

//deprecated๋œ ์ฝ”๋“œ, ์ง€๊ธˆ์€ ์ˆ˜์ •๋จ
	fun changeProfilePhoto(view: View) {
    val changePictureIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
        startActivityForResult(changePictureIntent, REQUEST_IMAGE_PICK)
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if(requestCode == REQUEST_IMAGE_PICK && resultCode == Activity.RESULT_OK && data != null){
            val selectedImageURI = data.data
            binding.imgProfile.setImageURI(selectedImageURI)
        }
    }
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
  • deprecated ๋œ ์ฝ”๋“œ๋ฅผ ์ ์šฉํ•˜๋˜ ๋‹น์‹œ์˜ ์ด์Šˆ๋‹ค. 
  • INTERNAL_CONTENT_URI๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ์šฐ ๋งค๋‹ˆํŽ˜์ŠคํŠธ์— ์Šคํ† ๋ฆฌ์ง€ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜์ง€ ์•Š์•„๋„ ์ž˜ ์ž‘๋™ํ•œ๋‹ค.

 

 

 

โ— ์ด์Šˆ3. displayUserInfo() ์„ค์ • ๋ฐฉ์‹

	๋ฌธ์ œ์˜ ์ฝ”๋“œ
    private fun displayUserInfo() {
        currentUser?.let { user ->
            binding.etName.setText(user.name)
            binding.etId.setText(user.id)
            binding.etBio.setText(user.bio)
            binding.etEmail.setText(user.email)
            binding.etPhone.setText(user.phoneNumber)
        }
        
        
        ์ˆ˜์ • ์ฝ”๋“œ (1์ฐจ)
    private fun displayUserInfo() {
        user.run {
            binding.etName.setText(name)
            binding.etId.setText(id)
            binding.etBio.setText(bio ?: " ")
            binding.etEmail.setText(email ?: " ")
            binding.etPhone.setText(phoneNumber ?: " ")
        }
    }
  • ์ฒ˜์Œ์— ์„ค์ •ํ–ˆ๋˜ ์ฝ”๋“œ๋Š” User๊ฐ€ null์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์ž…๋ ฅ๊ฐ’์„ User์— ๋„ฃ์–ด์ค€๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ณ  ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๋‹ค.
  • ์ผ๋‹จ user์˜ ์ผ๋ถ€ ๊ฐ’์ด ๋น„์–ด์žˆ๋Š” ๊ฒƒ์ด์ง€, user ์ž์ฒด๊ฐ€ null์ด ๋  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์ž˜๋ชป๋œ ์ฝ”๋“œ๋‹ค.
    ๊ฐ๊ฐ์˜ ์ž…๋ ฅ ๊ฐ’์ด null์ธ์ง€ ํ™•์ธํ•˜๊ณ , null ์ธ ๊ฒฝ์šฐ elvis ์—ฐ์‚ฐ์ž(?:)๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ณต๋ฐฑ์„ ๋„ฃ์–ด์ค€๋‹ค.
  • ์ฐธ๊ณ ๋กœ user.run์„ ์ด์šฉํ•˜๋ฉด this๊ฐ€ user๊ฐ€ ๋˜์–ด ๋”ฐ๋กœ user.name์„ ์ ์ง€ ์•Š๊ณ  name๋งŒ ์ ์–ด๋„ user์˜ name์„ ๋ฐ›๋Š”๋‹ค.
  • ์ด ๊ณผ์ •์—์„œ run๊ณผ apply์˜ ์ฐจ์ด์— ๋Œ€ํ•œ ์–˜๊ธฐ๊ฐ€ ์ข€ ์˜ค๊ณ ๊ฐ”๋‹ค. ๋Œ€๊ฐ• run์ธ ๊ฒฝ์šฐ ๋งˆ์ง€๋ง‰ ๋ผ์ธ์„ returnํ•˜๋Š” ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ, ์ด ๋ถ€๋ถ„์—์„œ ์–ด๋–ค ๊ฒƒ์„ ์ ์šฉํ•˜๋Š” ๊ฒŒ ์ข‹์€์ง€๋Š” ํŒ€ํ”„๋กœ์ ํŠธ ๋๋‚  ๋•Œ๊นŒ์ง€ ๋”... ์ฐพ์•„๋ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค.

 

        ์ˆ˜์ • ์ฝ”๋“œ(2์ฐจ)
        private fun displayUserInfo() {
        with(binding) {
            user.run {
                etName.setText(name)
                etId.setText(id)
                etBio.setText(bio ?: "")
                etEmail.setText(email ?: "")
                etPhone.setText(phoneNumber ?: "")
            }
        }
    }
  • with(binding)์œผ๋กœ ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๊น”๋”ํ•ด์กŒ๋‹ค.

 

 

 

โ— ์ด์Šˆ4. onCreate() ๋ธ”๋ก ๋‚ด์˜ ๊ฐ€๋…์„ฑ

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMyBinding.inflate(layoutInflater)
        setContentView(binding.root)

        displayUserInfo()
        clickDone()
        clickProfileChange()
        clickCancel()
        clickSwitchtoLogin()
    }
  • ์›๋ž˜๋Š” setOnClickListener๋ถ€ํ„ฐ ์˜จ๊ฐ– ๋‹ค์–‘ํ•œ ์ฝ”๋“œ๋ฅผ onCreate()์•ˆ์— ๋„ฃ์—ˆ์—ˆ๋Š”๋ฐ, PR๋กœ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
  • ์žฅ์ ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
    1) ๋‚˜์ค‘์— ์ฝ”๋“œ๊ฐ€ ์ปค์งˆ ์ˆ˜๋ก ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์—์„œ ์ข‹์Œ
    2) ์ฃผ์„์„ ์ผ์ผํžˆ ๋‹ฌ ํ•„์š” ์—†์ด, ํ•จ์ˆ˜ ๊ทธ ์ž์ฒด์˜ ์ด๋ฆ„์ด ์ฃผ์„์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ (๊ฐ€๋…์„ฑ ์ธก๋ฉด)

 

 

 

โ— ์ด์Šˆ5. Edittext ํฌ์ปค์Šค ์ด๋™ : ์—”ํ„ฐ๋ฅผ ๋ˆ„๋ฅด๊ฒŒ ๋˜๋ฉด ๋‹ค์Œ ๋ฒ„ํŠผ์œผ๋กœ ๊ฐ€๊ฒŒ๋” ์„ค์ •

 

  • ํ˜„์žฌ ์ƒํƒœ์—์„  Edittext์—์„œ ์—”ํ„ฐ๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋‘ ์ค„๋กœ ๋ณ€ํ•˜๋ฉด์„œ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฐ„์ด ๋Š˜์–ด๋‚œ๋‹ค.
  • ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์—”ํ„ฐ๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋ฐ”๋กœ ๋‹ค์Œ Edittext๋กœ ํฌ์ปค์Šค ์ด๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜๋‹ค.
  • binding.etId.requestFocus() ๋กœ ํฌ์ปค์Šค๋ฅผ ์ฃผ๊ณ  ๋‚˜์„œ, ์ž๋™์œผ๋กœ ํ‚คํŒจ๋“œ๊ฐ€ ์ถœ๋ ฅ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋”ฐ๋กœ
    val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    inputMethodManager.showSoftInput(etId, InputMethodManager.SHOW_IMPLICIT)
    ์ฒ˜๋Ÿผ ํ‚ค๋ณด๋“œ๋ฅผ ๋„์šฐ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๊ณ  ์‹คํ–‰์‹œ์ผœ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

→ ์ž๋™ ํฌ์ปค์Šค, ์ž๋™ ํ‚คํŒจ๋“œ ๊ธฐ๋Šฅ์ด ์žˆ์—ˆ๋‹ค!

์ž๋™ ํฌ์ปค์Šค, ์ž๋™ ํ‚คํŒจ๋“œ ๊ธฐ๋Šฅ ์˜ˆ์‹œ (nextFocusDown ์†์„ฑ ์ด์šฉ)

<LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

            <EditText
                    android:id="@+id/search_editText"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:nextFocusDown="@+id/๋‹ค์Œ ํฌ์ปค์Šค๋ฅผ ์ค„ ๋Œ€์ƒ์˜ id"
                    android:inputType="text"/>
</LinearLayout>
AndroidManifest.xml์˜ ํ•ด๋‹น ์•กํ‹ฐ๋น„ํ‹ฐ์— windowSoftInputMode="stateVisible" ์„ค์ •

<activity android:name=".@@@Activity"
                  android:windowSoftInputMode="stateVisible"
                  android:theme="@style/AppTheme"/>
  • ๊ทธ๋Ÿฌ๋‚˜ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ ์ถฉ๋Œ ๋“ฑ ํ˜„์žฌ๋กœ์„œ๋Š” ์ ์šฉ์ด ์• ๋งคํ•œ ๋ถ€๋ถ„์ด ์žˆ์–ด ๋‚˜์ค‘์— ๊ฐœ์ธ์ ์œผ๋กœ ๋‹ค์‹œ ์‹œ๋„ํ•ด ๋ณผ ์˜ˆ์ •์ด๋‹ค.

 

 

 

 

โ— ์ด์Šˆ6. buildString์œผ๋กœ ๊ฐ€๋…์„ฑ ๋ฐ ํšจ์œจ ๊ฐœ์„ 

// ๊ธฐ์กด ์ฝ”๋“œ
        if (daysDiff > 0) {
            if (daysDiff > 30) timeText = "${daysDiff / 30} months"
            else timeText = "${daysDiff} days "
        } else if (hourDiff > 0) {
            timeText = "${hourDiff} hours "
        } else if (minDiff > 0) {
            timeText = "${minDiff} minutes "
            
// ๋ณ€๊ฒฝ ์ฝ”๋“œ
            val timeText = buildString {
        if (daysDiff > 0) append("$daysDiff days ")
        if (hourDiff > 0) append("$hourDiff hours ")
        if (minDiff > 0) append("$minDiff minutes ")
    }
  • ๋‹ค๋ฅธ ํŒ€์› ๋ถ„์˜ ์ฝ”๋“œ๋ฅผ ๋ฆฌ๋ทฐํ•˜๋ฉฐ ๊ฐ€๋…์„ฑ ์ธก๋ฉด์—์„œ ์–ด๋Š ๋ฐฉ๋ฒ•์ด ์ข‹์„๊นŒ ์ƒ๊ฐํ•˜๋‹ค๊ฐ€ ์ฐพ์€ ๋ฐฉ์‹์ด๋‹ค.
  • ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฌธ์ž์—ด ๋’ค์— ๋ฌธ์ž์—ด์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์ˆ˜์ • ์ž‘์—…์˜ ๊ฒฝ์šฐ StringBuilder๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ž์› ๊ด€๋ฆฌ ๋ฐ ํšจ์œจ ์ธก๋ฉด์—์„œ ์ข‹๋‹ค๊ณ  ํ•œ๋‹ค. (์ถœ์ฒ˜: https://notepad96.tistory.com/96)
  • ๋”ํ•˜๊ธฐ ์—ฐ์‚ฐ ๊ฐ™์€ ๊ฒฝ์šฐ ๋ฌธ์ž์—ด ๋”ํ•˜๊ธฐ์ธ append๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜์ •ํ•˜์˜€๋‹ค.

 

 

 

 

โ— ์ด์Šˆ7. deprecated๋œ ์ฝ”๋“œ ์ˆ˜์ •

    fun changeProfilePhoto(view: View) {
        pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
    }
    private val pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
        uri?.let {
            binding.imgProfile.setImageURI(it)
        }
    }

 

 

์‚ฌ์ง„ ์„ ํƒ ๋„๊ตฌ  |  Android Developers

DataStore offers a more modern way of storing local data. You should use DataStore instead of SharedPreferences. Read the DataStore guide for more information. ์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ง„ ์„ ํƒ ๋„๊ตฌ ์ปฌ

developer.android.com

 

ํ™œ๋™์—์„œ ๊ฒฐ๊ณผ ๊ฐ€์ ธ์˜ค๊ธฐ  |  Android ๊ฐœ๋ฐœ์ž  |  Android Developers

์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ™œ๋™์—์„œ ๊ฒฐ๊ณผ ๊ฐ€์ ธ์˜ค๊ธฐ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. ์•ฑ ๋‚ด์—์„œ๋“  ๋‹ค๋ฅธ ์•ฑ์—์„œ๋“ 

developer.android.com

  • ์ด ๋ถ€๋ถ„์€ ์•„์ง ์ •๋ฆฌ์ค‘์ด๋ผ ๋‚ด์ผ TIL์— ๋” ์ž์„ธํžˆ ์ •๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋  ๊ฒƒ ๊ฐ™๋‹ค.
  • startActivityForResult(changePictureIntent, REQUEST_IMAGE_PICK) ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋˜ ๊ฒŒ deprecated๋œ ์ด์œ ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ธก๋ฉด์˜ ์ด์œ ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š” Activity๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋กœ์ง์„ ์‚ฌ์šฉํ•  ๋•Œ, ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์œผ๋กœ ์ธํ•ด ํ”„๋กœ์„ธ์Šค์™€ Activity๊ฐ€ ์‚ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค. (ํŠนํžˆ ์นด๋ฉ”๋ผ ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์ž‘์—…์€ ์†Œ๋ฉธ ํ™•๋ฅ ์ด ๊ต‰์žฅํžˆ ๋†’๋‹ค.)
    ์ถœ์ฒ˜: https://kimyunseok.tistory.com/40
  • URI๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค user์— ๋„ฃ์–ด์ค„ ๊ฑด๋ฐ ์ด ๋ถ€๋ถ„์€ ์ด์Šˆ8๋กœ ์ด์–ด์ง„๋‹ค.

 

 

 

 

โ— ์ด์Šˆ8. ์ด๋ฏธ ๋‹ค์–‘ํ•œ ์•กํ‹ฐ๋น„ํ‹ฐ์—์„œ ์ž‘์„ฑํ•œ User๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ

  • ์ดˆ๊ธฐ์— ํ”„๋กœ์ ํŠธ๋ฅผ ์„ธํŒ…ํ•  ๋•Œ ๊ณ ๋ คํ•˜์ง€ ๋ชปํ–ˆ๋˜ ๋ถ€๋ถ„์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค.
  • ํ”„๋กœํ•„ ์ด๋ฏธ์ง€๋ฅผ Uri๋‚˜ drawableResourceID ๋‘˜ ์ค‘ ํ•˜๋‚˜์˜ ํƒ€์ž…์œผ๋กœ ์„ ํƒ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„ธํŒ…ํ•ด๋†“์ง€ ๋ชปํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ „์ฒด์ ์œผ๋กœ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ์ผ๋“ค์ด ์ƒ๊ฒผ๋‹ค. ์ด๋ฏธ user์˜ image๋ฅผ ํŒ€์›๋“ค์ด ๋ชจ๋‘ ์‚ฌ์šฉํ•˜์…”์„œ, ๊ธฐ์กด์— ์ž‘์„ฑํ–ˆ๋˜ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒŒ ๋…ธ๊ฐ€๋‹ค๋ž€ ์ƒ๊ฐ์ด ๋“ค์–ด ๊ฐ ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ ์—†์ด ํ•˜๋Š”๋ฒ•์„ ์ฐพ์œผ๋ ค๊ณ  ๋…ธ๋ ฅ ์ค‘์ด์—ˆ๋‹ค
  • image๋ฅผ any ํƒ€์ž…์œผ๋กœ ํ• ๋‹นํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜๋ฉด ์–ด๋–จ๊นŒ, ์ €๋Ÿฌ๋ฉด ์–ด๋–จ๊นŒ ํŒ€์›๋“ค์˜ ์˜๊ฒฌ์ด ์žˆ์—ˆ๋‹ค.
  • ํŠœํ„ฐ๋‹˜๊ป˜ ์—ฌ์ญค๋ณด๋‹ˆ ์•„๋ž˜์™€ ๊ฐ™์€ ๋‹ต๋ณ€์„ ์–ป์—ˆ๋‹ค.
  • ์ƒ๊ฐ1) any ํƒ€์ž…์œผ๋กœ ๋ฐ”๊พธ๋ฉด ์–ด๋–จ๊นŒ?
    - any ํƒ€์ž…์€ ์•ˆ ์“ฐ๋Š”๊ฒŒ ์ข‹์Œ
    - ํƒ€์ž… ์ž์ฒด์˜ ์˜ค๋ฅ˜๊ฐ€ ๊ต‰์žฅํžˆ ๋งŽ์ด ๋‚˜๊ณ , ๋””๋ฒ„๊น… ๋น„์šฉ(๊ฐœ๋ฐœ์ž ๋น„์šฉ)์ด ๋งŽ์ด ๋“ฆ
    - Null๋กœ ์„ค์ •ํ•˜๋ฉด ์ ์–ด๋„ Null ์ธ์ง€ ์•„๋‹Œ์ง€์— ๋”ฐ๋ผ์„œ ํŒ๋‹จ์ด๋ผ๋„ ๊ฐ€๋Šฅํ•œ๋ฐ, any๋ฉด ๊ฐœ๋ฐœ์ž๋“ค๋„ ๋ฌธ์ œ ์‹œ ์•Œ ์ˆ˜๊ฐ€ ์—†์Œ
  • ์ƒ๊ฐ2) ์ง์ ‘ ๋ฐ”๊ฟ”์•ผ ํ•˜๋‚˜?
    - ํ˜„์—…์—์„œ๋„ ์ฒ˜์Œ๋ถ€ํ„ฐ ์™„๋ฒฝํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜์ง€ ๋ชปํ•œ๋‹ค. ์ˆ˜์ •ํ•ด์•ผ ํ•  ๋•Œ๋Š” ์ˆ˜์ •ํ•˜๋Š” ํŽธ์ด๋‹ค.
  • ์ƒ๊ฐ3) ์‚ฌ์ง„๊ณผ ๊ฐ™์ด ํ™•์žฅ์„ฑ์ด ์ข‹์€ sealed interface๋ฅผ ๋งŽ์ด ์“ด๋‹ค๊ณ  ํ•œ๋‹ค.

 

 

 

 

โ— ์ด์Šˆ9. ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ํŠน์ • ์•กํ‹ฐ๋น„ํ‹ฐ AVD ์ž‘๋™ํ•˜๊ธฐ

  • edit configuration - module - launch specified Activity ์„ค์ • ํ›„ apply ํ•˜๊ณ  Run
 

์‹คํ–‰/๋””๋ฒ„๊ทธ ๊ตฌ์„ฑ ์ƒ์„ฑ ๋ฐ ์ˆ˜์ •  |  Android Studio  |  Android Developers

์ฝ”๋“œ๋ฅผ ์‹คํ–‰, ๋””๋ฒ„๊ทธ, ํ…Œ์ŠคํŠธํ•  ๋•Œ Android ์ŠคํŠœ๋””์˜ค๋Š” ์‹คํ–‰/๋””๋ฒ„๊ทธ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…์„ ์‹คํ–‰ํ•  ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

developer.android.com

 

 

 

 

 

 

2. Git Troble Shooting

 

 

โ—์ด์Šˆ1. ๊นƒํ—ˆ๋ธŒ ์ž์ฒด ํด๋” ์ถ”๊ฐ€

 

[Git] ๊นƒํ—ˆ๋ธŒ ์ž์ฒด์—์„œ ํด๋” ์ถ”๊ฐ€, ํด๋” ์ด๋ฆ„ ๋ณ€๊ฒฝ ํ•˜๋Š” ๋ฒ•

ํŒ€์›๋“ค์ด ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” Develop ๋ธŒ๋žœ์น˜์— ์ ์šฉ๋  ๊ฐ„๋‹จํ•œ ํŒŒ์ผ์„ ๊นƒํ—ˆ๋ธŒ ์ƒ์—์„œ Add file๋กœ ์ถ”๊ฐ€ํ•˜๋Š”๋ฐ, ๋Œ€์ƒ ๊ฒฝ๋กœ์ธ ์ƒˆ๋กœ์šด ํด๋”๊ฐ€ ํ•„์š”ํ–ˆ๋‹ค. ํด๋” ํ•˜๋‚˜ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ ๋‹ค์‹œ Pullํ•˜๊ณ  ํŒŒ์ผ ๋งŒ๋“ค

limheejin.tistory.com

  • ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ฒŒ GitHub์—์„œ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

 

โ—์ด์Šˆ2. Develop ๋ธŒ๋žœ์น˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ ์šฉ๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๊ฐœ๋ฐœ ์ค‘ Pull ํ•˜๋Š” ์ƒํ™ฉ (์ถฉ๋Œ ๊ด€๋ฆฌ)

 

1. git branch (ํ˜„์žฌ ๋ธŒ๋žœ์น˜ ํ™•์ธ)
2. git status (ํ˜„์žฌ add๊ฐ€ ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ํŒŒ์ผ ํ™•์ธ)
3. git add, git status (ํ•„์š”ํ•œ ํŒŒ์ผ์„ addํ•˜๊ณ  status๋กœ ์ž˜ ์ถ”๊ฐ€๋๋‚˜ ํ™•์ธ)
4. git commit -m "" (ํ˜„์žฌ ๋ธŒ๋žœ์น˜์—์„œ add๋œ ์ง€๊ธˆ๊นŒ์ง€์˜ ๋‚ด์šฉ์„ ์ปค๋ฐ‹)
5. git pull origin ๊ฐ€์ ธ์˜ฌ๋ธŒ๋žœ์น˜๋ช… (๊ฐ€์ ธ์˜ฌ ๋ธŒ๋žœ์น˜์—์„œ pull)
	5.1) ์ด ๊ณผ์ •์—์„œ ๋‚ด ๋ธŒ๋žœ์น˜์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ๊ณผ CONFLICT๊ฐ€ ์กด์žฌํ•  ๊ฒƒ์ž„
6. CONFLICT๋‚œ ํŒŒ์ผ์„ ๋ชจ๋‘ ํ™•์ธํ•˜๊ณ , <<<HEAD ๋กœ์ปฌ์ฒด์ธ์ง€ == ๋ฆฌ๋ชจํŠธ์ฒด์ธ์ง€>>> ๋ถ€๋ถ„ ๋ชจ๋‘ ์ˆ˜์ •
7. git add, git commit
	7.1) (์˜ˆ) git commit -m "Merge branch 'develop' of https://github.com/Chapter-3-2-Android/SNS-APP"
	7.2) pullํ•œ ๋’ค ์ƒ๊ธด CONFLICT๋ฅผ ์ˆ˜์ •ํ•œ ํŒŒ์ผ๋“ค์„ ๋‹ค์‹œ add ํ›„ commit
8.git push (ํ˜„์žฌ ๋ธŒ๋žœ์น˜์— ๋ฐ˜์˜ ์™„๋ฃŒ)
  • conflict๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๋‹ค์‹œ ํ•ฉ์น˜๋Š” ๊ณผ์ •์—์„œ ๋งŽ์ด ํ—ท๊ฐˆ๋ ธ๋Š”๋ฐ, ์ด์ œ์„œ์•ผ ์ •๋ฆฝ์ด ๋๋‹ค.

 

 

 

 

๐Ÿ’ญ Retrospect

๊ณต๋ถ€๋“  ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋“  ํ˜ผ์ž ์ด๊ฒƒ์ €๊ฒƒ ์‚ฝ์งˆํ•˜๋Š” ๊ฒƒ์€ ๊ทธ ์ž์ฒด๋กœ ๋งค์šฐ ์ฆ๊ธฐ๋Š” ํŽธ์ธ๋ฐ, ์ฒซ ํŒ€ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋ฉด์„œ ๋“  ๊ฐ์ •์€ ์กฐ๊ธˆ ๋‹ค๋ฅธ ๊ฒƒ ๊ฐ™๋‹ค. '์•„. ํ˜ผ์ž์„œ ์‚ฝ์งˆํ•˜๋Š” ๊ฒƒ๋ณด๋‹จ ๋‹จ์ฒด๋กœ ์‚ฝ์งˆํ•˜๊ณ  ์˜๊ฒฌ์„ ์กฐ์œจํ•˜๋ฉฐ ํ•ด๊ฒฐํ•ด ๋‚˜๊ฐ€๋Š” ๊ฒŒ ๋ช‡ ๋ฐฐ๋Š” ๋” ์‰ฝ์ง€ ์•Š์€ ๋ฌธ์ œ๊ตฌ๋‚˜' ๋Š๋‚€๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋งŽ์€ ๊ฒƒ์„ ๋ฐฐ์šฐ๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ๋‹ค. ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋‚˜ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์— ์žˆ์–ด์„œ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•ด๋ณด์ง€ ๋ชปํ–ˆ๋˜ ์‹œ๊ฐ๊ณผ ์ •๋ณด๋ฅผ ๊ณต์œ  ๋ฐ›๋Š” ๊ฒŒ ์ข‹๋‹ค. 

ํด๋ฆฐ ์ฝ”๋“œ์˜ ์˜์—ญ์— ๋Œ€ํ•ด์„œ๋„ ๊ณ ๋ฏผ์ด ๊นŠ๋‹ค. '๋‚ด๊ฐ€ ๋ดค์„ ๋•Œ ์ดํ•ด๋˜๋Š” ์ฝ”๋“œ'๊ฐ€ ์•„๋‹ˆ๋ผ '๋‚จ๋“ค์ด ๋ดค์„ ๋•Œ๋„ ์‰ฝ๊ฒŒ ์ดํ•ด๋˜๋Š” ์ฝ”๋“œ'๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ํŒ€ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ  ๋‚˜์„œ์•ผ ๋น„๋กœ์†Œ ์ฒด๊ฐํ–ˆ๋‹ค. ๋‚ด๊ฐ€ ์ง  ์ฝ”๋“œ๋ฅผ ๋‚ด๊ฐ€ ๋ณด๋ฉด ๋‹น์—ฐํžˆ ์ดํ•ด๊ฐ€ ์ž˜ ๋  ์ˆ˜๋ฐ–์— ์—†๋‹ค. ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ์‚ฌ๋žŒ์˜ ์ž…์žฅ์—์„œ ์ƒ๊ฐํ•ด๋ณด์ž. ๊ฐ€๋…์„ฑ ์ธก๋ฉด, depth์— ๋Œ€ํ•ด์„œ๋„ ๋งŽ์ด ์ƒ๊ฐํ•˜๊ฒŒ ๋œ ํ•˜๋ฃจ๋‹ค.

 

 

 

 

๋ฐ˜์‘ํ˜•
 ๐Ÿ’ฌ C O M M E N T