ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 Bound Service 예제
    안드로이드 학습/Android 기술면접 대비 코드 2023. 7. 3. 18:26

    서비스에 관한 설명 : https://from-android-to-server.tistory.com/38

     

    먼저 Bound Service를 4가지 이유때문에 사용된다

     

    • 컴포넌트 간의 직접적인 통신: Bound Service는 서비스와 클라이언트 컴포넌트(예: 액티비티) 간의 직접적인 통신을 가능하게 합니다. 클라이언트는 서비스 인스턴스에 직접 바인딩하여 서비스의 메서드를 호출하고 데이터를 전달할 수 있습니다. 이를 통해 클라이언트는 서비스의 기능을 직접 활용하고 조작할 수 있습니다.
    • 공유 데이터 또는 상태 유지: Bound Service를 사용하면 여러 클라이언트 컴포넌트가 하나의 서비스에 바인딩되어 동일한 서비스 인스턴스를 공유할 수 있습니다. 이를 통해 데이터나 상태를 서비스 내부에 유지하고 공유할 수 있습니다. 서비스는 클라이언트 간에 공유되는 중요한 데이터를 관리하거나, 응용 프로그램의 전반적인 상태를 유지할 수 있습니다.
    • 백그라운드 작업 수행:  Bound Service는 백그라운드에서 실행되는 동작을 수행하기에 적합합니다. 예를 들어, 네트워크 통신, 데이터베이스 작업, 오래 걸리는 계산 등을 비동기적으로 처리하고, 결과를 클라이언트로 전달할 수 있습니다. 이는 액티비티와의 분리된 실행 컨텍스트에서 비동기 작업을 수행하여 UI의 응답성을 유지하는 데 도움이 됩니다.
    • 생명주기 관리: Bound Service는 바인딩된 클라이언트의 생명주기에 맞추어 동작합니다. 클라이언트가 연결되어 있을 때에만 서비스가 실행되며, 클라이언트가 바인딩을 해제하면 서비스도 종료될 수 있습니다. 이를 통해 메모리와 시스템 리소스를 효율적으로 관리할 수 있습니다.

     

    Bound Service를 통해 Service와 Activity간의 데이터를 주고 받는 것 같다. 

     

    Service에 변수를 정의하고 Activity에서 정수를 +, - 해주는 예제를 만들어봤다. 

     

    1. MyService.kt

    class MyService : Service() {
    
        private val mBinder: IBinder = LocalBinder()
        private var number = 0
    
        override fun onBind(intent: Intent?): IBinder {
            return mBinder
        }
    
        override fun onCreate() {
            super.onCreate()
            number = 0
    
        }
        fun getNumber(): Int {
            return number
        }
    
        fun plusOne() {
            number++
        }
    
        fun minusOne() {
            number--
        }
    
        internal inner class LocalBinder : Binder() {
            val service: MyService
                get() = this@MyService
        }
    
    }

     

    2. MainActivity.kt

    class MainActivity : AppCompatActivity() {
    
        var myService: MyService? = null
        var isService = false // 서비스 중인 확인용
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val button1 = findViewById<Button>(R.id.button1)
            val button2 = findViewById<Button>(R.id.button2)
    
            val plusBtn = findViewById<Button>(R.id.plusBtn)
            val minusBtn = findViewById<Button>(R.id.minusBtn)
    
            button1.setOnClickListener {
                val intent = Intent(this@MainActivity, MyService::class.java)
                bindService(intent, conn, Context.BIND_AUTO_CREATE)
            }
    
            button2.setOnClickListener{
                if (!isService) {
                    Toast.makeText(applicationContext, "서비스중이 아닙니다, 데이터받을수 없음", Toast.LENGTH_LONG).show()
                    return@setOnClickListener
                }
                val num = myService!!.getNumber() //서비스쪽 메소드로 값 전달 받아 호출
                Toast.makeText(applicationContext, "받아온 데이터 : $num", Toast.LENGTH_LONG).show()
            }
    
            plusBtn.setOnClickListener{
                myService?.plusOne()
            }
    
            minusBtn.setOnClickListener{
                myService?.minusOne()
            }
        }
    
        var conn: ServiceConnection = object : ServiceConnection {
    
            // 서비스와 연결되었을 때 호출되는 메서드
            override fun onServiceConnected(name: ComponentName, service: IBinder) {
                val localBinder = service as LocalBinder // 서비스 객체를 전역변수로 저장
                myService = localBinder.service
                isService = true
            }
    
            // 서비스와 연결이 끊겼을 때 호출되는 메서드
            override fun onServiceDisconnected(name: ComponentName) {
                isService = false
                Toast.makeText(applicationContext, "서비스 연결 해제", Toast.LENGTH_LONG).show()
            }
        }
    }

     

    3. activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        
        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="300dp"
            android:text="바운드 서비스 시작"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/plusBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="+1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button1" />
    
        <Button
            android:id="@+id/minusBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="-1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/plusBtn" />
    
        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="서비스에서 데이터 확인하기"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/minusBtn" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

     

    4. AndroidManifest.xml

    <application
    
        ... 생략 ...
        
        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true" />
    
    </application>

     

    완성된 스크린샷

     

Designed by Tistory.