android – 在什么情况下bindService返回false?

前端之家收集整理的这篇文章主要介绍了android – 在什么情况下bindService返回false?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想知道Context.bindService()什么时候返回false?

我试图让onBind()返回null,但是当调用bindService并且onServiceConnected没有执行时它仍然返回true.我也在Google网上论坛上看到了此消息,但没有回复
https://groups.google.com/forum/#!topic/android-developers/ZLl56Mz1jYg

我也找不到bindService的实现,因为它在Context.java中是抽象的,并且搜索“public boolean bindService”也不会产生任何有用的结果(最接近的是ApplicationContext,它似乎不存在于当前的API级别中).

解决方法

binderService的实现是在 android.app.ConntextImpl
  1. 1412 public boolean bindService(Intent service,ServiceConnection conn,int flags,int userHandle) {
  2. 1413 IServiceConnection sd;
  3. 1414 if (conn == null) {
  4. 1415 throw new IllegalArgumentException("connection is null");
  5. 1416 }
  6. 1417 if (mPackageInfo != null) {
  7. 1418 sd = mPackageInfo.getServiceDispatcher(conn,getOuterContext(),1419 mMainThread.getHandler(),flags);
  8. 1420 } else {
  9. 1421 throw new RuntimeException("Not supported in system context");
  10. 1422 }
  11. 1423 try {
  12. 1424 IBinder token = getActivityToken();
  13. 1425 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
  14. 1426 && mPackageInfo.getApplicationInfo().targetSdkVersion
  15. 1427 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
  16. 1428 flags |= BIND_WAIVE_PRIORITY;
  17. 1429 }
  18. 1430 service.setAllowFds(false);
  19. 1431 int res = ActivityManagerNative.getDefault().bindService(
  20. 1432 mMainThread.getApplicationThread(),getActivityToken(),1433 service,service.resolveTypeIfNeeded(getContentResolver()),1434 sd,flags,userHandle);
  21. 1435 if (res < 0) {
  22. 1436 throw new SecurityException(
  23. 1437 "Not allowed to bind to service " + service);
  24. 1438 }
  25. 1439 return res != 0;
  26. 1440 } catch (RemoteException e) {
  27. 1441 return false;
  28. 1442 }
  29. 1443 }

从第1431行开始,您可以看到它调用ActivityManagerNative的bindService.
该实施是在com.android.server.am.ActivityManagerService

  1. 11070 public int bindService(IApplicationThread caller,IBinder token,11071 Intent service,String resolvedType,11072 IServiceConnection connection,int userId) {
  2. 11073 enforceNotIsolatedCaller("bindService");
  3. 11074 // Refuse possible leaked file descriptors
  4. 11075 if (service != null && service.hasFileDescriptors() == true) {
  5. 11076 throw new IllegalArgumentException("File descriptors passed in Intent");
  6. 11077 }
  7. 11078
  8. 11079 synchronized(this) {
  9. 11080 return mServices.bindServiceLocked(caller,token,service,resolvedType,11081 connection,userId);
  10. 11082 }
  11. 11083 }

所以它最终调用了bindeServiceLocked为com.android.server.am.ActiveServices.

更新:

通过读取binderServiceLocked()的代码

  1. 472 ServiceLookupResult res =
  2. 473 retrieveServiceLocked(service,474 Binder.getCallingPid(),Binder.getCallingUid(),userId,true);
  3. 475 if (res == null) {
  4. 476 return 0;
  5. 477 }
  6. 478 if (res.record == null) {
  7. 479 return -1;
  8. 480 }

发现如果retrieveServiceLocked()的结果为null,则返回false.
检查retrieveServiceLocked()的代码

  1. 721 ResolveInfo rInfo =
  2. 722 AppGlobals.getPackageManager().resolveService(
  3. 723 service,724 ActivityManagerService.STOCK_PM_FLAGS,userId);
  4. 725 ServiceInfo sInfo =
  5. 726 rInfo != null ? rInfo.serviceInfo : null;
  6. 727 if (sInfo == null) {
  7. 728 Slog.w(TAG,"Unable to start service " + service + " U=" + userId +
  8. 729 ": not found");
  9. 730 return null;
  10. 731 }

发现如果无法获取Service的ResolveInfo,则会出错.

所以我尝试删除AndroidManifest.xml中的Service声明,发现bindService()返回false.

猜你在找的Android相关文章