4th Development Practice

13117 단어 SSACandroidSSAC

Thread

  • Context Switching
    //예제 1
    class MainActivity : AppCompatActivity() {

        var milk = 0

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)

            Thread() {
                for (i in 0 until 1001) {
                    println(i)
                }
            }

            Thread() {
                for (i in 1000 downTo 0) {
                    println(i)
                }
            }
        }
    }

    //예제 2
    class MainActivity : AppCompatActivity() {

        var milk = 0

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)

            Thread() {
                while(true) {
                    milk++
                }
            }.start()

            Thread() {
                while(true) {
                    milk--

                    if (milk < 0)
                        println("배고파")
                }
            }.start()
        }
    }

실제로 로그를 확인하면 배고파 라는 단어가 연속적으로 출력되지 않음, 눈에 보이지 않지만 milk 라는 변수가 0 아래에서 엎치랑 뒤치락 하는 중 -> Context Switching 은 언제 일어날지 모르기 때문에 배고파 라는 단어가 언제 나타날지 모름

    //예제 3
    class MainActivity : AppCompatActivity() {

        private lateinit var binding : ActivityMainBinding

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)

            binding = ActivityMainBinding.inflate(layoutInflater)
            val view = binding.root
            setContentView(view)

            var pictureChangeArrayList = ArrayList<Int>()

            pictureChangeArrayList.add(R.drawable.cat1)
            pictureChangeArrayList.add(R.drawable.cat2)
            pictureChangeArrayList.add(R.drawable.cat3)
            pictureChangeArrayList.add(R.drawable.cat4)

            Thread() {
                for (i in pictureChangeArrayList) {  //for-each문
                    Thread.sleep(1000)
                    binding.imgMain.setImageResource(i)
                }
            }.start()
        }
    }

에러 메세지 : original thread 에서만 뷰를 다룰 수 있다
메인 스레드를 제외한 다른 스레드에서는 뷰를 다룰 수 없다! -> handler 를 사용하면 해결! 원래 스레드가 아닌 다른 스레드에서도 뷰를 다룰 수 있다

    var handler = Handler(Looper.getMainLooper())

    Thread() {
        for (i in pictureArrayList) {  //for-each문
            Thread.sleep(1000)

            handler.post {
                binding.imgMain.setImageResource(i)
            }
        }
    }.start()

handler 를 선언하고 위의 코드를 아래처럼 수정하면 잘 돌아가는 것을 확인할 수 있다

좋은 웹페이지 즐겨찾기