欢迎参加我的常识星球Android体系开发指南

欢迎重视微信公众号 无限无羡
欢迎重视知乎账号 无限无羡

在平常的事务开发中,咱们往往需求开发自界说的体系服务来处理自己特别的需求,咱们这儿提供两种方式来完成。榜首种是依照已有的体系服务的办法,运行在system_server进程中,由于这样增加服务的话假如因为自界说的服务发生溃散,将会导致system_server溃散,从而引起体系重启。所以咱们这儿还会介绍第二种办法,就是将自界说的服务放到一个独立的进程中,与system_server进程隔离,这样即便自界说服务发生溃散,也不会影响到体系稳定性。

本节先介绍榜首种办法,下一节介绍第二种办法。

咱们将自界说的服务取名为BeanManagerService。

界说aidl

Binder默认能够传输根本类型的数据,假如要传递类目标,则这个类需求完成序列化。咱们先界说一个序列化的自界说类型,用于binder间参数传递。主要分为两步:

  1. 创立自界说类型,完成Parcelable接口
//frameworks/base/core/java/android/bean/Person.java
packageandroid.bean;
importandroid.annotation.NonNull;
importandroid.os.Parcel;
importandroid.os.Parcelable;
publicfinalclassPersonimplementsParcelable{
//留意界说成员变量的次序,后边读取和写入都有必要按这个次序
privateStringmName;
privateintmAge;
publicPerson(){
}
publicPerson(@NonNullStringname,intage){
this.mName=name;
this.mAge=age;
}
privatePerson(@NonNullParcelin){
//留意界说成员变量的次序
this.mName=in.readString();
this.mAge=in.readInt();
}
@NonNull
publicStringgetName(){
returnmName;
}
publicintgetAge(){
returnmAge;
}
publicvoidsetName(@NonNullStringname){
mName=name;
}
publicvoidsetAge(intage){
mAge=age;
}
@Override
publicintdescribeContents(){
return0;
}
//
@Override
publicvoidwriteToParcel(@NonNullParceldest,intflags){
//留意界说成员变量的次序
dest.writeString(this.mName);
dest.writeInt(this.mAge);
}
publicvoidreadFromParcel(@NonNullParcelsource){
//留意界说成员变量的次序
this.mName=source.readString();
this.mAge=source.readInt();
}
@NonNull
publicstaticfinalParcelable.Creator<Person>CREATOR=newParcelable.Creator<Person>(){
@Override
publicPersoncreateFromParcel(@NonNullParcelsource){
returnnewPerson(source);
}
@Override
publicPerson[]newArray(intsize){
returnnewPerson[size];
}
};
}
  1. 创立aidl文件,如下:
//frameworks/base/core/java/android/bean/Person.aidl
packageandroid.bean;
parcelablePerson;

这样就界说好了一个自界说目标类型,该类型能够经过binder传递,下面咱们会有例子阐明。

接下来咱们界说自界说服务,首先要界说一个aidl文件来界说咱们的接口,这个aidl文件编译后会生成binder的客户端服务端接口,咱们需求完成客户端和服务端。

//bean为新建的文件夹,用于存放自界说服务
//frameworks/base/core/java/android/bean/IBeanManager.aidl
packageandroid.bean;
importandroid.bean.Person;
/**
*{@hide}
*/
interfaceIBeanManager{
voidsayHello(Stringwords);
//自界说类型前面有必要加上in或许out或许inout标识符
//in:表明参数只能由客户端传递到服务端,根本类型默认只支持in修饰符
//out:表明参数只能由服务端传递到客户端,服务端假如修改了参数目标的值
//那么客户端的值也会改变,可是服务端无法读取客户端目标的值
//inout:表明参数能够双向传递
voidsayHelloTo(inPersonperson,Stringwords);
}

由于下面的Android.bp现已包含了该目录下几乎一切aidl文件和java文件的编译,所以咱们不需求再将自界说的BeanManager.aidl增加到编译环境。

