In Android development, there are sometimes problems with communication callbacks between components. It is generally done through Android-provided Resultreceiver (Resultreceiver is very simple to use, not much to mention here).
However, before the work, encountered a callback between the components of the problem, Resultreceiver can not meet the requirements. A brief description of the problem: opening a activity,activity in service requires the callback of a variable value to the service, and the callback must be synchronous . This means that the activity can continue executing the code down after confirming that the service received the variable value. It is well known that the Resultreceiver send method is asynchronous, and the receiving Party may not have received the message after the Send method executes. This "not in time" callback may cause the state to be out of sync in my project.
Then, you can only implement a synchronous callback communication on your own.
The synchronous callback communication code is as follows:
GitHub Address: Https://github.com/yuhaiyang89/yhy-utils
1. Define a Aidl
Package com.yhy.utils; Interface ichannel { void Send (int Code, in Bundle data);}
2. Define a class that implements Parcelable (implementing Parcelable to enable the class to be passed in the component) and implement the first step definition of aidl (through this aidl completion callback) in this class
PackageCom.yhy.utils.demo;ImportAndroid.os.Bundle;ImportAndroid.os.Parcel;Importandroid.os.Parcelable;ImportAndroid.util.Log;ImportCom.yhy.utils.IChannel; Public classSyncresultreceiverImplementsparcelable { Public Static FinalParcelable.creator<syncresultreceiver> Creator =NewParcelable.creator<syncresultreceiver>() { Publicsyncresultreceiver Createfromparcel (Parcel in) {return NewSyncresultreceiver (in); } PublicSyncresultreceiver[] NewArray (intsize) { return NewSyncresultreceiver[size]; } }; //is a local callback or a remote callback Final Booleanmlocal; IChannel Mbridge; PublicSyncresultreceiver () {mlocal=true; } syncresultreceiver (Parcel in) {mlocal=false; Mbridge=IChannel.Stub.asInterface (In.readstrongbinder ()); } Public voidSendintcode, Bundle data) { if(mlocal) {Onreceiveresult (code, data); return; } if(Mbridge! =NULL) { Try{mbridge.send (code, data); } Catch(Exception e) {LOG.E ("", "", E); } } } protected voidOnreceiveresult (intcode, bundle bundle) { //wait for subclasses to implement this method to receive messages } Public intdescribecontents () {return0; } Public voidWritetoparcel (Parcel out,intflags) { synchronized( This) { if(Mbridge = =NULL) {Mbridge=NewMyChannel (); } out.writestrongbinder (Mbridge.asbinder ()); } } classMyChannelextendsIchannel.stub { Public voidSendintcode, Bundle data) {Onreceiveresult (code, data); } }}
The implementation is complete!
You can use Syncresultreceiver to implement synchronous callbacks.
Example: Open Activity2,activity2 in mainactivity to mainactivity of some message synchronization callbacks
Mainactivity Code:
PackageCom.yhy.utils.demo;Importandroid.content.Intent;Importandroid.support.v7.app.AppCompatActivity;ImportAndroid.os.Bundle;ImportAndroid.util.Log; Public classMainactivityextendsappcompatactivity {Private intValue = 0; @Overrideprotected voidonCreate (Bundle savedinstancestate) {Super. OnCreate (savedinstancestate); Setcontentview (R.layout.activity_main); //override Syncresultreceiver's Onreceiveresult method to receive the return valueSyncresultreceiver Mresultreceiver =NewSyncresultreceiver () {@Overrideprotected voidOnreceiveresult (intcode, bundle bundle) {Value= Bundle.getint ("Value"); LOG.D ("TEST", "code=" + code + "| Value = "+value); } }; //Open Activity2Intent Intent =NewIntent ( This, Activity2.class); Intent.putextra ("Callback", Mresultreceiver); StartActivity (Intent); }}
Activity2 Code:
PackageCom.yhy.utils.demo;Importandroid.support.v7.app.AppCompatActivity;ImportAndroid.os.Bundle; Public classActivity2extendsappcompatactivity {syncresultreceiver mreceiver=NULL; @Overrideprotected voidonCreate (Bundle savedinstancestate) {Super. OnCreate (savedinstancestate); Mreceiver= Getintent (). Getparcelableextra ("Callback"); //give Mainactivity callback valueBundle bundle =NewBundle (); Bundle.putint ("Value", 1); Mreceiver.send (1, bundle); } @Overrideprotected voidOnStart () {Super. OnStart (); //give Mainactivity callback valueBundle bundle =NewBundle (); Bundle.putint ("Value", 2); Mreceiver.send (1, bundle); } @Overrideprotected voidOnDestroy () {//give Mainactivity callback valueBundle bundle =NewBundle (); Bundle.putint ("Value", 3); Mreceiver.send (1, bundle); Super. OnDestroy (); }}
Log output:
03-03 11:50:28.780 2790-2790/? d/test:code=1 | Value = 1
03-03 11:50:28.782 2790-2790/? d/test:code=1 | Value = 2
03-03 11:53:07.588 2790-2790/? d/test:code=1 | Value = 3
Android implements synchronous callback communication between components