
① 首先提供接口文件ISurfaceComposer.h
//frameworks\native\include\gui\ISurfaceComposer.h
//首先是接口,c++实现是虚函数
class ISurfaceComposer: public IInterface {
public:
DECLARE_META_INTERFACE(SurfaceComposer)
// flags for setTransactionState()
enum {
eSynchronous = 0x01,
eAnimation = 0x02,
}
enum {
eDisplayIdMain = 0,
}
/* create connection with surface flinger, requires
* ACCESS_SURFACE_FLINGER permission
*/
virtual sp<ISurfaceComposerClient>createConnection() = 0
}
② 建立BnSurfaceComposer
建立BnSurfaceComposer,需要重写BBinder的onTransact函数。
class BnSurfaceComposer: public BnInterface<ISurfaceComposer>{
public:
enum {
// Note: BOOT_FINISHED must remain this value, it is called from
// Java by ActivityManagerService.
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
CREATE_CONNECTION,
CREATE_GRAPHIC_BUFFER_ALLOC,
CREATE_DISPLAY_EVENT_CONNECTION,
CREATE_DISPLAY,
DESTROY_DISPLAY,
GET_BUILT_IN_DISPLAY,
SET_TRANSACTION_STATE,
AUTHENTICATE_SURFACE,
BLANK,
UNBLANK,
GET_DISPLAY_INFO,
CONNECT_DISPLAY,
CAPTURE_SCREEN,
}
virtual status_t onTransact(uint32_t code, const Parcel&data,
Parcel* reply, uint32_t flags = 0)
}
③ Bpxxx的实现
frameworks\native\libs\gui\ISurfaceComposer.cpp中,
//Bp实现,代理端
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
public:
BpSurfaceComposer(const sp<IBinder>&impl)
: BpInterface<ISurfaceComposer>(impl)
{
}
//代理接口
virtual sp<ISurfaceComposerClient>createConnection()
{
uint32_t n
Parcel data, reply
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor())
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply)
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder())
}
}
④ Bnxxx的实现
//Bn端,即server端
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel&data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply)
//createConnection就是server端的实现函数
sp<IBinder>b = createConnection()->asBinder()
reply->writeStrongBinder(b)
return NO_ERROR
}
default: {
return BBinder::onTransact(code, data, reply, flags)
}
}
// should be unreachable
return NO_ERROR
}
⑤ 注册service
通过上面几步已经完成了service的建立,我们需要将service注册到service manager中。
class SurfaceFlinger : public BnSurfaceComposer,
//在frameworks\native\services\surfaceflinger\main_surfaceflinger.cpp中,
// publish surface flinger
sp<IServiceManager>sm(defaultServiceManager())
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false)
⑥ 使用service
//首先获取代理端BpSurfaceComposer
sp<ISurfaceComposer>composer(ComposerService::getComposerService())
//直接调用代理BpSurfaceComposer的接口
sp<IGraphicBufferAlloc>alloc(composer->createGraphicBufferAlloc())
其中getComposerService()的实现为,
/*static*/ sp<ISurfaceComposer>ComposerService::getComposerService() {
ComposerService&instance = ComposerService::getInstance()
Mutex::Autolock _l(instance.mLock)
if (instance.mComposerService == NULL) {
ComposerService::getInstance().connectLocked()
assert(instance.mComposerService != NULL)
ALOGD("ComposerService reconnected")
}
return instance.mComposerService
}
void ComposerService::connectLocked() {
const String16 name("SurfaceFlinger")
//获取service,返回的mComposerService是BpSurfaceComposer,有了Bp就能直接调用代理接口了
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000)
}
assert(mComposerService != NULL)
// Create the death listener.
class DeathObserver : public IBinder::DeathRecipient {
ComposerService&mComposerService
virtual void binderDied(const wp<IBinder>&who) {
ALOGW("ComposerService remote (surfaceflinger) died [%p]",
who.unsafe_get())
mComposerService.composerServiceDied()
}
public:
DeathObserver(ComposerService&mgr) : mComposerService(mgr) { }
}
mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this))
mComposerService->asBinder()->linkToDeath(mDeathObserver)
}
java添加service
Android为了方便开发人员,提供了AIDL工具,简化了编写service的难度。下面以添加TestService这个服务为例,
① 编写AIDL文件
package android.app
interface ITestService {
boolean enableWifi(boolean enabled)
}
TestService的AIDL文件提供了一个接口,enableWifi()。
② 创建TestService服务
TestService 服务需要继承ITestService.Stub类,这个类就是通过AIDL工具对①中的AIDL文件处理后产生的,
class TestService extends ITestService.Stub {
//实现接口
public boolean enableWifi(boolean enabled)
{
......
}
}
③ Context.java中添加service名字字符串
// Context.java中添加service名字字符串
public static final String TEST_SERVICE = "my_test"
④ 向ServiceManager中注册service
java中大部分的系统service都是在SystemServer中去向service manager注册的,
//ServiceManager注册service
// 在SystemServer.java中,模仿其他向ServiceManager添加service的方法
try {
TestService myService = new TestService(context)
ServiceManager.addService(Context.TEST_SERVICE, myService)
} catch (Throwable e) {
reportWtf("register my test service fail", e)
}
⑤创建服务对应的Manager
对于每一个service而言,通常会有一个相关的Manager。 Managers提供API给app使用,成为SDK的一部分,是apps和remote service的中间桥梁。Manager中的接口和Service中的接口必须一一对应。
public class TestServiceManager{
private final ITestService mService
private final Context mContext
//构造函数中传入的service,其实就是BpTestService
TestServiceManager(Context context,ITestService service) {
mContext = context
mService = service
}
public boolean enableWifi(boolean enabled) {
try {
return mService.enableWifi(enabled)
} catch (RemoteException ex) {
}
return false
}
}
到目前为止,我们只是完成了Service的注册,但是还没有使用,该如何使用?
⑥ contextImpl中注册Manager
一旦我们实现了service和对应的Manager,需要有一种方法在app中调用他们。前面说过,Manager会成为SDK的一部分,供我们调用,那么Manager和Service是如何联系起来的?首先需要将我们的service和mangager注册到execution context,即contextImpl中,
registerService(TEST_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(TEST_SERVICE)
//asInterface(BpBinder)后就是BpTestService
ITestService service = ITestService.Stub.asInterface(b)
//创建TestServiceManager,第二个参数为BpBpTestService
return new TestServiceManager(ctx.getOuterContext(), service)
}})
registerService的第二个参数是一个ServiceFetcher对象,这里直接在调用时,新建了一个ServiceFetcher类,重写了createService方法。
ContextImpl.java中的registerService()方法,其核心就是把servicename和ServiceFetcher对象放到一个Hash的键值对中。
private static void registerService(String serviceName, ServiceFetcher fetcher) {
if (!(fetcher instanceof StaticServiceFetcher)) {
fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++
}
SYSTEM_SERVICE_MAP.put(serviceName, fetcher)
}
⑦ app如何使用service
那么app是如何调用的呢?
import android.app.TestServiceManager
import android.content.Context
TestServiceManager mTestServiceManager
mTestServiceManager=(TestServiceManager)context.getSystemService(Context.TEST_SERVICE)
然后直接调用TestServiceManager中的方法即可,其中的奥秘需要分析下getSystemService函数。
ContextImpl.java中,
@Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name)
//从ServiceFetcher 中获取service
return fetcher == null ? null : fetcher.getService(this)
}
getService()函数的核心就是上面重写的createService()函数,返回的就是TestServiceManager对象,所以通过context.getSystemService返回的是Manager对象。
public Object getService(ContextImpl ctx) {
ArrayList<Object>cache = ctx.mServiceCache
Object service
synchronized (cache) {
if (cache.size() == 0) {
// Initialize the cache vector on first access.
// At this point sNextPerContextServiceCacheIndex
// is the number of potential services that are
// cached per-Context.
for (int i = 0i <sNextPerContextServiceCacheIndexi++) {
cache.add(null)
}
} else {
service = cache.get(mContextCacheIndex)
if (service != null) {
return service
}
}
//调用重载的createService函数,返回的就是TestServiceManager对象
service = createService(ctx)
cache.set(mContextCacheIndex, service)
return service
}
}
Android开机启动Service,需要使用BroadcastReceiver,Android系统,开机会发送一个开机广播,可以通过BroadcastReceiver来接收开机广播。具体代码:
1.在配置文件AndroidManifest.xml中向系统注册receiver
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
2.需要添加相应权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
3.在Receiver中就可以添加开机需要进行的 *** 作
public class BootCompletedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
4.执行开机后的 *** 作,Intent intent = new Intent(context,Service.class)context.startService(intent)这样即可开机启动Service了。
1. 在android/app/目录下创建接口文件IServiceTest.aidlpackage android.app
oneway interface IServiceTest
{
void show()
}
2. 在Android.mk文件中的变量LOCAL_SRC_FILES中加入core/java/android/app/IServiceTest.aidl
如果要在sdk中发布这个服务就在变量aidl_files中加入一样的路径。
3. 通过aidl编译器编译IServiceTest.aidl,会生成一个IServiceTest.java文件。
4. 创建服务类ServiceTestSerice
class ServiceTestSerice extends IServiceTest.Stub{
private static final String TAG = “ServiceTestSerice”
Context mContext
public ServiceTestSerice(Context context){
mContext = context
}
public void show() throws RemoteException {
System.out.println(“My ServiceTestSerice”)
}
}
.5. 注册服务
Java系统服务在ServerThread类的run()方法中生成并注册到android平台,生成ServiceTestSerice实例对象,通过ServiceManager的addService方法将服务注册到系统中。
try{
serviceTestSerice = new ServiceTestSerice(context)
ServiceManager.addService(Context.SERVICE_TEST, serviceTestSerice)
} catch (Throwable t) {
}
ServiceTestSerice serviceTestSerice;
以上代码在ServerThread类的run()方法中。
在Context类中加入:
public static final StringSERVICE_TEST = “servicetest”
ServiceTestManager sServiceTestManager
6. 使用系统服务
编写一个ServiceTestManager类,为包装类。
public class ServiceTestManager{
private final IServiceTest mService
ServiceTestManager(IServiceTest service){
mService = service
}
public void test(){
try{
mService. show()
} catch (RemoteException ex){
}
}
}
7 提供应用层开发接口
在ContextImpl类中的getSystemService()方法中加入如下代码:
else if (SERVICE_TEST.equals(name)){
return getServiceTestManager()
}
private ServiceTestManager getServiceTestManager(){
synchronized(sSync) {
if (sServiceTestManager == null){
IBinder b = ServiceManager.getService(SERVICE_TEST)
IServiceTest service = IServiceTest.Stub.asInterface(b)
sServiceTestManager = new ServiceTestManager(service)
}
}
调用过程如下:
ServiceTestManager manager= (ServiceTestManager) getSystemService(Context. SERVICE_TEST)
manager.show()
8. 测试
make
make update-api 更新current.xml文件
生成system.imz文件,放到<ANDROID_SDK>/platform/android-20/images/目录下,
adb shell
service list
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)