The cornerstone of interprocess communication (IPC) in Android is the binder system, where the core binder drive of the binder system is C, which is undoubtedly obscure for application developers, and the entire Android framework is based on object-oriented thinking, The details of the operation of the underlying binder drive are all hidden, and the framework layer provides a very powerful binder object, so we want to implement interprocess communication (IPC) by simply playing with the binder object.
In the Android source code based on binder object communication can be found everywhere, almost recognized as the beginning of the class I, all have interprocess communication capabilities, such as: Iservicemanager,icontentprovider.
The way in which the source code is implemented can also be summarized as two kinds:
1. Use Aidl to generate the action on the binder.
2. Manually call Ibinder.transact to write the parcel code implementation that is written in sequence and read out.
The first method of online case more, not much to say. The second method realizes source code reference: Activitymanagernative,activitymanagerproxy
About the implementation of the second method I made a demo, please see the following code.
package dw.test;import java.util.hashmap;import android.os.binder;import android.os.ibinder;import android.os.iinterface;import android.os.parcel;import android.os.remoteexception;import android.util.log;/** * is responsible for receiving instructions ({@link cmdcode}), and distribute the instructions to the appropriate processor ({@link cmddispatcher.callback}) */public final class cmddispatcher extends binder implements iinterface{ private static final string log_tag = cmddispatcher.class.getsimplename ();p ublic static final string Descriptor = cmddispatcher.class.getname ();/** * stores all directive processors * map.key = {@link cmdcode} */private hashmap<integer,callback> mcallbacks = new HashMap<Integer, Callback> ();/** * processing * @see #addCallback for an instruction * @see #removeCallback &NBSP;*/PUBLIC&NBSP;INTERFACE&NBSp callback {/** * @param code Request instruction set {@link cmdcode.request}, Response instruction set {@link cmdcode.response} * @param data Data {@link Parcel} * @param reply Results of data processing {@link Parcel} * @return */public boolean ontransact (int code, parcel data, parcel reply);} /** * when the client side calls {@link ibinder#transact (int, parcel, parcel, int)}, This method will be recalled. */@Overrideprotected boolean ontransact (int code, parcel data, parcel reply,int flags) throws remoteexception {dispatch (code,data,reply); return true;} /** * gets a directive processor and calls */private void dispatch (Int code, parcel data, parcel reply) {log.i (log_tag, "Dispatch reply enter"); Callback callback = mcallbacks.get (code); if (callback!=null) {Callback.ontransacT (code, data, reply);} LOG.I (log_tag, "Dispatch reply exit");} @Overridepublic ibinder asbinder () {return this;} @Overridepublic string getinterfacedescriptor () {return descriptor;} @Overridepublic iinterface querylocalinterface (String descriptor) {return this;} /** * for a directive, such as: request instruction set {@link cmdcode.request}, Response instruction set {@link cmdcode.response} * Add callback processing * @param code instruction encoding * @param callback for a given processing {@ Link callback} */public void addcallback (Int code,callback callback) { Mcallbacks.put (code, callback);} Public void removecallback (Int code) {mcallbacks.remove (code);}}
Package dw.test;/** * Define instruction Set */public interface Cmdcode {public interface Basecode {/** * header parcel static final for each */public int parcel_head = 0xffff;public static final int result_success = 0x0001;public static final int result_error = 0x0002;} /** * Requesting instruction set */public interface request extends basecode{public static final int request = 0x0001;} /** * Response instruction Set */public interface Response extends Basecode {public static final int Response = 0x0001;}}
package dw.test;import dw.test.cmddispatcher.callback;import android.app.service;import android.content.intent;import android.os.ibinder;import android.os.parcel;import Android.util.log;/** * remoteservice as an independent process exists . */public class remotecmdservice Extends service implements callback,cmdcode.request{private static final string log_tag = remotecmdservice.class.getsimplename ();p rivate final cmddispatcher Mcmddispatcher = new cmddispatcher (); @Overridepublic ibinder onbind (intent Intent) {mcmddispatcher.addcallback (request, this); return mcmddispatcher;} @Overridepublic void oncreate () {super.oncreate ();} @Overridepublic int onstartcommand (Intent intent, int flags, int startid) &NBSP;{LOG.I (log_tag, "Onstartcommand enter"); Return super.onstartcommand (intent, flags, startid);} @Overridepublic boolean ontransact (int code, parcel data, parcel reply) &NBSP;{LOG.I (log_tag, "Remove service handle reply enter");d Ata.enforceinterface ( Cmddispatcher.descriptor);//Read Header int head = data.readint (); if (Head==parcel_head) {String handeresult = data.readstring (); Reply.writeint (result_success); LOG.I (Log_tag, handeresult);} else {reply.writeint (Result_error); &NBSP;}LOG.I (log_tag, "Remove service handle reply exit "); return true;}}
package dw.test.activity;import android.app.activity;import android.content.componentname; Import android.content.intent;import android.content.serviceconnection;import android.os.bundle ; import android.os.ibinder;import android.os.parcel;import android.os.remoteexception;import android.util.log;import android.view.view;import android.view.view.onclicklistener;import dw.test.CmdCode;import dw.test.CmdDispatcher;import dw.test.R;import dw.test.remotecmdservice;public class mainactivity extends activity implements onclicklistener , cmdcode.request,cmdcode.response{private static final string Log_tag = mainactivity.class.getsimplename (); @Override public void oncreate (bundle savedinstancestate) { super.oncreate (savedinstancestate), &Nbsp; setcontentview (R.layout.activity_main); this.findviewbyid (R.ID.TEST_REMOTE_BINDER_BTN). Setonclicklistener (This); } /** * Connect and invoke remote services */ private void testremote () { intent intent = new intent (mainactivity.this,remotecmdservice.class); //bind remote service bindservice (Intent, new serviceconnection () {@Overridepublic void Onservicedisconnected (componentname name) {} @Overridepublic void onserviceconnected ( Componentname name, ibinder service) {replyto (service);}}, bind_auto_create); } private void replyto (Ibinder service) {Parcel data = pArcel.obtain (); Parcel reply = parcel.obtain ();d Ata.writeinterfacetoken (cmddispatcher.descriptor);// Write to the header data.writeint (parcel_head);//write the character data to be sent data.writestring ("serviceconnected");// Of course you can also pass a binder object past as a callback, so that two processes can interact with each other. Data.writestrongbinder (ibinder binder); try {//calls the remote Message_request service service.transact (REQUEST, data, reply,0);} catch (remoteexception e) {//ignore}//message_request The results returned by the service int result = reply.readint (); if (Result_success==result) {log.i (log_tag, "OK");} Data.recycle (); Reply.recycle ();} @Overridepublic void onclick (VIEW&NBSP;V) {int id = v.getid (); if (r.id.test_ Remote_binder_btn==id) {testremote ();}} }
Code Engineering:http://download.csdn.net/detail/hacker686ok/5810399
Android non-aidl for interprocess communication (write sequential parcel write and read)