I. Service Classification
1.1> Android Service
Use Java to compile services running in JVM
1.2> native service
Services completed using C/C ++ are generally initialized at the beginning of the system, such as mediaservice and audio service.
2. Native service workflow analysis
Int main (INT argc, char ** argv ){ Sp <processstate> proc (processstate: Self ()); Sp <iservicemanager> Sm = defaultservicemanager (); Logi ("servicemanager: % P", Sm. Get ()); Audioflinger: instantiate (); Mediaplayerservice: instantiate (); Cameraservice: instantiate (); Audiopolicyservice: instantiate (); Processstate: Self ()-> startthreadpool (); Ipcthreadstate: Self ()-> jointhreadpool (); } |
2.1 create processstate and defaultservicemanager
Sp <processstate> proc (processstate: Self ());
Sp <iservicemanager> Sm = defaultservicemanager ();
Processstate is placed in the global variable gprocess. Each process has only one processstate object, which is used to open the driver of the binder device and establish a thread pool. The ipcthreadstate has one thread. The ipcthreadstate instance is registered in the context ancillary data of the Linux thread. It is mainly responsible for the binder Data Reading, writing, and request processing framework. During construction, ipcthreadsate obtains the processsate of the process and records it in its member variable mprocess. Through mprocess, it can obtain the binder handle.
2.2 put the service into servicemanager
Audioflinger: instantiate ();
==>>
Defaservicservicemanager ()-> addservice (string16 ("media. audio_flinger"), new audioflinger ());
2.3 start service cycle
Processstate: Self ()-> startthreadpool ();
Ipcthreadstate: Self ()-> jointhreadpool ();
A read/write: talkwithdriver () @ ipcthreadstate packs IOCTL (mprocess-> mdriverfd, binder_write_read, & BWR.
B request processing: executecommand (...) @ ipcthreadstate
C loop structure: jointhreadpool ()
Jointhreadpool (){
While (1 ){
Talkwithdriver (...)
...
Executecommand (...)
}
}
2.4 data transmission with core services through the ibinder: transact () function.
3. compile your native service
(1) Write demonativeservice
1 int DemoService::instantiate() { 2 LOGE("DemoService instantiate"); 3 int r = defaultServiceManager()->DemoService( 4 String16("alfred.demo"), new DemoService()); 5 LOGE("DemoService r = %d\n", r); 6 return r; 7 } 8 9 10 status_t DemoService::onTransact(11 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){12 switch(code) {13 case 0: {14 pid_t pid = data.readInt32();15 int num = data.readInt32();16 num = num + 1000;17 reply->writeInt32(num);18 return NO_ERROR;19 } break;20 default:21 return BBinder::onTransact(code, data, reply, flags);22 }23 }
(2) Write demoloader to start demonativeservice
1 int main(int argc, char** argv)2 {3 sp<ProcessState> proc(ProcessState::self());4 sp<IServiceManager> sm = defaultServiceManager();5 LOGI("ServiceManager: %p", sm.get());6 DemoService::instantiate();7 ProcessState::self()->startThreadPool();8 IPCThreadState::self()->joinThreadPool();9 }
(3) Write MK files
(4) Write native code to call demonativeservice
1 int Demo::setN(int n){ 2 getDemoService(); 3 Parcel data, reply; 4 data.writeInt32(getpid()); 5 data.writeInt32(n); 6 7 LOGE("BpDemoService::create remote()->transact()\n"); 8 binder->transact(0, data, &reply); 9 int i = reply.readInt32();10 return i;11 }12 const void Demo::getDemoService(){13 sp<IServiceManager> sm = defaultServiceManager();14 binder = sm->getService(String16("guilh.add"));15 LOGE("Add::getDemoService %p\n",sm.get());16 if (binder == 0) {17 LOGW("DemoService not published, waiting...");18 return;19 }20 }
(5) Use JNI to connect Java and nativeservice
(6) Call demonativeservice IN THE ACTIVITY
11. Four major components-service advanced (2) Native service