1, first of all, see two examples
(1) in-process
Client Side
public class Counterservice extends Service implements Icounterservice { ... public class Counterbinder extends Bin Der {public counterservice GetService () { return counterservice.this; } } ......}
Server Side
public class Mainactivity extends Activity implements Onclicklistener { ... private serviceconnection Serviceconnection = new Serviceconnection () {public void onserviceconnected (ComponentName className, IBinder Service) { Counterservice = ((counterservice.counterbinder) service). GetService (); LOG.I (Log_tag, "Counter Service Connected"); } ......}; ......}
(1) Inter-process
Client Side
public class Remoteservice extends Service {private final static String TAG = "Remoteservice"; @Overridepublic ibinder Onbi nd (Intent Intent) {log.i (TAG, "executed Onbind"); return new Mybinder ();} Private class Mybinder extends remotewebpage.stub{@Overridepublic String Getcurrentpageurl () throws remoteexception{ return "http://www.cnblogs.com/hibraincol/";}}}
Server Side
Private class Myserviceconnection implements serviceconnection{@Overridepublic void onserviceconnected (componentname Name, IBinder service) {LOG.I (tag, "Establish connection ..."), Remotewebpage = RemoteWebPage.Stub.asInterface (service), try {LOG.D (tag, Remotewebpage.getcurrentpageurl ());} catch (RemoteException e) {//TODO auto-generated catch Blocke.printstacktrace ();}} @Overridepublic void onservicedisconnected (componentname name) {log.i (TAG, "onservicedisconnected ...");}}
Why one is
Counterservice = ((counterservice.counterbinder) service). GetService ();
The other is
Remotewebpage = RemoteWebPage.Stub.asInterface (service);
The reason is that the first service is the Counterservice object, and the second service is the Binderproxy object, which points to the Mybinder object.
Why is there a difference between in-process and process? Please see:
In the 6th step, the parameter to be passed is the Binderproxy object.
The following code is executed in the process:
Case Binder_type_handle:case binder_type_weak_handle: {struct Binder_ref *ref = binder_get_ Ref (proc, fp->handle); ... if (Ref->node->proc = = Target_proc) {//same process if (Fp->type = = Binder_type_h Andle) Fp->type = Binder_type_binder; else Fp->type = Binder_type_weak_binder; Fp->binder = ref->node->ptr; Fp->cookie = ref->node->cookie; Binder_inc_node (ref->node, Fp->type = = Binder_type_binder, 0, NULL); if (Binder_debug_mask & binder_debug_transaction) printk (kern_info "ref%d desc%d-> ; Node%d u%p\n ", ref->debug_id, Ref->desc, ref->node->debug_id, ref->node-> PTR); } else {...} } To convert intoCounterservice object to be prepared.
The following code is executed between processes:
Case Binder_type_handle:case binder_type_weak_handle: {struct Binder_ref *ref = binder_get_ Ref (proc, fp->handle); ... if (Ref->node->proc = = Target_proc) {...} else {//different processes struct Binder_ref *new_ref; New_ref = Binder_get_ref_for_node (Target_proc, Ref->node); if (new_ref = = NULL) {return_error = br_failed_reply; Goto err_binder_get_ref_for_node_failed; } Fp->handle = new_ref->desc; Binder_inc_ref (new_ref, Fp->type = = Binder_type_handle, NULL); if (Binder_debug_mask & binder_debug_transaction) printk (kern_info "ref%d desc%d-> ; Ref%d desc%d (node%d) \ n ", ref->debug_id, Ref->desC, new_ref->debug_id, New_ref->desc, ref->node->debug_id); } }To convert intoBinderproxy object to be prepared. At this point the Binderproxy object is the counter process, and theMybinder object is the Counterservice process. They pass data in a way that communicates between processes.