마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

큐와 스레드 를 사용하는데 앱이 자꾸 죽습니다.

0 추천
open class BaseSprayActivity : BaseActivity(), SerialInputOutputManager.Listener {
//usb 시리얼 통신 라이브러리를 참조하고 SerialInputOutputManager리스너를 장착합니다.
//SerialInputOutputManager 자체는 스레드입니다.  시리얼 통신으로 데이터를 받으면
//onNewData () 를 자동으로 호출합니다.

private var mavlinkpacketQueue: Queue<Byte> = LinkedList()  // 큐를 선언합니다.

override fun onNewData(data: ByteArray) {  // 데이터를 수신하면 자동 호출됩니다.
        mainLooper!!.post {
            receive(data)
        }
    }

    private fun receive(data: ByteArray) {

        val bufflen = data.size;

            for(i in 0..bufflen-1) {
                var ldata = data.get(i)
                mavlinkpacketQueue.add(ldata) // 큐에 수신된데이터를 입력합니다.
            }

    }

inner class readPaketThread: Thread() {

        override fun run() {

            var payload_len : Byte = 0
            var pack_size: Int = 0

            while(isRunning) {

                sleep(70)

                if(mavlinkpacketQueue.peek() == 0xFE.toByte())
                {
                    pack_size = mavlinkpacketQueue.size
                    payload_len = mavlinkpacketQueue.elementAt(1)

                    if(mavlinkpacketQueue.size < payload_len+8)
                        continue

                    var data = ByteArray(payload_len.toInt()+8)

                    for(j in 0..payload_len+8-1) {
                         data[j] = mavlinkpacketQueue.poll()  // 큐에 저장된 데이터를 읽습니다.
                    }

                    if(mavlinkpacketQueue.size >= 1000) {
                        mavlinkpacketQueue.clear()
                    }

                } else {
                      mavlinkpacketQueue.poll()
                }

            }

            super.run()
        }
    }
}

usb 시리얼통신으로 데이터를 받아서 큐에 저장하고 동시에 스레드로 큐에서 데이터를
읽어 들여 처리하는 소스 입니다.
아무 문제없다고 생각했는데 실행하면 앱이 죽습니다.  어떻게 해야 할지 모르겠습니다.
고수님들의 도움이 필요합니다.  감사합니다.
quantumy (350 포인트) 님이 2021년 6월 7일 질문

1개의 답변

+1 추천
 
채택된 답변

에러로그같은 실마리가 될만한 것들을 올려주시면 다른 분들이 원인을 찾는데  도움이 될 듯합니다.

가장 쉽게 해볼 수 있는 부분은  디버그를 하시거나 try catch로 해당 thread 에서 어떤 Exception이 발생하는지 확인해 보는 방법일 것 같습니다.

참고로 Thread에 사용되는 로직은 Thread-safe가 되어야 할 것 같은데, LinkedList 는 thread에 안전하지 않은 것으로 보입니다. 동시에 여러군데서 접근할 경우 문제가 될 수 있을 것 같습니다.

그리고 해당 UI에 접근하는 로직이 없다면 모든 동작을 백그라운드에 처리하시는 게 더 좋다고 생각됩니다. 예를 들면, receive 같은 함수가 그렇습니다.

라이프사이클도 체크해 보셔야 할 듯 합니다. 로직 전체를 알 수 없지만, 아마도 Activity/Fragment가 stop되거나 destory될 때 해당 thread는 계속 살아있을 가능성이 높아 보입니다. 라이플 사이클에 따라서 Thread의 중지, 시작, 취소, 대기 등의 처리를 하셔야할 것 같습니다.

그리고 모발앱에서는 절대로 sleep(70)같은 UI를 멈추게 하는 코드는 사용하시면 안됩니다. Handler.postDelayed, RxJava, Kotlin Coroutines같은 등등을 적절하게 사용하셔서 처리하시는 게 좋을 듯 합니다.

mavlinkpacketQueue.poll() 가 같은 코드를 사용하실 때는 반드시 먼저 Queue에 데이터가 존재하는지 체크하셔야 합니다.

 

spark (224,800 포인트) 님이 2021년 6월 7일 답변
quantumy님이 2021년 6월 14일 채택됨
감사합니다  try catch 로 문제점을 알아냈고 해결했습니다.
 Queue에 데이터가 존재하는지 확인하지 않아서 생긴 문제였습니다.
...