• 架构师成长之路-基于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 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  

     

  • 相关阅读:
    Gitlab -- 基本操作
    javascript--事件委托
    javascript--Dom 二级事件
    Tableau学习笔记之五
    Tableau学习笔记之二
    Tableau学习笔记之四
    Tableau学习笔记之三
    Tableau学习笔记之一
    Qt使用Cookies对网站操作之Get和POST
    C++ 使用Htmlcxx解析Html内容(VS编译库文件)
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/9249764.html
Copyright © 2020-2023  润新知