最近一直在看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();
}
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 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());
}
}
}
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;
}
}