[android] Android의 활동에 서비스 바인딩

RTSP를 사용하여 스트리밍 오디오를 재생하는 간단한 미디어 플레이어를 작성하려고합니다. GUI 활동과 재생을 수행하는 서비스가 있습니다. 내 질문은 활동과 서비스 사이에서 가장 잘 통신하는 방법입니다 (예 : 플레이어 상태에 따라 GUI 업데이트).

onBind ()를 사용하여 서비스를 활동에 바인딩 할 수 있다는 것을 알고 있지만 올바르게 이해하면 활동이 종료되면 서비스가 중지됩니다. 사용자가 활동을 종료하더라도 재생을 계속하고 싶습니다. 이 문제를 처리하는 표준 또는 선호하는 방법이 있습니까?



답변

startService(..)해당 서비스를 사용하여 Android 서비스를 시작 하면 명시 적으로를 호출 할 때까지 계속 실행 stopService(..)됩니다. 시스템에서 서비스를 실행할 수있는 두 가지 이유가 있습니다. 누군가 호출 Context.startService()하면 시스템이 서비스를 검색합니다 (서비스를 생성하고 다음과 같은 onCreate()경우 해당 메서드를 호출). 필요) 그런 다음 onStartCommand(Intent, int, int)클라이언트가 제공 한 인수를 사용하여 해당 메서드 를 호출합니다 .이 시점에서 서비스는 Context.stopService()또는 stopSelf()호출 될 때까지 계속 실행 됩니다. Context.startService()중첩되지 않는 여러 호출이를 여러 번 호출 onStartCommand()하므로 서비스가 시작된 횟수에 관계없이Context.stopService() 되거나 stopSelf()호출되지만 서비스는 해당 서비스를 사용할 수 있습니다.stopSelf(int) 시작된 인 텐트가 처리 될 때까지 서비스가 중지되지 않도록하는 메소드입니다.

클라이언트는 Context.bindService()서비스에 대한 지속적인 연결을 얻기 위해 사용할 수도 있습니다 . 마찬가지로 아직 실행 중이 아닌 경우 서비스를 생성 onCreate()하지만 (실행하는 동안 호출) 을 호출 하지 않습니다 onStartCommand(). 클라이언트는 IBinder서비스가 onBind(Intent)메서드 에서 반환 하는 객체를 수신하여 클라이언트가 서비스를 다시 호출 할 수 있도록합니다. 서비스는 연결이 설정되는 한 계속 실행됩니다 (클라이언트가 서비스의 참조를 유지하는지 여부에 관계없이 IBinder). 일반적으로 IBinder반환되는 것은 AIDL로 작성된 복잡한 인터페이스에 대한 것입니다.

서비스를 시작하고 연결을 바인딩 할 수 있습니다. 이러한 경우 시스템은 서비스가 시작되거나 Context.BIND_AUTO_CREATE플래그를 사용하여 하나 이상의 연결이있는 한 서비스를 계속 실행합니다 . 이러한 상황 중 어느 것도 유지되지 않으면 서비스의 onDestroy()메서드가 호출되고 서비스가 효과적으로 종료됩니다. 에서 돌아 오면 모든 정리 (스레드 중지, 수신자 등록 해제)가 완료되어야합니다 onDestroy(). “


답변

우선 우리가 이해해야 할 두 가지

고객

  • 특정 서버에 요청

    bindService(new
        Intent("com.android.vending.billing.InAppBillingService.BIND"),
            mServiceConn, Context.BIND_AUTO_CREATE);`
    

여기 mServiceConnServiceConnection클래스 (내장)의 인스턴스 가 있는데, 실제로 네트워크 연결 상태를 모니터링하기 위해 두 가지 (네트워크 연결의 경우 첫 번째, 연결되지 않은 두 번째) 방법으로 구현해야하는 인터페이스입니다.

섬기는 사람

  • 그것은 클라이언트의 요청을 처리하고 요청을 보내는 클라이언트에게만 개인 복제본을 만들고이 서버의 복제본은 다른 스레드에서 실행됩니다.

이제 클라이언트 측에서 서버의 모든 방법에 액세스하는 방법은 무엇입니까?

  • 서버는 IBind Object.so로 응답을 보냅니다. IBind 객체는 (.) 연산자를 사용하여 모든 서비스 방법에 액세스하는 핸들러입니다.

    MyService myService;
    public ServiceConnection myConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            Log.d("ServiceConnection","connected");
            myService = binder;
        }
        //binder comes from server to communicate with method's of 
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }
    

이제 서비스에있는 메소드를 호출하는 방법

myservice.serviceMethod();

여기 myService에 개체이며 serviceMethode서비스 방법입니다. 그리고 이러한 방식으로 클라이언트와 서버간에 통신이 설정됩니다.


답변

나는 전화를 시도했다

startService(oIntent);
bindService(oIntent, mConnection, Context.BIND_AUTO_CREATE);

결과적으로 고정 서비스를 만들고 바인딩 할 수 있습니다. Bound Service Example에 대한 자세한 자습서 .


답변

bindService를 호출 할 때 생성 할 ServiceConnection을받는 unbindService 라는 메서드 가 있습니다. 이렇게하면 서비스를 계속 실행하면서 서비스 연결을 끊을 수 있습니다.

활동을 다시 시작할 때 실행 중인지 여부를 알 수 없기 때문에 다시 연결할 때 문제가 될 수 있으므로 활동 코드에서이를 고려해야합니다.

행운을 빕니다!


답변

이것은 편향된 답변이지만 Android 서비스가 앱과 동일한 프로세스에서 로컬로 실행되는 경우 Android 서비스 사용을 단순화 할 수있는 라이브러리를 작성했습니다. https://github.com/germnix/acacia

기본적으로 @Service 및 해당 구현 클래스로 주석이 달린 인터페이스를 정의하면 라이브러리가 서비스를 생성 및 바인딩하고 연결 및 백그라운드 작업자 스레드를 처리합니다.

@Service(ServiceImpl.class)
public interface MyService {
    void doProcessing(Foo aComplexParam);
}

public class ServiceImpl implements MyService {
    // your implementation
}

MyService service = Acacia.createService(context, MyService.class);
service.doProcessing(foo);

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    ...
    <service android:name="com.gmr.acacia.AcaciaService"/>
    ...
</application>

연결된 android.app.Service의 인스턴스를 가져와 영구 알림을 숨기거나 표시하고, 자체 android.app.Service를 사용하고, 원하는 경우 수동으로 스레딩을 처리 할 수 ​​있습니다.


답변

사용자가 철회하면 onDestroy()메서드가 호출됩니다. 이 방법은 응용 프로그램에서 사용되는 모든 서비스를 중지하는 것입니다. 따라서 사용자가 애플리케이션을 종료하더라도 서비스를 계속하려면을 지우십시오 onDestroy(). 이 도움을 바랍니다.


답변