Binder: Pins, paper clips. In life, we use a paper clip to "do not" with two sheets. In Android, Binder is used for interprocess communication, and two processes are "not" together.
Binder is an architecture with 3 modules (server-side interface, Binder driver, customer-service interface), such as:
The binder server, in effect, is a binder class object that, once created, initiates a hidden thread.
According to the above structure, say what I understand.
To access a remote service, a client-side program needs to obtain a binder reference to the server---mremote. Android engineers provide a solution that is the service. For the customer service side, there are two ways to connect with the server.
Public componentaname StartService (Intent Intent) Public Boolean int flags)
When the first method starts, the customer service side does not have a reference to the server binder at the moment.
When the second method is started, the onserviceconnected method of the Serviceconnection interface is recalled.
The Serviceconnection code is as follows:
Public Interface serviceconnection { publicvoid onserviceconnected (componentname name, IBinder Service); Public void onservicedisconnected (componentname name);}
The IBinder object service in the Onserviceconnected method is a reference to the remote service.
--------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------- --------------------------------------------
The binder mechanism I understand comes to an end here, so what is the aidl to solve?
Write a aidl file and see what it does. As shown below:
Package Com.aprz.aidl; Interface iaidltest{ void Test ();}
Interface is a keyword, sometimes preceded by interface, with OneWay indicating that the service provides no return value, and that the file name begins with "I" to unify the specification. After the file is written, the following code is automatically generated by the Android development environment:
/*___generated_by_idea___*/ /** This file is auto-generated. Do not MODIFY. * Original File:f:\\workspace\\aidlservice\\src\\com\\aprz\\aidl\\aidltest.aidl*/ PackageCom.aprz.aidl; Public InterfaceAidltestextendsAndroid.os.IInterface {/*** Local-side IPC implementation stub class. */ Public Static Abstract classStubextendsAndroid.os.BinderImplementsCom.aprz.aidl.AidlTest {Private Static FinalJava.lang.String descriptor = "Com.aprz.aidl.AidlTest"; /*** Construct The stub at attach it to the interface. */ PublicStub () { This. Attachinterface ( This, descriptor); } /*** Cast an IBinder object to an Com.aprz.aidl.AidlTest interface, * Generating a proxy if needed. */ Public Staticcom.aprz.aidl.AidlTest asinterface (Android.os.IBinder obj) {if(obj = =NULL)) { return NULL; } android.os.IInterface iin=Obj.querylocalinterface (descriptor); if(((Iin! =NULL) && (iininstanceofcom.aprz.aidl.AidlTest )) {return((com.aprz.aidl.AidlTest) iin); } return Newcom.aprz.aidl.AidlTest.Stub.Proxy (obj); } @Override PublicAndroid.os.IBinder Asbinder () {return This; } @Override Public BooleanOntransact (intCode, Android.os.Parcel data, android.os.Parcel reply,intFlagsthrowsandroid.os.RemoteException {Switch(code) { Caseinterface_transaction: {reply.writestring (descriptor); return true; } Casetransaction_test: {data.enforceinterface (descriptor); This. Test (); Reply.writenoexception (); return true; } } return Super. Ontransact (Code, data, reply, flags); } Private Static classProxyImplementsCom.aprz.aidl.AidlTest {PrivateAndroid.os.IBinder Mremote; Proxy (Android.os.IBinder remote) {mremote=remote; } @Override PublicAndroid.os.IBinder Asbinder () {returnMremote; } Publicjava.lang.String Getinterfacedescriptor () {returndescriptor; } @Override Public voidTest ()throwsandroid.os.RemoteException {android.os.Parcel _data=Android.os.Parcel.obtain (); Android.os.Parcel _reply=Android.os.Parcel.obtain (); Try{_data.writeinterfacetoken (descriptor); Mremote.transact (Stub.transaction_test, _data, _reply,0); _reply.readexception (); } finally{_reply.recycle (); _data.recycle (); } } } Static Final intTransaction_test = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } Public voidTest ()throwsandroid.os.RemoteException;}
The code accomplishes three tasks:
1. The file itself is a Java interface that contains the service functions declared by the Aidl file (at the bottom of the file).
2, defines a proxy class, this class as the customer service side to access the agent of the server, mainly to unify the order of the parameters written in the package (when we use the stub asinterface in the customer service side to convert IBinder to a specific interface in order to invoke the service-side method, In fact, the proxy object returned, the main task of the agent is to unify the order of the parameters written in the package.
We need more details to explain the meaning of this sentence. We know that the server is a Binder object, so let's say we design a service side that provides only two methods: Start (String FilePath) and stop ().
Then the code is roughly the following:
Public classMusicplayserviceextendsbinder{ Public voidStart (String filePath) {} Public voidstop () {}//The service side must implement the Ontransact () method@overrideprotected BooleanOntransact (intCode, Parcel data, pacel reply,intFlagsthrowsRemoteException {return Super. Ontransact (Code, data, reply, flags); }}
Ontransact's second parameter, data, is the parameters passed by the customer service side, so how do I read this parameter correctly (assuming there are multiple parameters)?
The correct way to read this should be:
= data.readstring (); start (FilePath);
Enforceinterface () is for some kind of calibration, corresponding to the Writeinterfacetoken () method on the customer service side. Since I wrote the Aidl file does not have parameters, from the code generated by it can not see what, you could do your own testing, to the Aidl file method plus a number of parameters, look at the generated code in the stub and proxy class method, contrast.
3, define a stub class, mainly by the service side to use. This class is abstract because the specific function service must be implemented by a programmer, as follows:
Public class extends Service { @Override public ibinder onbind (Intent Intent) { return mbinder; } Private Final New aidltest.stub () { publicvoidthrows remoteexception { LOG.E ("aidl", "Output from service side");}} ;}
We need to return a IBinder object, the Mbinder object is an instance object of the stub, need to implement its abstract method, Binder and IBinder relationship: public class binder implements IBinder.
In addition, some constants in the stub, such as Transaction_test, correspond to the service function, since the server receives the call message and executes the Ontransact () method, which is judged by this constant. Which method to execute (transaction_test indicates that the service side's test method needs to be executed). There is also a asinterface function in the stub that returns a Binder object, and it is important to note that if the binder reference from the server is fetched from the remote, the object in the binder driver is returned, if it is obtained from within the server-side process, A Binder object is returned to the service side itself (when a binder object is created, the server creates one, and the binder driver creates one).
The binder of Android