Whether or not components of other applications can invoke the service or interact with it — “true” if they can, and “false” if not. When the value is “false”, only components of the same application or applications with the same user ID can start the service or bind to it. The default value depends on whether the service contains intent filters. The absence of any filters means that it can be invoked only by specifying its exact class name. This implies that the service is intended only for application-internal use (since others would not know the class name). So in this case, the default value is “false”. On the other hand, the presence of at least one filter implies that the service is intended for external use, so the default value is “true”. This attribute is not the only way to limit the exposure of a service to other applications. You can also use a permission to limit the external entities that can interact with the service (see the permission attribute).
If set to true, this service will run under a special process that is isolated from the rest of the system and has no permissions of its own. The only communication with it is through the Service API (binding and starting).
这个比较简单,顾名思义也知道是让Service独立运行到一个特定进程中。
挖掘
既然搜也搜不到,官网也藏着掖着,那就只能我们自己挖掘了。这怎么少得了Read the fucking code呢? 这就要从系统启动App并解析Manifest文件开始说起了,我们只简要地分析一下: 1、SystemServer进程启动PackageManagerService(PMS)服务; 2、PMS扫描文件目录的过程,会调用到scanPackageLI方法,此方法中会实例化PackageParser,这是关键; 3、PackageParser会解析Manifest中的各种标签,其中parseService便是解析service的。
/** * Bit in {@link #flags}: If set, the service can be bound and run in the * calling application's package, rather than the package in which it is * declared. Set from {@link android.R.attr#externalService} attribute. */ publicstaticfinalintFLAG_EXTERNAL_SERVICE=0x0004;
顺便,我发现Context源码中也新增了一个bindService的flag:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/** * Flag for {@link #bindService}: The service being bound is an * {@link android.R.attr#isolatedProcess isolated}, * {@link android.R.attr#externalService external} service. This binds the service into the * calling application's package, rather than the package in which the service is declared. * <p> * When using this flag, the code for the service being bound will execute under the calling * application's package name and user ID. Because the service must be an isolated process, * it will not have direct access to the application's data, though. * * The purpose of this flag is to allow applications to provide services that are attributed * to the app using the service, rather than the application providing the service. * </p> */ publicstaticfinalintBIND_EXTERNAL_SERVICE=0x80000000;
/** Tests that BIND_EXTERNAL_SERVICE requires that an externalService be exported. */ publicvoidtestFailBindExternalNonExported() { Intentintent=newIntent(); intent.setComponent( newComponentName(sServicePackage, sServicePackage+".ExternalNonExportedService")); try { getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE); fail("Should not be able to BIND_EXTERNAL_SERVICE to non-exported service"); } catch (SecurityException e) { } }
/** Tests that BIND_EXTERNAL_SERVICE requires the service be an isolatedProcess. */ publicvoidtestFailBindExternalNonIsolated() { ... fail("Should not be able to BIND_EXTERNAL_SERVICE to non-isolated service"); ... }
3、没有用BIND_EXTERNAL_SERVICE进行绑定也是不行的:
1 2 3 4 5 6 7 8 9 10
/** Tests that an externalService can only be bound with BIND_EXTERNAL_SERVICE. */ publicvoidtestFailBindWithoutBindExternal() { Intentintent=newIntent(); intent.setComponent(newComponentName(sServicePackage, sServicePackage+".ExternalService")); try { getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE); fail("Should not be able to bind to an external service without BIND_EXTERNAL_SERVICE"); } catch (SecurityException e) { } }
Add external services, a way to run isolated processes as a different package.
This adds android:externalService boolean attribute to <service>. If that attribute is true, then bindService() may be called with BIND_EXTERNAL_SERVICE to create the new service process under the calling package's name and uid. The service will execute the code from the package in which it is declared, but will appear to run as the calling application.
External services may only be used if android:exported="false" and android:isolatedProcess="true".