Ste*_*han 6 service android ipc
我的应用使用其他(我的)应用提供的服务.我使用的绑定的服务机智Messenger访问和与它(和,因为它是一个不同的应用程序,它也是一个远程服务)进行通信.
当我打电话bindService了适当的意图,并调用返回false(如当APK提供服务不在身边预期),我从文档和示例代码假设,那我就不需要unbind了ServiceConnection.但是,当我在我的Galaxy Nexus(Jelly Bean)设备上这样做时,我ServiceConnectionLeaked在完成时得到了众所周知的信息Activity.
我通过这样做来挽救这一点
if (!ctxt.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)) {
try {
ctxt.unbindService(serviceConnection);
} catch (Throwable t) {}
// Clean up
return;
}
// Store serviceConnection for future use
Run Code Online (Sandbox Code Playgroud)
我很好奇:我是否只是遗漏了文档中的内容,是否应该以这种方式工作?我添加了try ... catch以确保即使此行为在其他设备或Android版本上确实不同,我的应用程序也不会(负面)受其影响.
一般来说,无论bindService()call是返回true还是false ,都始终由框架分配和注册ServiceConnection .请参阅android.app.ContextImpl中的 bindService()实现:
public boolean bindService(Intent service, ServiceConnection conn, int flags, int userHandle) {
IServiceConnection sd;
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
if (mPackageInfo != null) {
// A new ServiceDispatcher will be created and registered along with
// ServiceConnection in LoadedApk.mService for your application context.
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
mMainThread.getHandler(), flags);
} else {
throw new RuntimeException("Not supported in system context");
}
try {
... ...
return res != 0;
} catch (RemoteException e) {
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
根据官方开发指南的建议,您应该在完成服务后解除绑定,这是一种很好的编程方式:
要断开与服务的连接,请调用unbindService().
当您的客户端被销毁时,它将与服务解除绑定,但是当您完成与服务的交互或您的活动暂停时,您应始终取消绑定,以便服务可以在未使用时关闭.(下面将讨论绑定和解除绑定的适当时间.)
当框架开始执行最终清理(例如,当您的应用程序退出时)并发现存在未注册的ServiceConnection时,将引发ServiceConnectionLeaked,然后框架将尝试为您取消绑定.请参阅android.app.LoadedApk中的 removeContextRegistrations()实现:
public void removeContextRegistrations(Context context,
String who, String what) {
final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
... ...
//Slog.i(TAG, "Receiver registrations: " + mReceivers);
HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
mServices.remove(context);
if (smap != null) {
Iterator<LoadedApk.ServiceDispatcher> it = smap.values().iterator();
while (it.hasNext()) {
LoadedApk.ServiceDispatcher sd = it.next();
ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
what + " " + who + " has leaked ServiceConnection "
+ sd.getServiceConnection() + " that was originally bound here");
leak.setStackTrace(sd.getLocation().getStackTrace());
Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
if (reportRegistrationLeaks) {
StrictMode.onServiceConnectionLeaked(leak);
}
try {
ActivityManagerNative.getDefault().unbindService(
sd.getIServiceConnection());
} catch (RemoteException e) {
// system crashed, nothing we can do
}
sd.doForget();
}
}
mUnboundServices.remove(context);
//Slog.i(TAG, "Service registrations: " + mServices);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2006 次 |
| 最近记录: |