青春须早为,岂能长少年。这篇文章主要讲述架构师成长之路-基于android fragment通信的面向对象的万能接口相关的知识,希望能为你提供帮助。
前言
开发一个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 abstractclass Function { /** 方法名 */ public String mFunctionName ; public Function (String funName){ this.mFunctionName = funName; }}
【架构师成长之路-基于android fragment通信的面向对象的万能接口】2 建立无(有)参数无(有)四类
/** *无参无返回值 * < h3> Description< /h3> * TODO * < h3> Author< /h3> luzhenbang * < h3> Date< /h3> 2018/1/4 16:13 * < h3> Copyright< /h3> Copyright (c)2018 Shenzhen TLCo., 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 TLCo., 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 TLCo., 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 TLCo., 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 HandlermHandler; public NoParamNoResultFragment(Handlerhandler) { // 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 Viewview= 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) { Messagemessage = 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
推荐阅读
- 04.基于IDEA+Spring+Maven搭建测试项目--配置application-context.xml
- xamarin 安卓输出中文错误 乱码解决
- xamarin自定义 application 无法调试
- 修改admin中App的名称与表的名称
- Macbook pro Version 14.0 cannot copy and paste between different applicatons after updated system(示例
- 8Flask实战第8天(add_url_rule和app.route原理)
- Android移动开发-集成调用支付宝支付开发的实现
- 安卓自动化测试(Robotium批量运行测试代码)
- 教你知道电脑知识:固态硬盘与U盘有啥区别