打造万能FragmentInterface(Fragment和Activity通信完美解决,通往架构师之路)

 最近一直在看Activity和Fragment的通信,看了很多资料,也看了些学习视频,收货良多,下面把我学到的交给大家。

       相信我们做的所有项目,都会用到Fragment,所以说到Fragment和Activity通信,肯定每个开发者都会遇到。首先,让我们来做Fragment和Activity的通信数据交互,我们首先会想到用什么,博主我首先想到的用EventBus,因为博主没学习之前经常用EventBus来传递数据,博主感觉确实方便啊,每次注册一下,post一下,就传过去了,但是不得不说,EventBus还是有缺点的:

1、EventBus用的反射机制,性能上会大大折扣,效率低  2、时间长了,我们很难找到是谁发过来的事件,维护很难维护   3、数据无法返回,单向传递。 看到了这些缺点,大家应该要忍痛割舍掉EventBus。

还有人说,可以用广播啊,确实,博主当年也用过广播,当时也没想太多,广播的缺陷很大:

1、性能很差,有延迟  2、一个发生,多个接收  3、传播数据有限  4、代码沉余

还有一个可以用Handler,Handler的缺点我就不多说了,耦合、容易内存泄露等等

最后,我们来说说接口,用接口的话简单、高效、方便、解耦合,好,下面我们就来慢慢打造万能Interface


首先想想,一个接口由什么组成,如下图(画图不好,请见谅)


  我们首先来定义名称(用抽象类是为了继承它以后,可以直接重载抽象方法,调用super)

public abstract class Function {
    public String functionName;//名称
    public Function(String functionName) {
        this.functionName=functionName;
    }
}
然后根据参数和返回值组合,有四种:

1、无参数无返回值

2、有参数有返回值

3、有参数无返回值

4、无参数有返回值

知道了这四种,我们就来定义:

一、无参数无返回值(最简单,直接上代码)

public abstract class FunctionNoParamNoResult extends Function {

    public FunctionNoParamNoResult(String functionName) {
        super(functionName);
    }

    protected abstract void function();
}

二、有参数有返回值

public abstract class FunctionWithParamWithResult extends Function {
    public FunctionWithParamWithResult(String functionName) {
        super(functionName);
    }

    protected abstract Result function(Param param);
}
三、有参数无返回值

public abstract class FunctionWithParamNoResult extends Function {

    public FunctionWithParamNoResult(String functionName) {
        super(functionName);
    }

    protected abstract void function(Param param);
}
四、无参数有返回值
public abstract class FunctionNoParamWithResult extends Function {

    public FunctionNoParamWithResult(String functionName) {
        super(functionName);
    }

    protected  abstract Result function();
}


好,下面重点来了,我们要有一个统一的Manager来管理这些类,统一走Manager调用

private static FunctionManager functionManager;

    public FunctionManager() {
        mFunctionNoParamNoResult=new HashMap<>();
        mFunctionWithParamWithResult=new HashMap<>();
        mFunctionWithParamNoResult=new HashMap<>();
        mFunctionNoParamWithResult=new HashMap<>();
    }

    public static FunctionManager getInstance(){
        if(functionManager==null){
            functionManager=new FunctionManager();
        }
        return functionManager;
    }


    private static HashMap mFunctionNoParamNoResult;
    private static HashMap mFunctionWithParamWithResult;
    private static HashMap mFunctionWithParamNoResult;
    private static HashMap mFunctionNoParamWithResult;

上面用了单例模式。然后用HashMap来存接口类,key就是我们的functionName。然后我们以无参数无返回值为例,先添加一个类:

 /**
     * 添加无参数无返回值
     * @param function
     * @return
     */
    public FunctionManager addFunction(FunctionNoParamNoResult function){
        if(mFunctionNoParamNoResult!=null){
            mFunctionNoParamNoResult.put(function.functionName,function);
        }
        return this;
    }


