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;@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




转载于:https://www.cnblogs.com/younghome/p/6804399.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:https://dhexx.cn/news/show-18568.html

如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网进行投诉反馈,一经查实,立即删除!


相关文章:

  • SharePoint 2013 同步FBA认证用户
  • select下拉列表
  • react中创建组件的三种方法
  • Hibernate基础及配置
  • 垂直存储数据设想
  • [bzoj1042] [HAOI2008]硬币购物
  • 解密小程序码:36条放射线
  • javaweb几种常见乱码问题解决
  • PHP URL参数获取方式的四种例子
  • JavaScript 代码收集
  • AngularJS中$apply
  • mongo-connector导入数据到Es
  • Android异步载入AsyncTask具体解释
  • VS2013 update4+Cocos2d-x 3.7 Win8下安装方法及配置
  • Spark分布式安装
  • ios微信上无法自动播放音频的情况
  • Bootstrap学习之三:使用排版
  • Java面向对象(一)20170517
  • Linux下文件操作命令cat(转)
  • Simulink模块之VCO(压控振荡器)
  • Ubuntu 关闭触摸板
  • OneNET麒麟座应用开发之五:获取加速度传感器ADXL345数据
  • spring quartz执行两次问题
  • Redux零碎知识点回顾
  • 笔记3
  • [转] NOI, NOIP, IOI, ACM
  • numpy之转置(transpose)和轴对换
  • P2661 信息传递
  • 【solr基础教程之中的一个】Solr相关知识点串讲
  • Python练习5-正则表达式
  • 怎么把excel表格内的数据导入数据库?
  • Hibernate_01_初体验
  • java并发编程(1)并发程序的取消于关闭
  • hihoCoder - 1079 - 离散化 (线段树 + 离散化)
  • poj 2442 Sequence
  • bzoj 3676: [Apio2014]回文串
  • Linux ssh服务开启秘钥和密码认证
  • Spring Boot和Dubbo整合
  • ufldl学习笔记与编程作业:Linear Regression(线性回归)
  • Python-面向对象之一
  • 浅析我对代码规范的理解
  • Swift - 实现tableView单选系统样式
  • Problems with Ribbon/Feign/Zuul retry
  • 绝大多数人努力程度之低,根本轮不上拼天赋
  • GDTR与LDTR
  • c#之正则表达式
  • Makefile文件(一)_介绍
  • 高级控件 下(三)
  • ArcGIS Python实现Modis NDVI批量化月最大合成
  • crmjs区分窗口是否是高速编辑(2)