厌伴老儒烹瓠叶,强随举子踏槐花。这篇文章主要讲述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 = https://www.songbingjia.com/android/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 = "https://www.songbingjia.com/android/+ 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输出:
【Android实现组件之间同步的回调通信】03-03 11:50:28.780 2790-2790/? D/TEST: code=1 | value = https://www.songbingjia.com/android/1
03-03 11:50:28.782 2790-2790/? D/TEST: code=1 | value = https://www.songbingjia.com/android/2
03-03 11:53:07.588 2790-2790/? D/TEST: code=1 | value = https://www.songbingjia.com/android/3
推荐阅读
- android Dialog 底部弹出
- 安卓搭建局域网服务器KSWEB--序列号
- app性能测试通过loadrunner录制
- Android开发入门的正确姿势,你get到了吗()
- Android 使用内置的Camera应用程序捕获图像
- Hook android系统调用的实践
- 安卓车牌识别与警务通PDA之间的联系
- 通过cordova将vue项目打包为app
- 安卓动态添加碎片