[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);`
여기 mServiceConn
에 ServiceConnection
클래스 (내장)의 인스턴스 가 있는데, 실제로 네트워크 연결 상태를 모니터링하기 위해 두 가지 (네트워크 연결의 경우 첫 번째, 연결되지 않은 두 번째) 방법으로 구현해야하는 인터페이스입니다.
섬기는 사람
- 그것은 클라이언트의 요청을 처리하고 요청을 보내는 클라이언트에게만 개인 복제본을 만들고이 서버의 복제본은 다른 스레드에서 실행됩니다.
이제 클라이언트 측에서 서버의 모든 방법에 액세스하는 방법은 무엇입니까?
-
서버는 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()
. 이 도움을 바랍니다.