//frameworks/base/core/java/Android.bp
filegroup{
name:"framework-core-sources",
srcs:[
"**/*.java",
"**/*.aidl",
],
exclude_srcs:[
//Removeelectiontoolbarcodefrombuildtime
"android/service/selectiontoolbar/*.aidl",
"android/service/selectiontoolbar/*.java",
"android/view/selectiontoolbar/*.aidl",
"android/view/selectiontoolbar/*.java",
"com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java",
],
visibility:["//frameworks/base"],
}

用以下命令编译aidl
source build/envsetup.sh
lunch sdk_car_x86_64-userdebug// 这儿挑选自己的项目
make update-api
make framework -j16
编译完成后,能够看到out下现已生成了binder相关的文件

Android 13添加自定义Java系统服务(一)

Server端完成

cd frameworks/base
mkdir -p services/core/java/com/android/server/bean/
新建BeanManagerService.java
编译装备同上,不需求再独自加到编译装备中。

//frameworks/base/services/core/java/com/android/server/bean/BeanManagerService.java
packagecom.android.server.bean;
importandroid.bean.IBeanManager;
importandroid.bean.Person;
importandroid.content.Context;
importandroid.util.Log;
importcom.android.server.SystemService;
importcom.android.server.Watchdog;
publicclassBeanManagerServiceextendsIBeanManager.Stub
implementsWatchdog.Monitor{
staticfinalStringTAG="BeanManagerService";
finalContextmContext;
publicBeanManagerService(ContextsystemContext){
Log.d(TAG,"BeanManagerService");
mContext=systemContext;
Watchdog.getInstance().addMonitor(this);
}
@Override
publicvoidsayHello(Stringwords){
Log.d(TAG,"sayHello:"+words);
}
@Override
publicvoidsayHelloTo(Personperson,Stringwords){
Log.d(TAG,"sayHello"+person.getName()+":"+words);
}
publicvoidsystemReady(){
Log.d(TAG,"systemReady");
}
/**Inthismethodwetrytoacquireourlocktomakesurethatwehavenotdeadlocked*/
publicvoidmonitor(){
synchronized(this){}
}
//这儿咱们界说了一个内部类承继SystemService,这样便于便利system_server统一管理发动服务
//体系发动时会回调一切承继了SystemService的类的函数,比如onStart,onBootPhase等等。
publicstaticfinalclassLifecycleextendsSystemService{
staticfinalStringTAG="BeanManagerService.Lifecycle";
privateBeanManagerServicemService;
publicLifecycle(Contextcontext){
super(context);
//在这儿结构咱们的BeanManagerService目标
mService=newBeanManagerService(context);
}
@Override
publicvoidonStart(){
Log.d(TAG,"onStart");
//这儿终究调用ServiceManager.addService
publishBinderService(Context.BEAN_SERVICE,mService);
}
@Override
publicvoidonBootPhase(intphase){
Log.d(TAG,"onBootPhase");
if(phase==SystemService.PHASE_ACTIVITY_MANAGER_READY){
mService.systemReady();
}
}
}
}

增加服务称号

