2013-07-22 6 views
7

Ich frage mich, wann ist Context.bindService() zurückgeben false?In welchem ​​Fall liefert bindService false?

Ich habe versucht, das onBind() return null, zu machen, aber es gibt immer noch true wenn bindService genannt wird und die onServiceConnected ausgeführt werden soll nicht. Ich sah auch diese auf Google Groups ohne Antwort https://groups.google.com/forum/#!topic/android-developers/ZLl56Mz1jYg

ich auch nicht die Umsetzung von bindService finden, da sie abstrakt in Context.java ist und für „public boolean bindService“ gesucht ergeben keine brauchbaren Ergebnisse entweder (Am nächsten war ApplicationContext, das in den aktuellen API-Ebenen nicht vorhanden zu sein scheint).

Antwort

10

Die Implementierung von binderService ist in android.app.ConntextImpl:

1412 public boolean bindService(Intent service, ServiceConnection conn, int flags, int userHandle) { 
1413  IServiceConnection sd; 
1414  if (conn == null) { 
1415   throw new IllegalArgumentException("connection is null"); 
1416  } 
1417  if (mPackageInfo != null) { 
1418   sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), 
1419     mMainThread.getHandler(), flags); 
1420  } else { 
1421   throw new RuntimeException("Not supported in system context"); 
1422  } 
1423  try { 
1424   IBinder token = getActivityToken(); 
1425   if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null 
1426     && mPackageInfo.getApplicationInfo().targetSdkVersion 
1427     < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
1428    flags |= BIND_WAIVE_PRIORITY; 
1429   } 
1430   service.setAllowFds(false); 
1431   int res = ActivityManagerNative.getDefault().bindService(
1432    mMainThread.getApplicationThread(), getActivityToken(), 
1433    service, service.resolveTypeIfNeeded(getContentResolver()), 
1434    sd, flags, userHandle); 
1435   if (res < 0) { 
1436    throw new SecurityException(
1437      "Not allowed to bind to service " + service); 
1438   } 
1439   return res != 0; 
1440  } catch (RemoteException e) { 
1441   return false; 
1442  } 
1443 } 

Von Zeile 1431 können Sie sehen, es nennt bindService die ActivityManagerNative.
Diese Implementierung ist in com.android.server.am.ActivityManagerService:

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

so dass es schließlich die bindeServiceLocked von com.android.server.am.ActiveServices nennt.

Update:

durch den Code der binderServiceLocked lesen():

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

gefunden, dass, wenn das Ergebnis von retrieveServiceLocked() null ist, wird es false zurück.
SNach den Code retrieveServiceLocked()

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

gefunden, dass, wenn nicht die ResolveInfo of Service erhalten Überprüfung, wird es falsch. So

Ich versuchte zu entfernen die Service-Erklärung in AndroidManifest.xml und finde, dass der bindService() false zurück.

+0

Blick durch die Quelle von ActiveServices es scheint null Bindemittel zu akzeptieren und nur zurückgeben ok hinzufügen sollten. Irgendwie seltsam. –

+0

Bitte beachten Sie mein Update, ich fand einen Fall, dass bindService() false zurückgibt – Ivan

2

Ein sehr häufiger Fall, in dem bindService false zurückgibt, ist, wenn der Dienst nicht war. In diesem Fall können Sie Code wie unten zu sehen, um Ihre Manifest-Datei

<manifest ... > 
    ... 
    <application ... > 
     <service android:name=".ExampleService" /> 
     ... 
    </application> 
</manifest> 
Verwandte Themen