Android开发中,有时会遇到组件之间相互通信回调的问题。一般都是通过Android提供的ResultReceiver来实现(ResultReceiver的使用方法很简单,这里就不多提了)。
但之前在工作中,遇到了一个组件间回调的问题,ResultReceiver无法满足需求。简单描述一下问题:service中打开了一个activity,activity需要将一个变量值回调给service,而且这个回调必须是同步的。也就是说activity在确认service接收到了这个变量值后,才能继续向下执行代码。众所周知ResultReceiver的send方法是异步的,send方法执行后,接收方可能还没有收到消息。这样"不及时"的回调在我的项目中可能会造成状态不同步。
那么,只能自己实现一个同步的回调通信。
同步的回调通信代码如下:
github地址:https://github.com/yuhaiyang89/yhy-utils
1.定义一个AIDL
package com.yhy.utils; interface IChannel {void send(int code, in Bundle data); }
2.定义一个类,实现Parcelable(实现Parcelable是为了能让该类在组件中传递),并在此类中实现第一步定义的AIDL(通过这个AIDL完成回调)
package com.yhy.utils.demo;import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; import com.yhy.utils.IChannel;public class SyncResultReceiver implements Parcelable {public static final Parcelable.Creator<SyncResultReceiver> CREATOR = new Parcelable.Creator<SyncResultReceiver>() {public SyncResultReceiver createFromParcel(Parcel in) {return new SyncResultReceiver(in);}public SyncResultReceiver[] newArray(int size) {return new SyncResultReceiver[size];}};// 是本地回调还是远程回调final boolean mLocal;IChannel mBridge;public SyncResultReceiver() {mLocal = true;}SyncResultReceiver(Parcel in) {mLocal = false;mBridge = IChannel.Stub.asInterface(in.readStrongBinder());}public void send(int code, Bundle data) {if (mLocal) {onReceiveResult(code, data);return;}if (mBridge != null) {try {mBridge.send(code, data);} catch (Exception e) {Log.e("", "",e);}}}protected void onReceiveResult(int code, Bundle bundle) {// 等待子类去实现此方法,接收消息 }public int describeContents() {return 0;}public void writeToParcel(Parcel out, int flags) {synchronized (this) {if (mBridge == null) {mBridge = new MyChannel();}out.writeStrongBinder(mBridge.asBinder());}}class MyChannel extends IChannel.Stub {public void send(int code, Bundle data) {onReceiveResult(code, data);}} }
实现完毕!
下面就可以使用SyncResultReceiver来实现同步回调了
例:MainActivity中打开Activity2,Activity2将一些消息同步的回调给MainActivity
MainActivity代码:
package com.yhy.utils.demo;import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log;public class MainActivity extends AppCompatActivity {private int value = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 重写SyncResultReceiver的onReceiveResult方法接收返回值SyncResultReceiver mResultReceiver = new SyncResultReceiver(){@Overrideprotected void onReceiveResult(int code, Bundle bundle) {value = bundle.getInt("value");Log.d("TEST", "code=" + code + " | value = " + value);}};// 开启Activity2Intent intent = new Intent(this, Activity2.class);intent.putExtra("callback", mResultReceiver);startActivity(intent);} }
Activity2代码:
package com.yhy.utils.demo;import android.support.v7.app.AppCompatActivity; import android.os.Bundle;public class Activity2 extends AppCompatActivity {SyncResultReceiver mReceiver = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mReceiver = getIntent().getParcelableExtra("callback");// 给MainActivity回调值Bundle bundle = new Bundle();bundle.putInt("value", 1);mReceiver.send(1, bundle);}@Overrideprotected void onStart() {super.onStart();// 给MainActivity回调值Bundle bundle = new Bundle();bundle.putInt("value", 2);mReceiver.send(1, bundle);}@Overrideprotected void onDestroy() {// 给MainActivity回调值Bundle bundle = new Bundle();bundle.putInt("value", 3);mReceiver.send(1, bundle);super.onDestroy();} }
LOG输出:
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