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

 

原文地址:https://www.cnblogs.com/ganchuanpu/p/9249764.html

时间: 2024-08-25 01:59:06

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

如何成为一名架构师,架构师成长之路(转)

转自http://blog.csdn.net/fei33423/article/details/61934514 如何成为一名架构师,架构师成长之路 原创 2017年03月13日 22:50:34 3116 大量阅读别人的系统实现文章( 架构= 模块图 + 模块流程图(启动 和 主流程 ,可以用拟物 tag) 或者 模块时序图) 动态+静态 .对象很重要,模块很重要. 从产品角度,用户很重要 脑图不需要按空格,收缩行 https://www.processon.com/view/link/58c

架构师成长之路5.2-Saltstack远程执行

点击架构师成长之路 架构师成长之路5.2-Saltstack远程执行 配置管理工具: Pupper:1. 采用ruby编程语言:2. 安装环境相对较复杂:3.不支持远程执行,需要FUNC工具配置才可以 Ansible:1.采用python编程语言:2.被红帽收购:3.轻量级:4.基于模块工作的,本身没有批量部署的能力,真正批量部署的是ansible所运行的模块. Saltstack:采用python编程语言,同时提供Rest API方便二次开发以及和其它平台进行集成(目前企业使用率最高) Sal

开启运维自动化架构师成长之路

技术的提升仅是量的积累,思想的提升才是质的飞跃! 这句话是我在网上看到认为最有道理的励志语录了,当然互联网IT行业的工作者相对理解的会更加深刻. 以这句话开头引出我将要写的这篇文章.首先,请允许我做一个自我介绍: 熟悉的朋友喜欢叫我一声岩哥,这么些年我也认可了这个称谓,尽管不是太好听.从毕业之后就接触了互联网,到现在工作N多年,中间有接触过游戏行业.金融行业.教育行业.云计算行业.电商购物和系统项目集成等,所有的工作经验和项目经历都是跟互联网IT技术挂钩,熟知企业中.项目中和学习中关于IT方面的

架构师成长之路2.4-Kickstart文件剖析

点击返回架构师成长之路 架构师成长之路2.4-Kickstart文件剖析 kickstart文件是一个简单的文本文件,它包含了一个项目列表,每个项目由一个关键字来识别. 创建kickstart文件注意: 每节必须按顺序指定.除非特别申明,每节内的项目则不必按序排列.小节的顺序为: 命令部分,这里应该包括必需的选项.           %packages部分,这部分选择需要安装的软件包.           %pre和%post部分,这两个部分可以按任何顺序排列而且不是必需的.前者是预安装脚本,

架构师成长之路4.4-多维监控体系_zabbix

点击返回架构师成长之路 架构师成长之路4.4-多维监控体系_zabbix 点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路[第一回]:初识Zabbix 1.1 自学Zabbix1.1-简介 1.2 自学Zabbix1.2-zabbix特性 1.3 自学Zabbix1.3-zabbix进程 自学Zabbix之路[第二回]:安装Zabbix 2.1 自学Zabbix2.1-安装需求 2.2 自学Zabbix2.2-服务器端环境

架构师成长之路6.4 DNS服务器搭建(部署主从DNS)

点击返回架构师成长之路 架构师成长之路6.3 DNS服务器搭建(部署主从DNS)  部署主DNS : 点击 部署从DNS : 如下步骤 1.与主DNS一样,安装bind yum -y install bind-utils bind bind-devel bind-chroot bind-libs 2.与主DNS一样,编辑/etc/named.conf options { version "1.1.1"; listen-on port 53 {any;}; #表示使用53端口 direc

架构师成长之路(1)--什么是架构师(目标)

前言: 哲学家常思考的问题:" 我是谁?"" 我从哪里来?"" 要到哪里去?不只是哲学家,我想每个人都有自己对这三个问题的认知. 如果我们要成为架构师,我们自己要面临的三大问题: 找准自己定位:我是谁?在哪里? 怎样做好架构师:我要做什么? 如何搭建架构师知识体系:我该怎么做? 这里面就是做事方法论:目标(我要做什么),方法(计划)(我该怎么做),  执行/行动 软件行业架构师两个定义 ?系统架构师是一个既需要掌控整体又需要洞悉局部瓶颈并依据具体的业务场景

架构师成长之路(1)--什么是架构师

前言: 哲学家常思考的问题:" 我是谁?"" 我从哪里来?"" 要到哪里去?不只是哲学家,我想每个人都有自己对这三个问题的认知. 如果我们要成为架构师,我们自己要面临的三大问题:找准自己定位:我是谁?在哪里?怎样做好架构师:我要做什么?如何搭建架构师知识体系:我该怎么做? 这里面就是做事方法论:目标(我要做什么),方法(计划)(我该怎么做), ?执行/行动 1.架构师定义 ? ? 什么是架构师,这个聊架构话题时永恒的问题.每个公司对架构师的定位也有所不同,

(转)WEB架构师成长之路之一-走正确的路

本人也是coding很多年,虽然很失败,但也总算有点失败的心得,不过我在中国,大多数程序员都是像我一样,在一直走着弯路,如果想成为一个架构师,就必须走正确的路,否则离目标越来越远,正在辛苦工作的程序员们,你们有没有下面几种感觉? 一. 我的工作就是按时完成领导交给我的任务,至于代码写的怎样,知道有改进空间,但没时间去改进,关键是领导也不给时间啊. 二. 我发现我的水平总是跟不上技术的进步,有太多想学的东西要学,Jquery用的人最近比较多啊,听说最近MVC比较火,还有LINQ,听说微软又有Sil