这里可以看到,key是functionName,好了,添加进去以后,我们开始调用:

 /**
     * 执行没参数没返回值的
     * @param key
     */
    public void invokeFunction(String key){
        if(TextUtils.isEmpty(key)){
            return;
        }
        if(mFunctionNoParamNoResult!=null){
            FunctionNoParamNoResult functionNoParamNoResult=mFunctionNoParamNoResult.get(key);
            if(functionNoParamNoResult!=null){
                functionNoParamNoResult.function();
            }else {
                try {
                    throw new FunctionException("function not found");
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }
        }
    }
这样,一个无参数无返回值的方法就封装好了,现在我们来看看怎么在Activity和Fragment直接调用,达到通信数据传输。

一个Activity一般都是对多个Fragment,所以我们要创建BaseFragment,在Activity中写执行方法

/**
     * 执行方法
     */
    public void toImplementsInterface(String tag){
        BaseFrg baseFrg= (BaseFrg) manager.findFragmentByTag(tag);
        FunctionManager functionManager=FunctionManager.getInstance();
        baseFrg.setFunctionManager(functionManager.addFunction(new FunctionNoParamNoResult(Fragment1.INTERFACE) {
            @Override
            protected void function() {
                Toast.makeText(getApplicationContext(),"我执行了没有参数没有返回值的方法",Toast.LENGTH_SHORT).show();
            }
        }));
    }
manager是FragmentManager,tag是我们在添加Activivty的时候的Fragment唯一标示,Fragment1.INTERFACE就是传入的我们自己定义的名称,一定要是唯一的,Activity和Fragment唯一的耦合也只有这个名称,BaseFragment代码:

public class BaseFrg extends Fragment{

    public FunctionManager functionManager;
    private MainActivity mainActivity;
    public void setFunctionManager(FunctionManager functionManager){
        this.functionManager=functionManager;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if(context instanceof MainActivity){
            mainActivity= (MainActivity) context;
            mainActivity.toImplementsInterface(getTag());
        }
    }
}

这个代码很清晰,我不多解释,在onAttach方法里面添加,好了,我们现在只剩下调用了,当然,要去Fragment里面,上代码:

public class Fragment1 extends BaseFrg{
    public static final String TAG=Fragment1.class.getName();
    //无参数接口名称
    public static final String INTERFACE=Fragment1.class.getName()+"NPNR";
    private TextView tv;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment1,null);
        tv= (TextView) view.findViewById(R.id.tvFrg);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                functionManager.invokeFunction(INTERFACE);
            }
        });
    }
}
只在点击事件里面调用了一句代码,我的MainActivity里面就收到了消息,是不是很简单,其它Fragment再发消息怎么弄呢,看下面:
 /**
     * 执行方法
     */
    public void toImplementsInterface(String tag){
        BaseFrg baseFrg= (BaseFrg) manager.findFragmentByTag(tag);
        FunctionManager functionManager=FunctionManager.getInstance();
        baseFrg.setFunctionManager(functionManager.addFunction(new FunctionNoParamNoResult(Fragment1.INTERFACE) {
            @Override
            protected void function() {
                Toast.makeText(getApplicationContext(),"我执行了没有参数没有返回值的方法",Toast.LENGTH_SHORT).show();
            }
        }) .addFunction(new FunctionWithParamWithResult(Fragment2.INTERFACE_WITHPARAM_WITHRESULT) {
            @Override
            protected Object function(Object o) {
                Toast.makeText(getApplicationContext(),"我执行了有参数有返回值的方法:"+o.toString(),Toast.LENGTH_SHORT).show();

                return "执行好了,可以了";
            }
        }));
    }

