The binder is the core mechanism for implementing inter-process communication in the Android system. In essence, it is a specific implementation of the proxy mode, just like COM and CORBA.
The basic idea of the proxy mode is that the client program obtains the proxy object of the server in some way. All the service requests to the server are sent to the proxy object, which is responsible for communication with the server. From the client perspective, accessing a proxy object is like accessing other local objects. The server proxy object shields all inter-process communication details.
In this article, we plan to give a specific example. Based on this example, we will further analyze the binding mechanism of the Android system.
Instance: a New System Service exampleservice is added. This service can accept an integer parameter, add the value to 100, and return the result. The client application uses this service to calculate the value of 1 + 100.
Code 1: Implementation of System Service exampleservice
// File: exampleservice. h <br/> # ifndef android_example_service_h <br/> # define android_example_service_h <br/> # include <utils/threads. h> <br/> # include <utils/refbase. h> <br/> # include <binder/iinterface. h> <br/> # include <binder/bpbinder. h> <br/> # include <binder/parcel. h> </P> <p> namespace Android {<br/> class exampleservice: Public bbinder <br/>{< br/> mutable mutex mlock; <br/> int32_t mnextconnid; <Br/> Public: <br/> static int instantiate (); <br/> exampleservice (); <br/> virtual ~ Exampleservice (); <br/> virtual status_t ontransact (uint32_t, const parcel &, parcel *, uint32_t); <br/> }; // namespace <br/> # endif
// File: exampleservice. CPP <br/> # include "exampleservice. H "<br/> # include <binder/iservicemanager. h> <br/> # include <binder/ipcthreadstate. h> </P> <p> namespace Android {</P> <p> static struct sigaction oldact; <br/> static pthread_key_t sigbuskey; </P> <p> int exampleservice: instantiate () <br/>{< br/> LogE ("exampleservice instantiate "); <br/> // call the addservice method of servicemanager to register the system service, so that the client program can use Servic Emanager obtains the proxy object of this service and requests the services it provides <br/> int r = defaultservicemanager ()-> addservice (string16 ("Byn. example "), new exampleservice (); <br/> LogE (" exampleservice r = % d/N ", R); <br/> return R; <br/>}</P> <p> exampleservice: exampleservice () <br/> {<br/> logv ("exampleservice created "); <br/> mnextconnid = 1; <br/> pthread_key_create (& sigbuskey, null); <br/>}</P> <p> exampleservice ::~ Exampleservice () <br/>{< br/> pthread_key_delete (sigbuskey); <br/> logv ("exampleservice destroyed "); <br/>}< br/> // each system service is inherited from the bbinder class and the ontransact virtual function of bbinder should be rewritten. When a user sends a request to the service, the system framework calls the ontransact function of the Service <br/> status_t exampleservice: ontransact (uint32_t code, const parcel & Data, parcel * reply, uint32_t flags) <br/>{< br/> switch (CODE) <br/>{< br/> case 0 :{< br/> pid_t pid = data. readint32 (); <br/> int num = data. readint32 (); <br/> num = num + 100; <br/> reply-> writeint32 (Num); <br/> return no_error; <br/>}< br/> break; <br/> default: <br/> return bbinder: ontransact (Code, Data, reply, flags ); <br/>}< br/>}; // namespace
# File: Android. MK <br/> local_path: = $ (call my-DIR) <br/> include $ (clear_vars) <br/> local_src_files: =/<br/> exampleservice. CPP <br/> local_c_includes :=$ (jni_h_include) <br/> local_shared_libraries :=/ <br/> libutils libbinder <br/> local_prelink_module: = false <br/> local_module: = libexample </P> <p> include $ (build_shared_library)
Create a folder exampleservice under/framework/Android/src/frameworks/base and copy the preceding three files to the folder.
Code 2: Start the exampleservice Application
// File: exampleserver. CPP <br/> # include <sys/types. h> <br/> # include <unistd. h> <br/> # include <GRP. h> <br/> # include <binder/ipcthreadstate. h> <br/> # include <binder/processstate. h> <br/> # include <binder/iservicemanager. h> <br/> # include <utils/log. h> <br/> # include <private/android_filesystem_config.h> <br/> # include ".. /exampleservice. H "</P> <p> using namespace android; </P> <p> int main (INT argc, char ** argv) <br/>{ <br/> sp <processstate> proc (processstate: Self (); // to use the Binder Mechanism, you must create a processstate object <br/> sp <iservicemanager> Sm = defaultservicemanager (); <br/> Logi ("servicemanager: % P", SM. get (); <br/> exampleservice: instantiate (); <br/> processstate: Self ()-> startthreadpool (); <br/> ipcthreadstate :: self ()-> jointhreadpool (); <br/> return 0; <br/>}
# File: Android. MK <br/> local_path: = $ (call my-DIR) <br/> include $ (clear_vars) <br/> local_src_files: =/<br/> exampleserver. CPP <br/> local_c_includes :=$ (jni_h_include) <br/> local_shared_libraries: =/<br/> libutils libbinder libexample <br/> local_prelink_module: = false <br/> local_module: = exampleserver </P> <p> include $ (build_executable)
Create a folder exampleserver under/framework/Android/src/frameworks/base and copy the above two files to the folder.
Code 3: client application using exampleservice
// File: Example. h <br/> # ifndef android_byn_example_h <br/> # define android_byn_example_h </P> <p> namespace Android <br/>{< br/> class example {<br/> public: <br/> void add100 (int n); <br/> PRIVATE: <br/> static const void getexampleservice (); <br/>}; <br/> }; // namespace <br/> # endif // android_byn_example_h
// File: Example. CPP <br/> # include <binder/iservicemanager. h> <br/> # include <binder/ipcthreadstate. h> <br/> # include "example. H "</P> <p> namespace Android <br/> {<br/> sp <ibinder> binder; <br/> void example: add100 (int n) <br/>{< br/> getexampleservice (); <br/> parcel data, reply; <br/> int answer; </P> <p> data. writeint32 (getpid (); <br/> data. writeint32 (n); <br/> LogE ("bpexampleservice: Create remote ()-> transact ()/n"); <br/> binder-> transact (0, data, & reply); <br/> answer = reply. readint32 (); <br/> printf ("answner = % d/N", answer); <br/> return; <br/>}</P> <p> const void example: getexampleservice () <br/>{< br/> sp <iservicemanager> Sm = defaservicservicemanager (); <br/> binder = Sm-> getservice (string16 ("Byn. example "); <br/> LogE (" Example: getexampleservice % P/N ", SM. get (); <br/> If (Binder = 0) {<br/> logw ("exampleservice not published, waiting... "); <br/> return; <br/>}< br/>}; // namespace </P> <p> using namespace android; </P> <p> int main (INT argc, char ** argv) <br/> {<br/> example * P = new example (); <br/> P-> add100 (1); <br/> return 0; <br/>}
# File: Example <br/> local_path: = $ (call my-DIR) <br/> include $ (clear_vars) <br/> local_src_files: =/<br/> example. CPP <br/> local_c_includes :=$ (jni_h_include) <br/> local_shared_libraries: =/<br/> libutils libbinder libexample <br/> local_prelink_module: = false <br/> local_module: = example </P> <p> include $ (build_executable)
Create a folder named example under/framework/Android/src/frameworks/base and copy the preceding three files to the folder.
Build the entire android system. Three files are generated in the system, which are
/System/lib/libexample. So
/System/bin/exampleserver
/System/bin/Example
Then start the newly added exampleservice System Service and start the client program to verify the running result.
$> ADB Shell
# Cd/system/bin
#./Exampleserver &
#./Example
Answer= 101
In the following articles, we will analyze the Binder Mechanism in the Android system based on this example.
References:
1. Walking blog in the cloud: http://my.unix-center.net /~ Simon_fu/
2. How to write your first core service-Gao hentang: http://www.android1.net/Topic.aspx? Boardid = 21> topicid = 990