Android实现组件之间同步的回调通信
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; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 重写SyncResultReceiver的onReceiveResult方法接收返回值 SyncResultReceiver mResultReceiver = new SyncResultReceiver(){ @Override protected void onReceiveResult(int code, Bundle bundle) { value = bundle.getInt("value"); Log.d("TEST", "code=" + code + " | value = " + value); } }; // 开启Activity2 Intent 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; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mReceiver = getIntent().getParcelableExtra("callback"); // 给MainActivity回调值 Bundle bundle = new Bundle(); bundle.putInt("value", 1); mReceiver.send(1, bundle); } @Override protected void onStart() { super.onStart(); // 给MainActivity回调值 Bundle bundle = new Bundle(); bundle.putInt("value", 2); mReceiver.send(1, bundle); } @Override protected 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