前言

  开发一个app时,常用Activity和Fragment,由于操作方便Fragment越来越受欢迎,这样就避免不了Activity和Fragment、Fragment和Fragment之间的通信,我们知道Fragment和Fragment之间不能直接进行通信的,而是通过Activity进行通信。那么Activity和Fragment有几种通信方式呢,它们的优缺点又是什么?

一 常用的Activity和Fragment几种通信方式

1 通过Handle
在Activity创建一个Handle机制实例,然后在创建Fragment的通过构造方法把Handle实例传递过去,这样Fragment就可以往Activity传送数据了。但这样如下缺点:
(1)Activity和Fragment之间耦合性增大;
(2)Activity处理后的结果不能实时反馈给Fragment;
(3)提高了内存泄漏风险;
2 使用static变量
缺点很明确增大内存消耗;
3 使用广播
分别在Activity和Fragment中注册广播,这样就可以实现通信了。其缺点:
(1)性能差,有延迟,用户体验就会差;
(2)一般使用的是标准广播,一个发送,多个接收者,大材小用,性能差;
(3)代码冗余;
(4)传播的数据有限;
4 EventBus 、rxBus(俗称万能油)
其使用方法参考官方文档,其优点就是实用起来简单方便,其缺点也很明显:
(1)EventBus 、rxBus其内部使用的是反射机制,那么其性能就会降低;
(2)代码维护困难(不熟悉的项目代码的新人很难找到实现的方法在是如何调用的);
(3)数据返回困难,它们是单向传递;
5 普通接口
在Fragment写一个接口,让Activity去实现这个接口,通过这个接口把Activity与Fragment绑定在一起,这样Activity和Fragment实时进行通信了,其实谷歌推荐就是这么干的,由于每个Fragment都写一个接口,就会造成代码冗余;如果Fragment少的话还好,多的话,Activity实现多个接口,显得Activity头部很大,况且接口的命名也是一个问题;

二 万能接口

如果在5的基础能够解决代码冗余、接口命名就好了,我们知道一个函数包括函数名、函数体、参数、返回值,那么就可以通过搭建一个简单的框架实现上述问题。
1 建立基类

public abstract  class Function {
/** 方法名 */
public String mFunctionName ; public Function (String funName){
this.mFunctionName = funName;
} }

2 建立无(有)参数无(有)四类

/**
* 无参无返回值
* <h3>Description</h3>
* TODO
* <h3>Author</h3> luzhenbang
* <h3>Date</h3> 2018/1/4 16:13
* <h3>Copyright</h3> Copyright (c)2018 Shenzhen TL Co., Ltd. Inc. All rights reserved.
*/
public abstract class FunctionNoParamNoResult extends Function { public FunctionNoParamNoResult(String funName) {
super(funName);
} public abstract void function(); }
/**
* 有参无返回值
* <h3>Description</h3>
* TODO
* <h3>Author</h3> luzhenbang
* <h3>Date</h3> 2018/1/4 16:13
* <h3>Copyright</h3> Copyright (c)2018 Shenzhen TL Co., Ltd. Inc. All rights reserved.
*/ public abstract class FunctionWithParamOnly<Param> extends Function {
public FunctionWithParamOnly(String funName) {
super(funName);
}
public abstract void function(Param param);
}
/**
* 有参有返回值
* <h3>Description</h3>
* TODO
* <h3>Author</h3> luzhenbang
* <h3>Date</h3> 2018/1/4 16:13
* <h3>Copyright</h3> Copyright (c)2018 Shenzhen TL Co., Ltd. Inc. All rights reserved.
*/ public abstract class FunctionWithParamWithResult<Result,Param> extends Function {
public FunctionWithParamWithResult(String funName) {
super(funName);
}
public abstract Result function(Param param);
}
/**
* 无参有返回值
* <h3>Description</h3>
* TODO
* <h3>Author</h3> luzhenbang
* <h3>Date</h3> 2018/1/4 16:13
* <h3>Copyright</h3> Copyright (c)2018 Shenzhen TL Co., Ltd. Inc. All rights reserved.
*/ public abstract class FunctionWithResultOnly<Result> extends Function {
public FunctionWithResultOnly(String funName) {
super(funName);
}
public abstract Result function();
}

  

3 建立管理器类

