본문 바로가기
개발/일지

20.06.01.(월) 채팅 구현 with 서비스

by EPdev 2020. 6. 1.
728x90

TCP 소켓 통신을 통해 채팅을 구현하고 있다.

 

안드로이드 4대 컴포넌트 중 하나인 service를 이용해서 백그라운드에서도 채팅을 받아보고 알림을 뿌려주는 등의 기능을 하려고 한다.

 

문제는 어떻게 구현할 것인가..

 

서비스는 먼저 3가지로 나뉜다. 포어그라운드, 백그라운드, 바인드 서비스

 

포어그라운드는 사용자에게 뭔가 전시되어야할 때 사용한다. 알림을 띄워놓고 있어야하는게 특징이다.

예를 들어 뮤직앱을 볼 수 있다. 알림창에 계속 띄워지면서 어디서든 실행은 계속되고, 사용자와 상호작용을 할 수 있다.

 

백그라운드 사용자에게 보이지 않는 서비스. 예를 들어 다운로드 같은 행위가 될 수 있다.

 

바인드 사용자와 상호작용을 할 때 주로 사용된다. 특정 액티비티/프래그먼트가 서비스와 바인딩 된다고 보면 된다. 바인딩했던 것들이 모두 없어지면, 자동적으로 서비스가 멈춘다.

 

*** 서비스와 주로 비교되는 것이 쓰레드이다. 쓰레드는 보통 액티비티 안에서 통제되어야할 때 사용하는게 좋겠고, 서비스는 액티비티 밖에서도 뭔가 실행되어야할 때 사용하면 좋겠다. ***

 

서비스 클래스에는 크게 두가지가 있다.

첫 번째는 그냥 service 클래스를 이용하는 것이고,

두 번째는 IntentService 클래스를 이용하는 것이다.

둘의 차이는... 작업을 동시에 여러개 처리할 것이냐, 아니면 하나씩 처리할 것이냐의 차이다.

IntentService가 들어온 작업이 하나씩 처리되고, 그냥 service의 경우에는 동시에 여러 작업을 처리할 수 있다.(멀티쓰레딩에 사용한다고 보면 된다.) IntentService가 구현이 더욱 간단하니 참고하자.

간단히 이해해보자.. 백그라운드에서 10개의 파일을 동시에 받으려면 service! 10개의 파일을 순차적으로 받으려면 intentservice를 사용하면 될 거 같다. (주의할 점은 service의 경우에 기기의 성능을 저하할 수 있다.)

 

그냥 서비스와 바인드서비스의 차이를 보자.

그냥 서비스는 액티비티에서 startService를 할 때 처음만 데이터를 넘길 수 있다.

바인드 서비스는 액티비티에 서비스 객체를 생성해주기 때문에, 정보를 주고 받을 수 있다.

*** 한가지 주의할 점은 둘 중 하나만 사용해도 되고, 같이 사용해도 된다. 내가 뭘 하려는지 그 특성에 맞게 사용하면 되겠다. ***

난 채팅앱이기 때문에 ① 타인으로부터 채팅을 받을 때마다 알림을 보내줘야하고,

② "채팅 보내기"할 때마다 데이터를 서비스로 넘겨야한다.

그리고 서버로부터 받아온 데이터를 계속 화면에 띄워줄 필요도 있었다.

그래서 ①번 기능을 위해 IntentService로 초기 앱 실행할 때 서비스가 실행되도록 했다.

그리고 ②, ③번 기능을 위해 해당 액티비티에서 bindService를 해주려고 했다.

 

그런데 문제가 발생했다.

 

데이터를 서비스로 보내는 것은 문제가 없었다. 서비스 클래스에 함수를 하나 만들고 그 파라미터로 보내면 된다.

하지만 바인드 서비스에서 액티비티로 데이터를 가져오는 기본적인 방법은 바인드서비스 클래스에 선언된 메소드로 가져오는 것이다.

근데 내가 서비스를 최초 실행할 때 소켓을 생성해서 서버와 연결하고 바로 receive() 함수를 통해 데이터를 받고 있는 상황에서

액티비티 단에서 다시 receive() 를 선언하면 인풋스트림이 두개 생기는 것이다. 이게 되나? 가 문제였고.. 된다고 하더라도 데이터를 받을 때마다 중복된 값을 계속 받는것이 꽤 꺼림칙했다.

 

그래서 지금 생각하는 해결방안은

receive() 메소드에서 조건문을 통해 현재 바인드 된 상태라면 로컬브로드캐스트 리시버로 데이터를 보내주고,

바인드 되지 않았다면 알림을 만들어서 보내주는 것이다.

보낼 땐 서비스에 선언된 send() 함수를 이용하자.

 

조금 조잡해지는 거 같은데... 해결해보겠다.

728x90

댓글