Deperecated/Android_강의

안드로이드 - Fragment - IPC

누알라리 2020. 2. 19. 13:37
1. IPC란?

- Activity에서 실행 중인 서비스에 접속하여 그 서비스의 데이터를 사용하고자 할 때 사용하는 개념.

- Activity가 현재 실행중인 서비스에 접속하고 서브사가 가지고있는 메서드를 호출함으로써 값을 가져와 사용할 수 있다.

 

2. 서비스에 접속해서 데이터 가져오기.

1. Service()를 상속하는 서비스 클래스 생성하기.

2. Main에서 서비스를 실행시킨다.

    // 2.
    // 서비스를 실행시킨다.
    // 현재 실행중인 서비스의 목록을 순회하며 매개변수로 들어간 클래스이름과 같은 서비스가 없다면 return false.
    fun isServiceRunning(name:String):Boolean {
        var manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager

        // manager.getRunningServices(Int.MAX_VALUE) -> 현재 실행중인 서비스들의 정보가 넘어온다.
        for (service : ActivityManager.RunningServiceInfo in manager.getRunningServices(Int.MAX_VALUE))
        {
            if(service.service.className.equals(name))
            {
                return true
            }
        }
        return false
    }

3. IPC할 서비스 객체를 생성하고 실행시킨다.

        // 3. IPCService를 할 클래스 객체를 Intent에 넣어서 생성
        var intent = Intent(this, ServiceClass1::class.java)

        // 만일 실행중이 아니라면, 실행시킨다.
        if(!isServiceRunning("package com.example.hyunndy_01"))
        {
            startService(intent)
        }

4. 바인더 생성.

- IPC 개념을 사용하기 위해 액티비티에서 value값을 얻어올텐데 getNumber()을 사용해서 값을 얻어오려면 이 클래스의 객체를 생성하고 그 객체를 통해서 얻어오는 수 밖에 없다.
- 하지만 이 클래스의 객체는 안드로이드OS가 만드는거라 개발자의 입장에서 주소값을 직접적으로 가져올 수는 없다.
- 그래서 안드로이드에서는 Binder라는 클래스를 이용해서 액티비티-서비스의 중간단계 역할을 하게 한다.
- 따라서 액티비티에서 바인더객체를 통해 서비스에서 사용하는 값을 가져올 수 있다.

    // 4.
    // IPC 개념을 사용하기 위해 액티비티에서 value값을 얻어올텐데 getNumber()을 사용해서 값을 얻어오려면 이 클래스의 객체를 생성하고 그 객체를 통해서 얻어오는 수 밖에 없다.
    // 하지만 이 클래스의 객체는 안드로이드OS가 만드는거라 개발자의 입장에서 주소값을 직접적으로 가져올 수는 없다.
    // 그래서 안드로이드에서는 Binder라는 클래스를 이용해서 액티비티-서비스의 중간단계 역할을 하게 한다.
    // 따라서 액티비티에서 바인더객체를 통해 서비스에서 사용하는 값을 가져올 수 있다.
    fun getNumber() : Int{
        return value
    }

    // 5. 바인더 생성
    inner class LocalBinder : Binder()
    {
        // 바인더를 통해 서비스 객체의 주소값을 액티비티에게 반환.
        fun getService() : ServiceClass1{
            return this@ServiceClass1
        }
    }

5. 서비스 클래스안에서 바인더 객체 생성

    // 6. 바인더 객체 생성
    var binder : IBinder = LocalBinder()
    // 외부에서 서비스에 접속하게 되면 자동으로 onBind()가 호출된다.
    // 이 함수가 리턴하는 IBinder 객체를 액티비티에서 얻어와서 서비스가 사용하는 값을 사용할 수 있다.
    override fun onBind(intent: Intent): IBinder {
        return binder
    }

6. 커넥션 생성.

- 서비스 클래스의 OnBind() 메서드가 반환하는 Binder 객체가 이 OnServiceConnected에 넘어온다.

    // 7. 커넥션 생성
    // 서비스 클래스의 OnBind() 메서드가 반환하는 Binder 객체가 이 OnServiceConnected()에 넘어옵니다.
    private val mConnection = object : ServiceConnection
    {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {

            // 서비스 객체를 얻어온다!
            val binder = service as ServiceClass1.LocalBinder
            ipc_service = binder.getService()
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            ipc_service = null
        }
    }

7. 메인에서 IPC할 서비스 객체를 담을 변수를 생성.

    // 7. IPC 서비스객체를 받아올 변수
    var ipc_service:ServiceClass1? = null

8. 서비스에 접속!

- 서비스에 접속해서 서비스의 변수를 가져올 getter를 호출한다던지 값을 불러와서 작업한다.

        // 8.
        // 서비스에 접속!
        // bindService()를 안하고 그냥 startService()해버려도 켜지긴하는데 서비스 종료하면 그냥 강제종료되버려서 재접속 시 문제가 생길 수 있으므로 서비스 키고, 서비스에 접속하자.
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE)

        button.setOnClickListener { view ->
            var value = ipc_service?.getNumber()
            textView.text = "value : ${value}"
        }

9. 메인이 종료됨에따라 서비스 커넥션도 해제.

    // 9. 서비스 해제
    override fun onDestroy() {
        super.onDestroy()

        unbindService(mConnection)
    }

'Deperecated > Android_강의' 카테고리의 다른 글

안드로이드 - Activity Controller  (0) 2020.02.19
안드로이드 - Fragment  (0) 2020.02.19
안드로이드 - 서비스  (0) 2020.02.19
안드로이드 - 시스템 메세지  (0) 2020.02.19
안드로이드 - BroadCastReceiver  (0) 2020.02.19