Android应用程序绑定服务(bindService)的过程源代码分析(2)
Step 7.ActivityManagerService.bringUpServiceLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalbooleanbringUpServiceLocked(ServiceRecordr,
- intintentFlags,booleanwhileRestarting){
- ......
- finalStringappName=r.processName;
- ProcessRecordapp=getProcessRecordLocked(appName,r.appInfo.uid);
- if(app!=null&&app.thread!=null){
- try{
- realStartServiceLocked(r,app);
- returntrue;
- }catch(RemoteExceptione){
- ......
- }
- }
- //Notrunning--getitstarted,andenqueuethisservicerecord
- //tobeexecutedwhentheappcomesup.
- if(startProcessLocked(appName,r.appInfo,true,intentFlags,
- "service",r.name,false)==null){
- ......
- }
- ......
- }
- ......
- }
回忆在Android系统中的广播(Broadcast)机制简要介绍和学习计划中一文中,我们没有在程序的AndroidManifest.xml配置文件中设置CounterService的process属性值,因此,它默认就为application标签的process属性值,而application标签的process属性值也没有设置,于是,它们就默认为应用程序的包名了,即这里的appName的值为"shy.luo.broadcast"。接下来根据appName和应用程序的uid值获得一个ProcessRecord记录,由于之前在启动MainActivity的时候,已经根据这个appName和uid值创建了一个ProcessReocrd对象(具体可以参考Android应用程序启动过程源代码分析一文),因此,这里取回来的app和app.thread均不为null,于是,就执行realStartServiceLocked函数来执行下一步操作了。
如果这里得到的ProcessRecord变量app为null,又是什么情况呢?在这种情况下,就会执行后面的startProcessLocked函数来创建一个新的进程,然后在这个新的进程中启动这个Service了,具体可以参考前面一篇文章Android系统在新进程中启动自定义服务过程(startService)的原理分析。
Step 8.ActivityManagerService.realStartServiceLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalvoidrealStartServiceLocked(ServiceRecordr,
- ProcessRecordapp)throwsRemoteException{
- ......
- r.app=app;
- ......
- app.services.add(r);
- ......
- try{
- ......
- app.thread.scheduleCreateService(r,r.serviceInfo);
- ......
- }finally{
- ......
- }
- requestServiceBindingsLocked(r);
- ......
- }
- ......
- }
这个函数执行了两个操作,一个是操作是调用app.thread.scheduleCreateService函数来在应用程序进程内部启动CounterService,这个操作会导致CounterService的onCreate函数被调用;另一个操作是调用requestServiceBindingsLocked函数来向CounterService要一个Binder对象,这个操作会导致CounterService的onBind函数被调用。
这里,我们先沿着app.thread.scheduleCreateService这个路径分析下去,然后再回过头来分析requestServiceBindingsLocked的调用过程。这里的app.thread是一个Binder对象的远程接口,类型为ApplicationThreadProxy。每一个Android应用程序进程里面都有一个ActivtyThread对象和一个ApplicationThread对象,其中是ApplicationThread对象是ActivityThread对象的一个成员变量,是ActivityThread与ActivityManagerService之间用来执行进程间通信的,具体可以参考Android应用程序启动过程源代码分析一文。
Step 9. ApplicationThreadProxy.scheduleCreateService
这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:
- classApplicationThreadProxyimplementsIApplicationThread{
- ......
- publicfinalvoidscheduleCreateService(IBindertoken,ServiceInfoinfo)
- throwsRemoteException{
- Parceldata=Parcel.obtain();
- data.writeInterfaceToken(IApplicationThread.descriptor);
- data.writeStrongBinder(token);
- info.writeToParcel(data,0);
- mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION,data,null,
- IBinder.FLAG_ONEWAY);
- data.recycle();
- }
- ......
- }
这里通过Binder驱动程序就进入到ApplicationThread的scheduleCreateService函数去了。
Step 10.ApplicationThread.scheduleCreateService
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalclassApplicationThreadextendsApplicationThreadNative{
- ......
- publicfinalvoidscheduleCreateService(IBindertoken,
- ServiceInfoinfo){
- CreateServiceDatas=newCreateServiceData();
- s.token=token;
- s.info=info;
- queueOrSendMessage(H.CREATE_SERVICE,s);
- }
- ......
- }
- ......
- }
这里它执行的操作就是调用ActivityThread的queueOrSendMessage函数把一个H.CREATE_SERVICE类型的消息放到ActivityThread的消息队列中去。
Step 11.ActivityThread.queueOrSendMessage
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- //ifthethreadhasn'tstartedyet,wedon'thavethehandler,sojust
- //savethemessagesuntilwe'reready.
- privatefinalvoidqueueOrSendMessage(intwhat,Objectobj){
- queueOrSendMessage(what,obj,0,0);
- }
- privatefinalvoidqueueOrSendMessage(intwhat,Objectobj,intarg1){
- queueOrSendMessage(what,obj,arg1,0);
- }
- privatefinalvoidqueueOrSendMessage(intwhat,Objectobj,intarg1,intarg2){
- synchronized(this){
- ......
- Messagemsg=Message.obtain();
- msg.what=what;
- msg.obj=obj;
- msg.arg1=arg1;
- msg.arg2=arg2;
- mH.sendMessage(msg);
- }
- }
- ......
- }
这个消息最终是通过mH.sendMessage发送出去的,这里的mH是一个在ActivityThread内部定义的一个类,继承于Hanlder类,用于处理消息的。
Step 12. H.sendMessage
由于H类继承于Handler类,因此,这里实际执行的Handler.sendMessage函数,这个函数定义在frameworks/base/core/java/android/os/Handler.java文件,这里我们就不看了,有兴趣的读者可以自己研究一下,调用了这个函数之后,这个消息就真正地进入到ActivityThread的消息队列去了,最终这个消息由H.handleMessage函数来处理,这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalclassHextendsHandler{
- ......
- publicvoidhandleMessage(Messagemsg){
- ......
- switch(msg.what){
- ......
- caseCREATE_SERVICE:
- handleCreateService((CreateServiceData)msg.obj);
- break;
- ......
- }
- }
- }
- ......
- }
这个消息最终由ActivityThread的handleCreateService函数来处理。
Step 13.ActivityThread.handleCreateService
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalvoidhandleCreateService(CreateServiceDatadata){
- ......
- LoadedApkpackageInfo=getPackageInfoNoCheck(
- data.info.applicationInfo);
- Serviceservice=null;
- try{
- java.lang.ClassLoadercl=packageInfo.getClassLoader();
- service=(Service)cl.loadClass(data.info.name).newInstance();
- }catch(Exceptione){
- ......
- }
- try{
- ......
- ContextImplcontext=newContextImpl();
- context.init(packageInfo,null,this);
- Applicationapp=packageInfo.makeApplication(false,mInstrumentation);
- context.setOuterContext(service);
- service.attach(context,this,data.info.name,data.token,app,
- ActivityManagerNative.getDefault());
- service.onCreate();
- mServices.put(data.token,service);
- ......
- }catch(Exceptione){
- ......
- }
- }
- ......
- }
这个函数的工作就是把CounterService类加载到内存中来,然后调用它的onCreate函数。
Step 14. CounterService.onCreate
这个函数定义在Android系统中的广播(Broadcast)机制简要介绍和学习计划中一文中所介绍的应用程序Broadcast的工程目录下的src/shy/luo/broadcast/CounterService.java文件中:
- publicclassCounterServiceextendsServiceimplementsICounterService{
- ......
- @Override
- publicvoidonCreate(){
- super.onCreate();
- Log.i(LOG_TAG,"CounterServiceCreated.");
- }
- ......
- }
这样,CounterService就启动起来了。
至此,应用程序绑定服务过程中的第一步MainActivity.bindService->CounterService.onCreate就完成了。
这一步完成之后,我们还要回到Step 8中去,执行下一个操作,即调用ActivityManagerService.requestServiceBindingsLocked函数,这个调用是用来执行CounterService的onBind函数的。 Step 15.ActivityManagerService.requestServiceBindingsLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalvoidrequestServiceBindingsLocked(ServiceRecordr){
- Iterator<IntentBindRecord>bindings=r.bindings.values().iterator();
- while(bindings.hasNext()){
- IntentBindRecordi=bindings.next();
- if(!requestServiceBindingLocked(r,i,false)){
- break;
- }
- }
- }
- privatefinalbooleanrequestServiceBindingLocked(ServiceRecordr,
- IntentBindRecordi,booleanrebind){
- ......
- if((!i.requested||rebind)&&i.apps.size()>0){
- try{
- ......
- r.app.thread.scheduleBindService(r,i.intent.getIntent(),rebind);
- ......
- }catch(RemoteExceptione){
- ......
- }
- }
- returntrue;
- }
- ......
- }
这里的参数r就是我们在前面的Step 6中创建的ServiceRecord了,它代表刚才已经启动了的CounterService。函数requestServiceBindingsLocked调用了requestServiceBindingLocked函数来处理绑定服务的操作,而函数requestServiceBindingLocked又调用了app.thread.scheduleBindService函数执行操作,前面我们已经介绍过app.thread,它是一个Binder对象的远程接口,类型是ApplicationThreadProxy。 Step 16.ApplicationThreadProxy.scheduleBindService
这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:
- classApplicationThreadProxyimplementsIApplicationThread{
- ......
- publicfinalvoidscheduleBindService(IBindertoken,Intentintent,booleanrebind)
- throwsRemoteException{
- Parceldata=Parcel.obtain();
- data.writeInterfaceToken(IApplicationThread.descriptor);
- data.writeStrongBinder(token);
- intent.writeToParcel(data,0);
- data.writeInt(rebind?1:0);
- mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION,data,null,
- IBinder.FLAG_ONEWAY);
- data.recycle();
- }
- ......
- }
这里通过Binder驱动程序就进入到ApplicationThread的scheduleBindService函数去了。
更多相关文章
- android- activity,Application,activity渲染xml文件
- ListView取消和自定义分割线的方法
- 【Gradle】自定义Android Gradle工程
- 海创软件组--20200712--Butterknife与自定义图标字体
- Android 文件操作大全