Jun*_*Lee 6 java service android aidl
我正在编写一个简单的音乐播放器,并且创建了一个播放服务,它实现了一个 AIDL 接口来与客户端绑定,一个是简单的曲目浏览器,另一个是更简单的播放器活动。该服务控制 MediaPlayer 对象,而两个活动使用 ServiceConnections 来获取与该服务的连接。
这包含在两个活动的 onStart() 方法中:
@Override
public void onStart()
{
super.onStart();
Intent i = new Intent(this, PureService.class);
startService(i);
bindService(i, mConnection, 0);
}
Run Code Online (Sandbox Code Playgroud)
我这样做是为了让服务不会在解绑后立即停止。当然,这实际上并不是问题,因为我的活动根本拒绝与服务解除绑定。每当我的应用程序在这些活动中执行 unbindService 时,unbindService 每次都会抛出 IllegalArgumentException,无一例外(呵呵)。
在 onStop 方法中:
@Override
public void onStop()
{
super.onStop();
if (mBound) {
try {
unbindService(mConnection);
} catch (java.lang.IllegalArgumentException e)
{
//Print to log or make toast that it failed
}
}
mBound = false;
}
Run Code Online (Sandbox Code Playgroud)
我想知道的是:
提前致谢。
编辑:这是 ServiceConnection 覆盖
public void onServiceConnected(ComponentName className, IBinder service) {
mBound = true;
mService = IPureService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
Run Code Online (Sandbox Code Playgroud)
播放器活动中有一些额外的代码,但它与绑定本身无关。
首先,除非您确实需要跨进程调用此服务(即从其他 .apk,或者您出于某种原因使用 android:process 将您自己的 .apk 拆分为多个进程),那么我真的建议只放弃使用aidl。它更加复杂,但没有任何好处。服务文档中的“本地服务示例”展示了如何执行此操作:http://developer.android.com/reference/android/app/Service.html
其次,在开始的同时进行绑定强烈表明设计中存在一些基本缺陷。启动服务和绑定到服务在语义上非常不同,因此将根据这些不同的语义在不同的地方完成。也就是说,如果两者都完成了......事实上,这是一种不寻常的情况,您在同一个服务中同时使用启动和绑定。
在用于进行音乐播放的服务的类实现中,它将在主动执行播放时使用 start(因此,当用户不再主动与应用程序的 UI 交互时,其进程不会被系统终止)。当用户进入 UI 时启动服务可能会造成痛苦,因为现在服务的启动/停止状态没有明确定义——它可能会因为正在播放或用户碰巧进入而启动。应用程序的 UI,现在什么时候停止它合适?这会很麻烦。
现在至于何时取消绑定——您只需要确保始终将 unbindService() 与之前的 bindService() 相匹配。从你的代码片段来看,你似乎正在这样做,但其中有一些奇怪的事情,比如 mBound 从未被设置。事实上,如果您始终在 onStart() 中绑定并在 onStop() 中取消绑定,则永远不需要 mBound 来决定是否取消绑定,因为 onStop() 始终在 onStart() 之后调用。
因此,根据您在这里给出的代码,看起来没有问题。不过,如果您遇到异常,那么显然存在异常,因此它可能位于应用程序的其他位置。为了帮助缩小问题范围,您可以在调用bindService()时使用此标志,以便在发生故障时在日志中获取其他信息:http://developer.android.com/reference/android/content/Context.html# BIND_DEBUG_UNBIND