//frameworks/base/core/java/android/content/Context.java
diff--gita/core/java/android/content/Context.javab/core/java/android/content/Context.java
index77ca48a8ed1d..6ad91d26daf7100644
---a/core/java/android/content/Context.java
+++b/core/java/android/content/Context.java
@@-3809,6+3809,7@@publicabstractclassContext{
ACCOUNT_SERVICE,
ACTIVITY_SERVICE,
ALARM_SERVICE,
+BEAN_SERVICE,
NOTIFICATION_SERVICE,
ACCESSIBILITY_SERVICE,
CAPTIONING_SERVICE,
@@-4248,6+4249,16@@publicabstractclassContext{
*/
publicstaticfinalStringACTIVITY_SERVICE="activity";
+/**
+*Usewith{@link#getSystemService(String)}toretrievea
+*{@linkandroid.bean.BeanManager}forinteractingwiththeglobal
+*systemstate.
+*
+*@see#getSystemService(String)
+*@seeandroid.bean.BeanManager
+*/
+publicstaticfinalStringBEAN_SERVICE="bean";
+

开机发动服务:

//frameworks/base/services/java/com/android/server/SystemServer.java
//体系发动时将服务分为几个类型,如下,咱们能够依据自己的详细事务增加到对应的函数里边
try{
t.traceBegin("StartServices");
//引导服务,有必要
startBootstrapServices(t);
//中心服务,有必要
startCoreServices(t);
//其他服务,一般放在这儿面
startOtherServices(t);
//界说在apexes中的服务apexes,有爱好的能够看下源码
startApexServices(t);
}catch(Throwableex){
Slog.e("System","******************************************");
Slog.e("System","************Failurestartingsystemservices",ex);
throwex;
}finally{
t.traceEnd();//StartServices
}
---a/services/java/com/android/server/SystemServer.java
+++b/services/java/com/android/server/SystemServer.java
@@-110,6+110,7@@importcom.android.server.appbinding.AppBindingService;
importcom.android.server.art.ArtManagerLocal;
importcom.android.server.attention.AttentionManagerService;
importcom.android.server.audio.AudioService;
+importcom.android.server.bean.BeanManagerService;
importcom.android.server.biometrics.AuthService;
importcom.android.server.biometrics.BiometricService;
importcom.android.server.biometrics.sensors.face.FaceService;
@@-1466,6+1467,10@@publicfinalclassSystemServerimplementsDumpable{
}
},SECONDARY_ZYGOTE_PRELOAD);
+t.traceBegin("BeanManagerService");
//这儿终究会经过反射的办法调用BeanManagerService.Lifecycle的结构函数
+mSystemServiceManager.startService(BeanManagerService.Lifecycle.class);
+t.traceEnd();
+
t.traceBegin("StartKeyAttestationApplicationIdProviderService");
ServiceManager.addService("sec_key_att_app_id_provider",
newKeyAttestationApplicationIdProviderService(context));

mSystemServiceManager.startService的完成:

//frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public<TextendsSystemService>TstartService(Class<T>serviceClass){
try{
finalStringname=serviceClass.getName();
Slog.i(TAG,"Starting"+name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,"StartService"+name);
//Createtheservice.
if(!SystemService.class.isAssignableFrom(serviceClass)){
thrownewRuntimeException("Failedtocreate"+name
+":servicemustextend"+SystemService.class.getName());
}
finalTservice;
try{
//调用结构函数,对于咱们的自界说服务就是BeanManagerService.Lifecycle
Constructor<T>constructor=serviceClass.getConstructor(Context.class);
service=constructor.newInstance(mContext);
}catch(InstantiationExceptionex){
thrownewRuntimeException("Failedtocreateservice"+name
+":servicecouldnotbeinstantiated",ex);
}catch(IllegalAccessExceptionex){
thrownewRuntimeException("Failedtocreateservice"+name
+":servicemusthaveapublicconstructorwithaContextargument",ex);
}catch(NoSuchMethodExceptionex){
thrownewRuntimeException("Failedtocreateservice"+name
+":servicemusthaveapublicconstructorwithaContextargument",ex);
}catch(InvocationTargetExceptionex){
thrownewRuntimeException("Failedtocreateservice"+name
+":serviceconstructorthrewanexception",ex);
}
startService(service);
returnservice;
}finally{
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
publicvoidstartService(@NonNullfinalSystemServiceservice){
//Checkifalreadystarted
StringclassName=service.getClass().getName();
if(mServiceClassnames.contains(className)){
Slog.i(TAG,"Notstartinganalreadystartedservice"+className);
return;
}
mServiceClassnames.add(className);
//将BeanManagerService.Lifecycle参加mServices列表
//体系的发动进程会遍历mServices列表,回调每个服务的对应函数
//Registerit.
mServices.add(service);
//Startit.
longtime=SystemClock.elapsedRealtime();
try{
//这儿就是调用每个服务的onStart函数
service.onStart();
}catch(RuntimeExceptionex){
thrownewRuntimeException("Failedtostartservice"+service.getClass().getName()
+":onStartthrewanexception",ex);
}
warnIfTooLong(SystemClock.elapsedRealtime()-time,service,"onStart");
}

到此,服务的增加代码现已完成,咱们编译验证一下:
// 因为Context.java中新增了BEAN_SERVICE的API,所以要先make update-api
source build/envsetup.sh
lunch sdk_car_x86_64-userdebug
make update-api -j16
make -j16
发动模拟器
emulator

这时发现服务无法发动,看日志有如下报错:

Android 13添加自定义Java系统服务(一)

Selinux权限问题,咱们依据日志按规则增加:
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
输出信息如下:

#=============system_server==============
allowsystem_serverdefault_android_service:service_manageradd;

咱们假如看过我的另一篇文章Android 13增加自界说native服务,就能立马理解这儿该怎么增加。
假如依照上面的提示应该是在system_server.te里增加allow system_server default_android_service:service_manager add;
可是这样会触发neverallow,正确的办法是为自界说的服务增加一个新的标签:

//vendor/zzh/sepolicy/private/service_contexts
beanu:object_r:bean_service:s0
//vendor/zzh/sepolicy/public/service.te
typebean_service,service_manager_type;
//vendor/zzh/sepolicy/public/system_server.te
allowsystem_serverbean_service:service_manageradd;

上述修改的文件咱们依据自己项目增加到详细的文件中,也能够参考Android 13增加自界说native服务。
修改后从头编译发动验证

Android 13添加自定义Java系统服务(一)

能够看到服务现已正常发动。
假如遇到修改selinux后开机还是报错的情况,手动kill掉模拟器进程再发动模拟器。

Client端调用

Client调用实际上就是获取binder的署理目标,然后经过署理目标调用服务端的办法。在Android体系中,为了便利App运用体系服务的功用,一般都会给每个服务界说一个XXXManager,App能够经过Context.getSystemService(serviceName)来获取到经过包装的服务端的署理XXXManager。Context.getSystemService终究会调用到SystemServiceRegistry中的getSystemService。

//frameworks/base/core/java/android/app/SystemServiceRegistry.java
/**
*Getsasystemservicefromagivencontext.
*@hide
*/
publicstaticObjectgetSystemService(ContextImplctx,Stringname){
if(name==null){
returnnull;
}
//SYSTEM_SERVICE_FETCHERS是一个map,保存了每个服务的称号和Manager的映射关系
//ServiceFetcher是一个接口,有一个笼统办法TgetService(ContextImplctx);
//这个getService回来的就是服务的署理包装类XXXManager
finalServiceFetcher<?>fetcher=SYSTEM_SERVICE_FETCHERS.get(name);
if(fetcher==null){
if(sEnableServiceNotFoundWtf){
Slog.wtf(TAG,"Unknownmanagerrequested:"+name);
}
returnnull;
}
finalObjectret=fetcher.getService(ctx);
if(sEnableServiceNotFoundWtf&&ret==null){
//Someservicesdoreturnnullincertainsituations,sodon'tdoWTFforthem.
switch(name){
caseContext.CONTENT_CAPTURE_MANAGER_SERVICE:
caseContext.APP_PREDICTION_SERVICE:
caseContext.INCREMENTAL_SERVICE:
caseContext.ETHERNET_SERVICE:
returnnull;
}
Slog.wtf(TAG,"Managerwrappernotavailable:"+name);
returnnull;
}
returnret;
}

ServiceFetcher接口的界说

//frameworks/base/core/java/android/app/SystemServiceRegistry.java
/**
*Baseinterfaceforclassesthatfetchservices.
*Theseobjectsmustonlybecreatedduringstaticinitialization.
*/
staticabstractinterfaceServiceFetcher<T>{
TgetService(ContextImplctx);
}

ServiceFetcher接口的完成有两个,CachedServiceFetcher和StaticServiceFetcher,这两个其实是两个笼统类,都有一个笼统办法createService,而这个createService正式获取服务端署理的真实完成。CachedServiceFetcher顾名思义就是将每个服务的署理目标都进行缓存,下一次获取的时候直接运用缓存的目标就能够了。

//frameworks/base/core/java/android/app/SystemServiceRegistry.java
/**
*Overridethisclasswhenthesystemserviceconstructorneedsa
*ContextImplandshouldbecachedandretainedbythatcontext.
*/
staticabstractclassCachedServiceFetcher<T>implementsServiceFetcher<T>{
privatefinalintmCacheIndex;
CachedServiceFetcher(){
//Notethisclassmustbeinstantiatedonlybythestaticinitializerofthe
//outerclass(SystemServiceRegistry),whichalreadydoesthesynchronization,
//sobareaccesstosServiceCacheSizeisokayhere.
//每一个Context目标包含了一个保存服务署理的数组,每增加一个署理,也就是每创立一个CachedServiceFetcher,
//sServiceCacheSize便会递增,而每个CachedServiceFetcher中的mCacheIndex则是自己在整个数组中的index。
//后续获取服务署理时,假如cache中有数据,则直接依据mCacheIndex获取即可。
mCacheIndex=sServiceCacheSize++;
}
@Override
@SuppressWarnings("unchecked")
publicfinalTgetService(ContextImplctx){
//获取Context中的保存服务署理的数组mServiceCache
finalObject[]cache=ctx.mServiceCache;
//finalint[]mServiceInitializationStateArray=newint[mServiceCache.length];
//mServiceInitializationStateArray是一个以mServiceCache.length为size的int数组,用于
//保存每个服务署理的状况,现在有四种状况:
//staticfinalintSTATE_UNINITIALIZED=0;
//staticfinalintSTATE_INITIALIZING=1;
//staticfinalintSTATE_READY=2;
//staticfinalintSTATE_NOT_FOUND=3;
finalint[]gates=ctx.mServiceInitializationStateArray;
booleaninterrupted=false;
Tret=null;
for(;;){
booleandoInitialize=false;
synchronized(cache){
//Returnitifwealreadyhaveacachedinstance.
//先依据mCacheIndex获取,假如不为null,阐明之前现已保存过,直接回来。
Tservice=(T)cache[mCacheIndex];
if(service!=null){
ret=service;
break;//exitthefor(;;)
}
//Ifwegethere,there'snocachedinstance.
//Grr...ifgateisSTATE_READY,thenthismeansweinitializedtheservice
//oncebutsomeoneclearedit.
//WestartoverfromSTATE_UNINITIALIZED.
//Similarly,ifthepreviousattemptreturnednull,we'llretryagain.
//走到这儿阐明缓存中没有保存署理目标
//可是状况却是(STATE_READY),阐明之前是增加过的,可是现在找不到了,阐明被谁从数组中移除了
//或许状况是找不到(STATE_NOT_FOUND)
//那么就将状况重置为STATE_UNINITIALIZED,从头再往cache数组增加一次
if(gates[mCacheIndex]==ContextImpl.STATE_READY
||gates[mCacheIndex]==ContextImpl.STATE_NOT_FOUND){
gates[mCacheIndex]=ContextImpl.STATE_UNINITIALIZED;
}
//It'spossibleformultiplethreadstogethereatthesametime,so
//usethe"gate"tomakesureonlythefirstthreadwillcallcreateService().
//Atthispoint,thegatemustbeeitherUNINITIALIZEDorINITIALIZING.
//这儿在往署理服务数组中增加新数据之前,先把状况设置为STATE_INITIALIZING
if(gates[mCacheIndex]==ContextImpl.STATE_UNINITIALIZED){
doInitialize=true;
gates[mCacheIndex]=ContextImpl.STATE_INITIALIZING;
}
}
if(doInitialize){
//Onlythefirstthreadgetshere.
//接下来就要真实的保存服务署理到数组中了
Tservice=null;
@ServiceInitializationStateintnewState=ContextImpl.STATE_NOT_FOUND;
try{
//Thisthreadisthefirstonetogethere.Instantiatetheservice
//*without*thecachelockheld.
//这儿经过createService获取到服务署理目标,前面说过createService是一个笼统办法,
//阐明有子类完成的当地,后边会讲到
service=createService(ctx);
newState=ContextImpl.STATE_READY;
}catch(ServiceNotFoundExceptione){
onServiceNotFound(e);
}finally{
synchronized(cache){
//假如createService没有反常的话,将署理服务保存到cache数组
//将状况设置为newState,newState在前面设置为了STATE_READY
cache[mCacheIndex]=service;
gates[mCacheIndex]=newState;
cache.notifyAll();
}
}
ret=service;
break;//exitthefor(;;)
}
//TheotherthreadswillwaitforthefirstthreadtocallnotifyAll(),
//andgobacktothetopandretry.
synchronized(cache){
//RepeatuntilthestatebecomesSTATE_READYorSTATE_NOT_FOUND.
//Wecan'trespondtointerruptshere;justlikewecan'tinthe"doInitialize"
//path,soweremembertheinterruptstatehereandre-interruptlater.
//假如服务署理正在增加进程中,还没有增加完成时,又有一个新的线程来getSystemService,则会
//进去wait状况,等待服务署理目标增加完成后履行notifyAll来唤醒当时线程
while(gates[mCacheIndex]<ContextImpl.STATE_READY){
try{
//Cleartheinterruptstate.
interrupted|=Thread.interrupted();
cache.wait();
}catch(InterruptedExceptione){
//Thisshouldn'tnormallyhappen,butifsomeoneinterruptsthe
//thread,itwill.
Slog.w(TAG,"getService()interrupted");
interrupted=true;
}
}
}
}
if(interrupted){
Thread.currentThread().interrupt();
}
returnret;
}
//笼统办法createService
publicabstractTcreateService(ContextImplctx)throwsServiceNotFoundException;
}
//StaticServiceFetcher则是服务署理中不需求Context目标的一种完成,也就是创立XXXManager目标时不需求
//传入Context参数
/**
*OverridethisclasswhenthesystemservicedoesnotneedaContextImpl
*andshouldbecachedandretainedprocess-wide.
*/
staticabstractclassStaticServiceFetcher<T>implementsServiceFetcher<T>{
privateTmCachedInstance;
@Override
publicfinalTgetService(ContextImplctx){
synchronized(StaticServiceFetcher.this){
if(mCachedInstance==null){
try{
mCachedInstance=createService();
}catch(ServiceNotFoundExceptione){
onServiceNotFound(e);
}
}
returnmCachedInstance;
}
}
publicabstractTcreateService()throwsServiceNotFoundException;
}

经过上面能够看到,CachedServiceFetcher和StaticServiceFetcher都需求完成createService的笼统办法,咱们的自界说服务署理目标BeanManager假定需求传入Context目标,则需求运用CachedServiceFetcher。

//frameworks/base/core/java/android/app/SystemServiceRegistry.java
registerService(Context.BEAN_SERVICE,BeanManager.class,
//这儿是CachedServiceFetcher笼统类的完成
newCachedServiceFetcher<BeanManager>(){
//笼统办法createService的完成,咱们看到其实很简单,就是经过ServiceManager获取服务的binder署理目标
@Override
publicBeanManagercreateService(ContextImplctx)throwsServiceNotFoundException{
IBinderb=ServiceManager.getServiceOrThrow(Context.BEAN_SERVICE);
IBeanManagerservice=IBeanManager.Stub.asInterface(b);
//以IBeanManager和Context为参数结构BeanManager,这样咱们经过Context.getSysetemService(Context.BEAN_SERVICE)
//回来的目标就是BeanManager
returnnewBeanManager(service,ctx);
}});
/**
*Staticallyregistersasystemservicewiththecontext.
*Thismethodmustbecalledduringstaticinitializationonly.
*/
//registerService只是保存为全局的目标
privatestatic<T>voidregisterService(@NonNullStringserviceName,
@NonNullClass<T>serviceClass,@NonNullServiceFetcher<T>serviceFetcher){
SYSTEM_SERVICE_NAMES.put(serviceClass,serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName,serviceFetcher);
SYSTEM_SERVICE_CLASS_NAMES.put(serviceName,serviceClass.getSimpleName());
}

接下来就是该界说BeanManager了

//frameworks/base/core/java/android/bean/BeanManager.java
packageandroid.bean;
importandroid.annotation.NonNull;
importandroid.content.Context;
importandroid.os.RemoteException;
importandroid.util.Log;
/**
*{@hide}
*/
publicclassBeanManager{
privatestaticfinalStringTAG="BeanManager";
privateContextmContext;
privateIBeanManagermService;
publicBeanManager(IBeanManagerservice,Contextctx){
Log.d(TAG,"newBeanManager");
mService=service;
mContext=ctx;
}
publicvoidsayHello(@NonNullStringwords){
Log.d(TAG,"sayHellowords:"+words);
if(mService==null){
Log.d(TAG,"sayHellomServiceisnull!!!");
return;
}
try{
mService.sayHello(words);
}catch(RemoteExceptione){
throwe.rethrowFromSystemServer();
}
}
publicvoidsayHelloTo(@NonNullPersonperson,@NonNullStringwords){
Log.d(TAG,"sayHelloTo"+person.getName()+":"+words);
if(mService==null){
Log.d(TAG,"sayHelloTomServiceisnull!!!");
return;
}
try{
mService.sayHelloTo(person,words);
}catch(RemoteExceptione){
throwe.rethrowFromSystemServer();
}
}
}

到此,咱们的服务署理就增加完成了。咱们调用BeanManager测验一下,咱们增加到Launcher里,开机加载
Launcher时就会调用。

//packages/apps/Car/Launcher/src/com/android/car/carlauncher/CarLauncher.java
---a/src/com/android/car/carlauncher/CarLauncher.java
+++b/src/com/android/car/carlauncher/CarLauncher.java
@@-21,7+21,10@@importstaticandroid.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERL
importandroid.app.ActivityManager;
importandroid.app.TaskStackListener;
+importandroid.bean.BeanManager;
+importandroid.bean.Person;
importandroid.car.user.CarUserManager;
+importandroid.content.Context;
importandroid.content.Intent;
importandroid.content.res.Configuration;
importandroid.os.Bundle;
@@-108,6+111,13@@publicclassCarLauncherextendsFragmentActivity{
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
+BeanManagerbeanManager=(BeanManager)getSystemService(Context.BEAN_SERVICE);
+beanManager.sayHello("Helloworld!");
+Personperson=newPerson();
+person.setName("Rick");
+person.setAge(32);
+beanManager.sayHelloTo(person,"GoodNight!!!");
+
if(CarLauncherUtils.isCustomDisplayPolicyDefined(this)){
IntentcontrolBarIntent=newIntent(this,ControlBarActivity.class);
controlBarIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

编译后重启服务器,看到如下日志阐明调用成功:

04-0521:08:24.623638638ISystemServiceManager:Startingcom.android.server.bean.BeanManagerService$Lifecycle
04-0521:08:24.624638638DBeanManagerService:BeanManagerService
04-0521:08:24.624638638DBeanManagerService.Lifecycle:onStart
04-0521:08:25.592638638DBeanManagerService.Lifecycle:onBootPhase
04-0521:08:25.650638638DBeanManagerService.Lifecycle:onBootPhase
04-0521:08:25.650638638DBeanManagerService:systemReady
04-0521:08:26.020638638DBeanManagerService.Lifecycle:onBootPhase
04-0521:08:36.51319331933DBeanManager:newBeanManager
04-0521:08:36.51319331933DBeanManager:sayHellowords:Helloworld!
04-0521:08:36.515638805DBeanManagerService:sayHello:Helloworld!
04-0521:08:36.51719331933DBeanManager:sayHellotoRick:GoodNight!
04-0521:08:36.519638805DBeanManagerService:sayHellotoRick:GoodNight!