没错,只需要再add一下,这个是既有参数又有返回值的

 /**
     * 有参数有返回值
     * @param key
     * @param param
     * @param result
     * @param 
     * @param 
     * @return
     */
    public Result invokeFunction(String key,Param param,Class result){
        if(TextUtils.isEmpty(key)){
            return null;
        }
        if(mFunctionWithParamWithResult!=null){
            FunctionWithParamWithResult f=mFunctionWithParamWithResult.get(key);
            if(f!=null){
                if(result==null){
                    return (Result) f.function(param);
                }else {
                    return result.cast(f.function(param));
                }

            }else {
                try {
                    throw new FunctionException("function not found");
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }


public class Fragment2 extends BaseFrg{
    public static final String TAG=Fragment2.class.getName();

    public static final String INTERFACE_WITHPARAM_WITHRESULT=Fragment2.class.getName()+"wpwr";

    private TextView tv;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment2,null);
        tv= (TextView) view.findViewById(R.id.tvFrg);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                functionManager.invokeFunction(INTERFACE_WITHPARAM_WITHRESULT,"大家好,我是文武编程师",String.class);
            }
        });
    }
}

好了,这是我的经验,也是我今天一行一行敲出来的,大家赶紧试试,希望能和大家一起学习了

package com.sto.myfrginterface.struct;

import android.text.TextUtils;

import java.util.HashMap;

/**
 * 作者:wb on 2017-08-24 10:32
 * 邮箱:[email protected]
 * 功能:总的manager管理
 */

public class FunctionManager {

    private static FunctionManager functionManager;

    public FunctionManager() {
        mFunctionNoParamNoResult=new HashMap<>();
        mFunctionWithParamWithResult=new HashMap<>();
        mFunctionWithParamNoResult=new HashMap<>();
        mFunctionNoParamWithResult=new HashMap<>();
    }

    public static FunctionManager getInstance(){
        if(functionManager==null){
            functionManager=new FunctionManager();
        }
        return functionManager;
    }


    private static HashMap mFunctionNoParamNoResult;
    private static HashMap mFunctionWithParamWithResult;
    private static HashMap mFunctionWithParamNoResult;
    private static HashMap mFunctionNoParamWithResult;

    /**
     * 添加无参数无返回值
     * @param function
     * @return
     */
    public FunctionManager addFunction(FunctionNoParamNoResult function){
        if(mFunctionNoParamNoResult!=null){
            mFunctionNoParamNoResult.put(function.functionName,function);
        }
        return this;
    }

    /**
     * 添加有参数有返回值
     * @param function
     * @return
     */
    public FunctionManager addFunction(FunctionWithParamWithResult function){
        if(mFunctionWithParamWithResult!=null){
            mFunctionWithParamWithResult.put(function.functionName,function);
        }
        return this;
    }

    /**
     * 添加有参数无返回值
     * @param function
     * @return
     */
    public FunctionManager addFunction(FunctionWithParamNoResult function){
        if(mFunctionWithParamNoResult!=null){
            mFunctionWithParamNoResult.put(function.functionName,function);
        }
        return this;
    }

    /**
     * 添加吴参数有返回值
     * @param function
     * @return
     */
    public FunctionManager addFunction(FunctionNoParamWithResult function){
        if(mFunctionNoParamWithResult!=null){
            mFunctionNoParamWithResult.put(function.functionName,function);
        }
        return this;
    }

    /**
     * 执行没参数没返回值的
     * @param key
     */
    public void invokeFunction(String key){
        if(TextUtils.isEmpty(key)){
            return;
        }
        if(mFunctionNoParamNoResult!=null){
            FunctionNoParamNoResult functionNoParamNoResult=mFunctionNoParamNoResult.get(key);
            if(functionNoParamNoResult!=null){
                functionNoParamNoResult.function();
            }else {
                try {
                    throw new FunctionException("function not found");
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 有参数有返回值
     * @param key
     * @param param
     * @param result
     * @param 
     * @param 
     * @return
     */
    public Result invokeFunction(String key,Param param,Class result){
        if(TextUtils.isEmpty(key)){
            return null;
        }
        if(mFunctionWithParamWithResult!=null){
            FunctionWithParamWithResult f=mFunctionWithParamWithResult.get(key);
            if(f!=null){
                if(result==null){
                    return (Result) f.function(param);
                }else {
                    return result.cast(f.function(param));
                }

            }else {
                try {
                    throw new FunctionException("function not found");
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

}



你可能感兴趣的:(打造万能FragmentInterface(Fragment和Activity通信完美解决,通往架构师之路))