¿En qué caso se devuelve bindService?
Me preguntaba cuándo Context.bindService()
devuelve false
?
He intentado hacer que el onBind()
devuelva null
, pero todavía devuelve true
cuando bindService
es llamado y el onServiceConnected
no se ejecuta. También vi esto en Grupos de Google sin respuesta https://groups.google.com/forum/#!topic/android-developers/ZLl56Mz1jYg
- ¿Por qué se extiende ImageView marcado como error?
- Android Intent Context Confusing
- Qué es Android Context y por qué es necesario
- ¿Qué es "Contexto" en Android?
- Contexto de Android fuera de la clase de actividad
También no puedo encontrar la implementación de bindService, ya que es abstracto en Context.java y la búsqueda de "public boolean bindService" no produce ningún resultado útil tampoco (más cercano fue ApplicationContext que no parece estar presente en los niveles de API actuales ).
- ¿Por qué mi contexto en mi Fragmento es nulo?
- Diferencia entre getApplicationContext y classname.this
- Obtenga el contexto de aplicación de la clase singleton de no actividad
- ¿Cómo obtener mi contexto de actividad?
- No se puede hacer referencia estática al método no estático (Android getApplicationContext ())
- Get Context en la clase non-Activity
- SQlite Database: No se puede encontrar el contexto
- Todavía la confusión sobre el contexto
La implementación de binderService está en 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 }
Desde la línea 1431, puede ver que llama a bindService de ActivityManagerNative.
Esta implementación está en 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 }
Por lo que finalmente llama al bindeServiceLocked de com.android.server.am.ActiveServices .
Actualizar:
Leyendo el código de binderServiceLocked ():
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 }
Se encontró que si el resultado de retrieveServiceLocked () es nulo, se devolverá false.
SA después de comprobar el código de 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 }
Se encontró que si no puede obtener el ResolveInfo de servicio, será falsa.
Así que traté de eliminar la declaración de servicio en AndroidManifest.xml y encontrar que el bindService () devuelve false.
Un caso muy común en el que bindService devuelve false es si el servicio no fue declarado en el Manifiesto . En ese caso debe agregar código como se ve a continuación a su archivo de manifiesto
<manifest ... > ... <application ... > <service android:name=".ExampleService" /> ... </application> </manifest>
- Deshabilitar vínculos de WebView funciona en el emulador pero no en el dispositivo
- La aplicación se carga con una pantalla blanca durante 3 segundos antes de mostrar la interfaz de usuario adecuada – utilizando fragmentos (sin vista web)