目的
在Android开发阶段,组件之间的通信是不可避免的,组件之间的通信方式也会有很多,它们各有优劣,今天我们主要了解的是,一种万能接口的方式来实现,一个简单而优雅的通讯方式,用少量的代码,来完成组件间的通信解耦。
常用的组件间的通讯方式
其中最常用就前三种,其中:
- Intent 只能界面逐级传输
- Handler 存在内存泄漏, 在activity被销毁时,由于队列还有消息,Handler还存在,造成存在泄漏。
- interface 书写反锁,耦合性强,并且不能切换线程
当然也有一些常用的三方的框架,如EventBus,XBus等等,但是一个优秀的第三方框架百分之八十的功能我们都不会使用,所以当这些都没有的时候,我们如何更加优雅的实现大量组件间的通信了?
“数据源” -- 思路
核心思想
- 通过数据源或方法栈中转,组件只管接受或发送
- 将方法进行封装
- 将方法提取出来进行管理
具体实践
1.方法的封装
四种类型:
方法封装的父类
package com.fly.newstart.neinterface;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 创建时间 : 2019/4/23
* 描述: 方法封装管理的父类
*/
public class Function {
//方法名称
public String functionName;
public Function(String functionName) {
this.functionName = functionName;
}
}
无参数无返回值类型方法
package com.fly.newstart.neinterface;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 创建时间 : 2019/4/23
* 描述: 无参数 无返回 类型 方法
*/
public abstract class FunctionNoParamNoResult extends Function{
public FunctionNoParamNoResult(String functionName) {
super(functionName);
}
public abstract void function();
}
无参数有返回值类型方法
package com.fly.newstart.neinterface;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 创建时间 : 2019/4/23
* 描述: 无参数 有返回值 类型 方法
*/
public abstract class FunctionNoParamHasResult<T> extends Function{
public FunctionNoParamHasResult(String functionName) {
super(functionName);
}
public abstract T function();
}
有参数无返回值类型方法
package com.fly.newstart.neinterface;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 创建时间 : 2019/4/23
* 描述: 有参数 无返回值 类型 方法
*/
public abstract class FunctionHasParamNoResult<P> extends Function{
public FunctionHasParamNoResult(String functionName) {
super(functionName);
}
public abstract void function(P p);
}
有参数有返回值类型方法
package com.fly.newstart.neinterface;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 创建时间 : 2019/4/23
* 描述: 有参数 有返回值 类型 方法
*/
public abstract class FunctionHasParamHasResult<T,P> extends Function{
public FunctionHasParamHasResult(String functionName) {
super(functionName);
}
public abstract T function(P p);
}
2.方法管理类构建
方法管理类
package com.fly.newstart.neinterface;
import android.text.TextUtils;
import com.fly.newstart.utils.LogUtil;
import java.util.HashMap;
import java.util.Map;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 创建时间 : 2019/4/23
* 描述: 方法管理类
*/
public class FunctionManager {
private static FunctionManager instance;
private Map<String, FunctionNoParamNoResult> mFunctionNoParamNoResultMap;
private Map<String, FunctionNoParamHasResult> mFunctionNoParamHasResultMap;
private Map<String, FunctionHasParamNoResult> mFunctionHasParamNoResultMap;
private Map<String, FunctionHasParamHasResult> mFunctionHasParamHasResultMap;
public FunctionManager() {
mFunctionNoParamNoResultMap = new HashMap<>();
mFunctionNoParamHasResultMap = new HashMap<>();
mFunctionHasParamNoResultMap = new HashMap<>();
mFunctionHasParamHasResultMap = new HashMap<>();
}
public static FunctionManager getInstance() {
if (instance == null) {
instance = new FunctionManager();
}
return instance;
}
/**
* 添加无参数无返回值方法
*
* @param function
*/
public void addFunction(FunctionNoParamNoResult function) {
if (function != null) {
this.mFunctionNoParamNoResultMap.put(function.functionName, function);
} else LogUtil.print("FunctionNoParamNoResult is Null");
}
/**
* 调用无参数无返回值方法
*
* @param functionName
*/
public void invokeFunction(String functionName) {
if (TextUtils.isEmpty(functionName)) {
return;
}
if (mFunctionNoParamNoResultMap != null) {
FunctionNoParamNoResult function = mFunctionNoParamNoResultMap.get(functionName);
if (function != null) {
function.function();
} else LogUtil.print("FunctionNoParamNoResult not created");
}
}
/**
* 添加无参数有返回值方法
*
* @param function
*/
public void addFunction(FunctionNoParamHasResult function) {
if (function != null) {
this.mFunctionNoParamHasResultMap.put(function.functionName, function);
} else LogUtil.print("FunctionNoParamNoResult is Null");
}
/**
* 调用无参数有返回值方法
*
* @param functionName
* @param t 返回泛型
* @param <T> 返回泛型
* @return
*/
public <T> T invokeFunction(String functionName, Class<T> t) {
if (!TextUtils.isEmpty(functionName)) {
if (mFunctionNoParamHasResultMap != null) {
FunctionNoParamHasResult function = mFunctionNoParamHasResultMap.get(functionName);
if (function != null) {
if (t != null) {
return t.cast(function.function());
} else LogUtil.print("Class T is null");
} else LogUtil.print("FunctionNoParamHasResult not created");
}
}
return null;
}
/**
* 添加有参数无返回值方法
*
* @param function
*/
public void addFunction(FunctionHasParamNoResult function) {
if (function != null) {
this.mFunctionHasParamNoResultMap.put(function.functionName, function);
} else LogUtil.print("FunctionNoParamNoResult is Null");
}
/**
* 调用有参数无返回值方法
*
* @param functionName
* @param param
* @param <P>
*/
public <P> void invokeFunction(String functionName, P param) {
if (TextUtils.isEmpty(functionName)) {
return;
}
if (mFunctionHasParamNoResultMap != null) {
FunctionHasParamNoResult function = mFunctionHasParamNoResultMap.get(functionName);
if (function != null) {
function.function(param);
} else LogUtil.print("FunctionNoParamHasResult not created");
}
}
/**
* 添加有参数有返回值方法
*
* @param function
*/
public void addFunction(FunctionHasParamHasResult function) {
if (function != null) {
this.mFunctionHasParamHasResultMap.put(function.functionName, function);
} else LogUtil.print("FunctionNoParamNoResult is Null");
}
/**
* 调用有参数有返回值方法
*
* @param functionName
* @param param
* @param t
* @param <T>
* @param <P>
* @return
*/
public <T, P> T invokeFunction(String functionName, P param, Class<T> t) {
if (!TextUtils.isEmpty(functionName)) {
if (mFunctionHasParamHasResultMap != null) {
FunctionHasParamHasResult function = mFunctionHasParamHasResultMap.get(functionName);
if (function != null) {
if (t != null) {
return t.cast(function.function(param));
} else LogUtil.print("Class T is null");
} else LogUtil.print("FunctionNoParamHasResult not created");
}
}
return null;
}
public void removeFunctionNoParamNoResult(String functionName) {
mFunctionNoParamNoResultMap.remove(functionName);
}
public void removeFunctionNoParamHasResult(String functionName) {
mFunctionNoParamHasResultMap.remove(functionName);
}
public void removeFunctionHasParamNoResult(String functionName) {
mFunctionHasParamNoResultMap.remove(functionName);
}
public void removeFunctionHasParamHasResult(String functionName) {
mFunctionHasParamHasResultMap.remove(functionName);
}
public void removeAll(String functionName) {
mFunctionNoParamNoResultMap.remove(functionName);
mFunctionNoParamHasResultMap.remove(functionName);
mFunctionHasParamNoResultMap.remove(functionName);
mFunctionHasParamHasResultMap.remove(functionName);
}
public void removeAll() {
mFunctionNoParamNoResultMap.clear();
mFunctionNoParamHasResultMap.clear();
mFunctionHasParamNoResultMap.clear();
mFunctionHasParamHasResultMap.clear();
}
}
3.组件通信测试
组件A
代码
package com.fly.newstart.neinterface.text;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.fly.newstart.R;
import com.fly.newstart.common.base.BaseActivity;
import com.fly.newstart.neinterface.FunctionHasParamHasResult;
import com.fly.newstart.neinterface.FunctionHasParamNoResult;
import com.fly.newstart.neinterface.FunctionManager;
import com.fly.newstart.neinterface.FunctionNoParamHasResult;
import com.fly.newstart.neinterface.FunctionNoParamNoResult;
public class AActivity extends BaseActivity {
public static final String FUNCTION_1 = "functon01";
public static final String FUNCTION_2 = "functon02";
public static final String FUNCTION_3 = "functon03";
public static final String FUNCTION_4 = "functon04";
private TextView mTvShow;
private Button mBtnStartB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);
mTvShow = findViewById(R.id.tvShow);
mBtnStartB = findViewById(R.id.btnStartB);
mBtnStartB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AActivity.this.startActivity(new Intent(AActivity.this, BActivity.class));
}
});
//注册方法1-无参数无返回值类型方法
FunctionManager.getInstance().addFunction(new FunctionNoParamNoResult(FUNCTION_1) {
@Override
public void function() {
mTvShow.setText("调用了方法1,无参数无返回值类型方法");
}
});
FunctionManager.getInstance().addFunction(new FunctionNoParamHasResult<String>(FUNCTION_2) {
@Override
public String function() {
return "调用了方法2,无参数有返回值类型方法";
}
});
FunctionManager.getInstance().addFunction(new FunctionHasParamNoResult<String>(FUNCTION_3) {
@Override
public void function(String s) {
mTvShow.setText(s);
}
});
FunctionManager.getInstance().addFunction(new FunctionHasParamHasResult<String, String>(FUNCTION_4) {
@Override
public String function(String s) {
return s;
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
FunctionManager.getInstance().removeFunctionNoParamNoResult(FUNCTION_1);
FunctionManager.getInstance().removeFunctionNoParamHasResult(FUNCTION_2);
FunctionManager.getInstance().removeFunctionHasParamNoResult(FUNCTION_3);
FunctionManager.getInstance().removeFunctionHasParamHasResult(FUNCTION_4);
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context="com.fly.newstart.neinterface.text.AActivity">
<TextView
android:id="@+id/tvShow"
style="@style/WrapWrap"
android:textSize="@dimen/dp_16" />
<Button
android:id="@+id/btnStartB"
style="@style/WrapWrap"
android:layout_marginTop="@dimen/dp_10"
android:text="启动B组件"/>
</LinearLayout>
组件B
代码
package com.fly.newstart.neinterface.text;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.fly.newstart.R;
import com.fly.newstart.common.base.BaseActivity;
import com.fly.newstart.neinterface.FunctionManager;
public class BActivity extends BaseActivity {
private Button mBtnFuncton01;
private Button mBtnFuncton02;
private Button mBtnFuncton03;
private Button mBtnFuncton04;
private Button mBtnCloseB;
private TextView mTvShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
mBtnFuncton01 = findViewById(R.id.btnFuncton01);
mBtnFuncton02 = findViewById(R.id.btnFuncton02);
mBtnFuncton03 = findViewById(R.id.btnFuncton03);
mBtnFuncton04 = findViewById(R.id.btnFuncton04);
mBtnCloseB = findViewById(R.id.btnCloseB);
mTvShow = findViewById(R.id.tvShow);
mBtnFuncton01.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FunctionManager.getInstance().invokeFunction(AActivity.FUNCTION_1);
}
});
mBtnFuncton02.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTvShow.setText(FunctionManager.getInstance().invokeFunction(AActivity.FUNCTION_2, String.class));
}
});
mBtnFuncton03.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FunctionManager.getInstance().invokeFunction(AActivity.FUNCTION_3, "调用了方法3,有参数无返回值类型方法");
}
});
mBtnFuncton04.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTvShow.setText(FunctionManager.getInstance().invokeFunction(AActivity.FUNCTION_4, "调用了方法4,有参数有返回值类型方法", String.class));
}
});
mBtnCloseB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="@style/MatchMatch"
android:gravity="center"
android:orientation="vertical"
tools:context="com.fly.newstart.neinterface.text.BActivity">
<Button
android:id="@+id/btnFuncton01"
style="@style/WrapWrap"
android:text="调用方法1" />
<Button
android:id="@+id/btnFuncton02"
style="@style/WrapWrap"
android:text="调用方法2" />
<Button
android:id="@+id/btnFuncton03"
style="@style/WrapWrap"
android:text="调用方法3" />
<Button
android:id="@+id/btnFuncton04"
style="@style/WrapWrap"
android:text="调用方法4" />
<Button
android:id="@+id/btnCloseB"
style="@style/WrapWrap"
android:text="关闭B" />
<TextView
android:id="@+id/tvShow"
style="@style/WrapWrap" />
</LinearLayout>
小结
- 代码简洁,主要是提供一个思路,还有很多可以完善的地方
- EventBus的核心与我们当前一样:将方法提取出来管理
- 只是EventBus运用反射机制与更加完善的调用获取方式
- 我们只要是去理解整个实现的过程和思维方式