为了账号安全,请及时绑定邮箱和手机立即绑定

架构师成长之路-基于android fragment通信的面向对象的万能接口

标签:
Android 架构

前言

  开发一个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  

架构师成长之路-基于android fragment通信的面向对象的万能接口

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消