public class FunctionManager {

private static FunctionManager instance = null;
public static final String TAG = FunctionManager.class.getSimpleName() + "-------->"; /**容器,用来存储方法名字 key 对应的方法名 value 对应的是 参数返回对象*/
private HashMap<String,FunctionWithParamWithResult> mFunctionWithParamWithResultHashMap = null;
private HashMap<String,FunctionWithParamOnly> mFunctionWithParamsOnlyHashMap = null;
private HashMap<String,FunctionWithResultOnly> mFunctionWithResultOnlyHashMap = null;
private HashMap<String,FunctionNoParamNoResult> mFunctionNoParamNoResultHashMap = null; private FunctionManager() {
mFunctionNoParamNoResultHashMap = new HashMap<>();
mFunctionWithParamWithResultHashMap = new HashMap<>();
mFunctionWithParamsOnlyHashMap = new HashMap<>();
mFunctionWithResultOnlyHashMap = new HashMap<>();
} public static FunctionManager getInstance() {
if (null == instance){
instance = new FunctionManager();
}
return instance;
} /**
* 添加无参无返回值的方法
* @return
*/
public FunctionManager addFunction(FunctionNoParamNoResult function){
mFunctionNoParamNoResultHashMap.put(function.mFunctionName,function);
return this;
} /**
* 添加有返回值的方法
* @return
*/
public FunctionManager addFunction(FunctionWithResultOnly function){
mFunctionWithResultOnlyHashMap.put(function.mFunctionName,function);
return this;
} /**
* 添加有参数的方法
* @return
*/
public FunctionManager addFunction(FunctionWithParamOnly function){
mFunctionWithParamsOnlyHashMap.put(function.mFunctionName,function);
return this;
} /**
* 添加有参有返回值的方法
* @return
*/
public FunctionManager addFunction(FunctionWithParamWithResult function){
mFunctionWithParamWithResultHashMap.put(function.mFunctionName,function);
return this;
} /**
* 调用无返回值无参数的方法
* @param funName
*/
public void invokeNoAll (String funName) throws NullPointerException {
if (TextUtils.isEmpty(funName)){
Log.e(TAG,"funName is null !");
}else {
if ( null != mFunctionNoParamNoResultHashMap){
FunctionNoParamNoResult function = mFunctionNoParamNoResultHashMap.get(funName);
if (null != function){
function.function();
}else {
Log.e(TAG,"function is null !");
}
}else {
throw new NullPointerException("mFunctionNoParamNoResultHashMap can not be null ,please first init FunctionManager !");
}
}
} /**
* 调用有参数的方法
* @param funName
*/
public <Param> void invokeWithParamOnly (String funName,Param param) throws NullPointerException {
if (TextUtils.isEmpty(funName)){
Log.e(TAG,"funName is null !");
}else {
if ( null != mFunctionWithParamsOnlyHashMap){
FunctionWithParamOnly<Param> function = mFunctionWithParamsOnlyHashMap.get(funName);
if (null != function){
function.function(param);
}else {
Log.e(TAG,"function is null !");
}
}else {
throw new NullPointerException("mFunctionWithParamsOnlyHashMap can not be null ,please first init FunctionManager !");
}
}
} /**
* 调用有返回值的方法
* @param funName
*/
public <Result> Result invokeWithResultOnly (String funName, Class<Result> c) throws NullPointerException {
if (TextUtils.isEmpty(funName)){
Log.e(TAG,"funName is null !");
}else {
if ( null != mFunctionWithResultOnlyHashMap){
FunctionWithResultOnly function = mFunctionWithResultOnlyHashMap.get(funName);
if (null != function){
if ( null != c){
return c.cast(function.function());
}else {
return (Result) function.function();
}
}else {
Log.e(TAG,"function is null !");
}
}else {
throw new NullPointerException("mFunctionWithParamsOnlyHashMap can not be null ,please first init FunctionManager !");
}
}
return null; } /**
* 调用有参数有返回值的方法
* @param funName
*/
public <Result,Param> Result invokeWithAll (String funName, Class<Result> c,Param param) throws NullPointerException {
if (TextUtils.isEmpty(funName)){
Log.e(TAG,"funName is null !");
}else {
if ( null != mFunctionWithParamWithResultHashMap){
FunctionWithParamWithResult<Result,Param> function = mFunctionWithParamWithResultHashMap.get(funName);
if (null != function){
if ( null != c){
return c.cast(function.function(param));
}else {
return function.function(param);
}
}else {
Log.e(TAG,"function is null !");
}
}else {
throw new NullPointerException("mFunctionWithParamsOnlyHashMap can not be null ,please first init FunctionManager !");
}
}
return null; }
}

4 在Activity写一个方法

