目的
在Android開(kāi)發(fā)階段侮措,組件之間的通信是不可避免的懈叹,組件之間的通信方式也會(huì)有很多,它們各有優(yōu)劣分扎,今天我們主要了解的是澄成,一種萬(wàn)能接口的方式來(lái)實(shí)現(xiàn),一個(gè)簡(jiǎn)單而優(yōu)雅的通訊方式,用少量的代碼墨状,來(lái)完成組件間的通信解耦卫漫。
常用的組件間的通訊方式
常用的組件間的通訊方式
其中最常用就前三種,其中:
- Intent 只能界面逐級(jí)傳輸
- Handler 存在內(nèi)存泄漏肾砂, 在activity被銷毀時(shí)列赎,由于隊(duì)列還有消息,Handler還存在镐确,造成存在泄漏粥谬。
- interface 書寫反鎖,耦合性強(qiáng)辫塌,并且不能切換線程
當(dāng)然也有一些常用的三方的框架,如EventBus,XBus等等派哲,但是一個(gè)優(yōu)秀的第三方框架百分之八十的功能我們都不會(huì)使用臼氨,所以當(dāng)這些都沒(méi)有的時(shí)候,我們?nèi)绾胃觾?yōu)雅的實(shí)現(xiàn)大量組件間的通信了芭届?
“數(shù)據(jù)源” -- 思路
“數(shù)據(jù)源” -- 思路
核心思想
- 通過(guò)數(shù)據(jù)源或方法棧中轉(zhuǎn)储矩,組件只管接受或發(fā)送
- 將方法進(jìn)行封裝
- 將方法提取出來(lái)進(jìn)行管理
具體實(shí)踐
1.方法的封裝
四種類型:
方法封裝的四種類型
方法封裝的父類
package com.fly.newstart.neinterface;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 創(chuàng)建時(shí)間 : 2019/4/23
* 描述: 方法封裝管理的父類
*/
public class Function {
//方法名稱
public String functionName;
public Function(String functionName) {
this.functionName = functionName;
}
}
無(wú)參數(shù)無(wú)返回值類型方法
package com.fly.newstart.neinterface;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 創(chuàng)建時(shí)間 : 2019/4/23
* 描述: 無(wú)參數(shù) 無(wú)返回 類型 方法
*/
public abstract class FunctionNoParamNoResult extends Function{
public FunctionNoParamNoResult(String functionName) {
super(functionName);
}
public abstract void function();
}
無(wú)參數(shù)有返回值類型方法
package com.fly.newstart.neinterface;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 創(chuàng)建時(shí)間 : 2019/4/23
* 描述: 無(wú)參數(shù) 有返回值 類型 方法
*/
public abstract class FunctionNoParamHasResult<T> extends Function{
public FunctionNoParamHasResult(String functionName) {
super(functionName);
}
public abstract T function();
}
有參數(shù)無(wú)返回值類型方法
package com.fly.newstart.neinterface;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 創(chuàng)建時(shí)間 : 2019/4/23
* 描述: 有參數(shù) 無(wú)返回值 類型 方法
*/
public abstract class FunctionHasParamNoResult<P> extends Function{
public FunctionHasParamNoResult(String functionName) {
super(functionName);
}
public abstract void function(P p);
}
有參數(shù)有返回值類型方法
package com.fly.newstart.neinterface;
/**
* <pre>
* .----.
* _.'__ `.
* .--(Q)(OK)---/$\
* .' @ /$$$\
* : , $$$$$
* `-..__.-' _.-\$/
* `;_: `"'
* .'"""""`.
* /, FLY ,\
* // \\
* `-._______.-'
* ___`. | .'___
* (______|______)
* </pre>
* 包 名 : com.fly.newstart.neinterface
* 作 者 : FLY
* 創(chuàng)建時(shí)間 : 2019/4/23
* 描述: 有參數(shù) 有返回值 類型 方法
*/
public abstract class FunctionHasParamHasResult<T,P> extends Function{
public FunctionHasParamHasResult(String functionName) {
super(functionName);
}
public abstract T function(P p);
}
2.方法管理類構(gòu)建
方法管理類
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
* 創(chuàng)建時(shí)間 : 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;
}
/**
* 添加無(wú)參數(shù)無(wú)返回值方法
*
* @param function
*/
public void addFunction(FunctionNoParamNoResult function) {
if (function != null) {
this.mFunctionNoParamNoResultMap.put(function.functionName, function);
} else LogUtil.print("FunctionNoParamNoResult is Null");
}
/**
* 調(diào)用無(wú)參數(shù)無(wú)返回值方法
*
* @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");
}
}
/**
* 添加無(wú)參數(shù)有返回值方法
*
* @param function
*/
public void addFunction(FunctionNoParamHasResult function) {
if (function != null) {
this.mFunctionNoParamHasResultMap.put(function.functionName, function);
} else LogUtil.print("FunctionNoParamNoResult is Null");
}
/**
* 調(diào)用無(wú)參數(shù)有返回值方法
*
* @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;
}
/**
* 添加有參數(shù)無(wú)返回值方法
*
* @param function
*/
public void addFunction(FunctionHasParamNoResult function) {
if (function != null) {
this.mFunctionHasParamNoResultMap.put(function.functionName, function);
} else LogUtil.print("FunctionNoParamNoResult is Null");
}
/**
* 調(diào)用有參數(shù)無(wú)返回值方法
*
* @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");
}
}
/**
* 添加有參數(shù)有返回值方法
*
* @param function
*/
public void addFunction(FunctionHasParamHasResult function) {
if (function != null) {
this.mFunctionHasParamHasResultMap.put(function.functionName, function);
} else LogUtil.print("FunctionNoParamNoResult is Null");
}
/**
* 調(diào)用有參數(shù)有返回值方法
*
* @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.組件通信測(cè)試
組件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));
}
});
//注冊(cè)方法1-無(wú)參數(shù)無(wú)返回值類型方法
FunctionManager.getInstance().addFunction(new FunctionNoParamNoResult(FUNCTION_1) {
@Override
public void function() {
mTvShow.setText("調(diào)用了方法1,無(wú)參數(shù)無(wú)返回值類型方法");
}
});
FunctionManager.getInstance().addFunction(new FunctionNoParamHasResult<String>(FUNCTION_2) {
@Override
public String function() {
return "調(diào)用了方法2,無(wú)參數(shù)有返回值類型方法";
}
});
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="啟動(dòng)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, "調(diào)用了方法3,有參數(shù)無(wú)返回值類型方法");
}
});
mBtnFuncton04.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTvShow.setText(FunctionManager.getInstance().invokeFunction(AActivity.FUNCTION_4, "調(diào)用了方法4,有參數(shù)有返回值類型方法", 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="調(diào)用方法1" />
<Button
android:id="@+id/btnFuncton02"
style="@style/WrapWrap"
android:text="調(diào)用方法2" />
<Button
android:id="@+id/btnFuncton03"
style="@style/WrapWrap"
android:text="調(diào)用方法3" />
<Button
android:id="@+id/btnFuncton04"
style="@style/WrapWrap"
android:text="調(diào)用方法4" />
<Button
android:id="@+id/btnCloseB"
style="@style/WrapWrap"
android:text="關(guān)閉B" />
<TextView
android:id="@+id/tvShow"
style="@style/WrapWrap" />
</LinearLayout>
小結(jié)
- 代碼簡(jiǎn)潔,主要是提供一個(gè)思路褂乍,還有很多可以完善的地方
- EventBus的核心與我們當(dāng)前一樣:將方法提取出來(lái)管理
- 只是EventBus運(yùn)用反射機(jī)制與更加完善的調(diào)用獲取方式
- 我們只要是去理解整個(gè)實(shí)現(xiàn)的過(guò)程和思維方式