如何访问 MediaBrowserServiceCompat 服务实例?
How to access instance of MediaBrowserServiceCompat service?
我出乎意料地努力获取派生自 MediaBrowserServiceCompat
的服务实例。
对于典型的服务,要实现这一点,使用本地绑定器
class MyService extends MediaBrowserServiceCompat {
class MyBinder extends Binder {
public MyService getService() {
return MyService.this;
}
private final MyBinder binder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public void doMagic() { // <-- How to call this from activity?
// ...
}
}
// At the activity, for example, this binder is retrieved through
// `onServiceConnected()`, typecast to `MyBinder` and thus
// `getService()` gets us the service instance.
但是,这不适用于从 MediaBrowserServiceCompat
派生的服务。
当我尝试提供本地活页夹时,如上所示,服务崩溃了,因为 MediaBrowserServiceCompat
需要它自己的具有附加功能的自定义活页夹。这是崩溃堆栈跟踪
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at android.os.Binder.queryLocalInterface(Binder.java:254)
at android.service.media.IMediaBrowserService$Stub.asInterface(IMediaBrowserService.java:31)
at android.media.browse.MediaBrowser$MediaServiceConnection.onServiceConnected(MediaBrowser.java:793)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1223)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1240)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
我试过从 MediaBrowserServiceCompat
super class 包装活页夹,如下所示,但仍然行不通。
class MyService extends MediaBrowserServiceCompat {
class MyBinder extends Binder {
public MyService getService() {
return MyService.this;
}
private final WrappingBinder<MyService> binder;
@Override
public IBinder onBind(Intent intent) {
if (binder == null) {
binder = new WrappingBinder(super.onBind(intent));
}
return binder;
}
public void doMagic() { // <-- How to call this from activity or elsewhere?
// ...
}
}
想知道访问 MediaBrowserServiceCompat 服务实例的方法是什么?
明确地说,播放功能对我来说工作正常。问题是关于如何获取服务的引用,以便我可以调用该服务上的自定义 public 方法。
如您所见,MediaBrowserServiceCompat
已经是绑定服务 - 您不能也不应该覆盖 onBind()
。
相反,您必须按照 the documentation 使用 MediaBrowserCompat
连接到您的 MediaBrowserServiceCompat
。连接后,您可以触发自定义方法,例如 doMagic
by:
- 从您的
MediaBrowserCompat
实例创建一个 MediaControllerCompat
,跟随 the documentation
- 致电
sendCommand
,传入唯一标识您的命令的 command
字符串(例如,doMagic
),您希望传递给该方法的任何参数,以及 ResultReceiver
(如果需要) return 值。
- 在使用您的
MediaBrowserServiceCompat
注册的 MediaSessionCompat.Callback
中,覆盖 onCommand() 并处理命令(例如,通过调用 doMagic
)。
中提供了此方法的示例
您可以试试这个解决方案(为了快速修复,不推荐):
private final MyBinder myBinder = new MyBinder();
@Nullable
@Override
public IBinder onBind(Intent intent) {
if (intent.getBooleanExtra("is_binding", false)) {
return myBinder;
}
return super.onBind(intent);
}
// Bind service in your activity:
Intent intent = new Intent(this, MyPlaybackService.class);
intent.putExtra("is_binding", true);
bindService(intent, this, Context.BIND_AUTO_CREATE);
我出乎意料地努力获取派生自 MediaBrowserServiceCompat
的服务实例。
对于典型的服务,要实现这一点,使用本地绑定器
class MyService extends MediaBrowserServiceCompat {
class MyBinder extends Binder {
public MyService getService() {
return MyService.this;
}
private final MyBinder binder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public void doMagic() { // <-- How to call this from activity?
// ...
}
}
// At the activity, for example, this binder is retrieved through
// `onServiceConnected()`, typecast to `MyBinder` and thus
// `getService()` gets us the service instance.
但是,这不适用于从 MediaBrowserServiceCompat
派生的服务。
当我尝试提供本地活页夹时,如上所示,服务崩溃了,因为 MediaBrowserServiceCompat
需要它自己的具有附加功能的自定义活页夹。这是崩溃堆栈跟踪
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at android.os.Binder.queryLocalInterface(Binder.java:254)
at android.service.media.IMediaBrowserService$Stub.asInterface(IMediaBrowserService.java:31)
at android.media.browse.MediaBrowser$MediaServiceConnection.onServiceConnected(MediaBrowser.java:793)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1223)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1240)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
我试过从 MediaBrowserServiceCompat
super class 包装活页夹,如下所示,但仍然行不通。
class MyService extends MediaBrowserServiceCompat {
class MyBinder extends Binder {
public MyService getService() {
return MyService.this;
}
private final WrappingBinder<MyService> binder;
@Override
public IBinder onBind(Intent intent) {
if (binder == null) {
binder = new WrappingBinder(super.onBind(intent));
}
return binder;
}
public void doMagic() { // <-- How to call this from activity or elsewhere?
// ...
}
}
想知道访问 MediaBrowserServiceCompat 服务实例的方法是什么?
明确地说,播放功能对我来说工作正常。问题是关于如何获取服务的引用,以便我可以调用该服务上的自定义 public 方法。
如您所见,MediaBrowserServiceCompat
已经是绑定服务 - 您不能也不应该覆盖 onBind()
。
相反,您必须按照 the documentation 使用 MediaBrowserCompat
连接到您的 MediaBrowserServiceCompat
。连接后,您可以触发自定义方法,例如 doMagic
by:
- 从您的
MediaBrowserCompat
实例创建一个MediaControllerCompat
,跟随 the documentation - 致电
sendCommand
,传入唯一标识您的命令的command
字符串(例如,doMagic
),您希望传递给该方法的任何参数,以及ResultReceiver
(如果需要) return 值。 - 在使用您的
MediaBrowserServiceCompat
注册的MediaSessionCompat.Callback
中,覆盖 onCommand() 并处理命令(例如,通过调用doMagic
)。
您可以试试这个解决方案(为了快速修复,不推荐):
private final MyBinder myBinder = new MyBinder();
@Nullable
@Override
public IBinder onBind(Intent intent) {
if (intent.getBooleanExtra("is_binding", false)) {
return myBinder;
}
return super.onBind(intent);
}
// Bind service in your activity:
Intent intent = new Intent(this, MyPlaybackService.class);
intent.putExtra("is_binding", true);
bindService(intent, this, Context.BIND_AUTO_CREATE);