public void setFunctionForFragment(String tag){
if (TextUtils.isEmpty(tag)){
Log.e(MainActivity.class.getSimpleName(),"tag is null !");
return;
}
BaseFragment fragment = (BaseFragment) fm.findFragmentByTag(tag);
FunctionManager functionManager = FunctionManager.getInstance(); functionManager.addFunction(new FunctionNoParamNoResult(FunctionNoParamNoResult) {
@Override
public void function() {
Toast.makeText(MainActivity.this, "无参无返回值", Toast.LENGTH_SHORT).show();
}
}); functionManager.addFunction(new FunctionWithResultOnly<String>(FunctionWithResultOnly) {
@Override
public String function() {
return "无参有返回值";
}
}); functionManager.addFunction(new FunctionWithParamOnly<String>(FunctionWithParamOnly) {
@Override
public void function(String o) {
Toast.makeText(MainActivity.this, o, Toast.LENGTH_SHORT).show();
}
}); functionManager.addFunction(new FunctionWithParamWithResult<String,String>(FunctionWithParamWithResult) {
@Override
public String function(String o) {
return o;
}
}); fragment.setFunctionManager(functionManager);
}

5 编辑一个Fragment基类(实用Fragment的时候直接集成该类就可以了),并绑定上面建立的接口

public class BaseFragment extends Fragment{

public FunctionManager mFunctionManager;
private MainActivity mainActivity; public void setFunctionManager(FunctionManager mFunctionManager) {
this.mFunctionManager = mFunctionManager;
} @Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof MainActivity) {
mainActivity = (MainActivity) context;
mainActivity.setFunctionForFragment(getTag());
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
} @Override
public void onDetach() {
super.onDetach();
mainActivity = null;
} }

6 继承BaseFragment

public class NoParamNoResultFragment extends BaseFragment {

private Handler  mHandler;

    public NoParamNoResultFragment(Handler  handler) {
// Required empty public constructor
this.mHandler = handler;
} @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
}
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_no_param_no_result, container, false); view.findViewById(R.id.txt_handle).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = mHandler.obtainMessage();
message.what = 0x123;
message.obj = "handle 通信";
mHandler.sendMessage(message);
}
}); view.findViewById(R.id.txt_noALl).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mFunctionManager.invokeNoAll(MainActivity.FunctionNoParamNoResult); }
});
view.findViewById(R.id.txt_result).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// mFunctionManager.invokeNoAll(MainActivity.FunctionNoParamNoResult);
String result = mFunctionManager.invokeWithResultOnly(MainActivity.FunctionWithResultOnly,String.class);
Toast.makeText(getActivity(), result, Toast.LENGTH_SHORT).show();
}
});
view.findViewById(R.id.txt_param).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mFunctionManager.invokeWithParamOnly(MainActivity.FunctionWithParamOnly,"有参无返回值");
}
});
view.findViewById(R.id.txt_withAll).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String result = mFunctionManager.invokeWithAll(MainActivity.FunctionWithParamWithResult,String.class,"有参有返回值");
Toast.makeText(getActivity(), result, Toast.LENGTH_SHORT).show();
}
});
return view;
}
}

说明,上述在点击控件的时候,会触发在Activity添加的方法,这样就可以实现Activity与Fragment实时通信,近而实现Fragment之间的通信  

https://gitee.com/lzbgit/AppInterface  

 

最新文章

  1. RecyclerView的使用之多种Item加载布局
  2. 多表头固定demo--html Table
  3. Win10系统下编译GDAL1.9.2版本
  4. [g2o]一个备忘
  5. views中的公共代码放在一起
  6. insertion sort
  7. [linux]linux下开启wifi热点
  8. [Effective Modern C++] Item 3. Understand decltype - 了解decltype
  9. 蓝桥杯算法训练&lt;二&gt;
  10. Bootstrap 网格系统
  11. scrapy爬虫框架和selenium的配合使用
  12. null 和System.DBNull.Value
  13. 计蒜客 2019 蓝桥杯省赛 B 组模拟赛(三)数字拆分
  14. 【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--请求处理结果适配篇(7/8)
  15. 在WIN10打造成能运行Oracle的JDK的Linux
  16. arcface和Dlib人脸识别算法对比
  17. SpringMVC之类型转换
  18. WPF基础学习笔记整理 (九) 资源
  19. .NET 2.0 参考源码索引
  20. linux 命令 uniq

热门文章

  1. DedeCMS上传视频
  2. [java]__如何用你的编程语言表达至尊宝&quot;爱你一万年&quot;的浪漫情怀.
  3. IntelliJ IDEA 注册码 (秘钥)
  4. WebBrowser使用例子
  5. 2016 ACM/ICPC亚洲区青岛站现场赛(部分题解)
  6. man exportfs(exportfs命令中文手册)
  7. Perl的输出:print、say和printf、sprintf
  8. 使用NetworkX模块绘制深度神经网络(DNN)结构图
  9. [转]启动container的时候出现iptables: No chain/target/match by that name
  10. 【转载】Windows服务器修改远程桌面默认端口