Android non-aidl for interprocess communication (write sequential parcel write and read)

Source: Internet
Author: User

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)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.