Github地址
https://github.com/jasonwang18/pluginMVPM
MVPM Model-View-Presenter-MethodCenter
相较于MVP框架多一个M,这个M就是MethodCenter,它是所有plugin的presenter的方法集合,集中管理所有同步和异步的方法,这个框架比较适用于有许多小功能的模块的集合
比如unity工程Android jar包,也可用于多presenter的MVP工程,可以按需将需要的presenter实例化,创建出不同的MethodCenter子类。
public class MethodCenter extends BaseMethodCenter {
.....
/**
* 调用异步方法
* @param method
* @param arg
*/
protected void callASynMethod(String method, String[] arg){
super.callASynMethod(method, arg);
}
/**
* @param method 方法名
* @param arg 可变参数
* @return bool
*/
public boolean callMethodBoolean(String method, String[] arg){
BaseLog.i( "callMethodBoolean");
SynResult<Boolean> result = (SynResult<Boolean>)callSynMethod(method, arg);
if(result == null ){
return false;
}
return result.value();
}
/**
* @param method
* @param arg
* @return int
*/
public int callMethodInt(String method, String[] arg){
SynResult<Integer> result = (SynResult<Integer>) callSynMethod(method, arg);
if(result == null){
return -1;
}
return result.value();
}
/**
* @param method
* @param arg
* @return String
*/
public String callMethodString(String method, String[] arg){
SynResult<String> result = (SynResult<String>) callSynMethod(method, arg);
if(result == null){
return "";
}
return result.value();
}
/**
* @param method
* @param arg
*
*/
public String callMethodVoid(String method, String[] arg){
if(isASynMethod(method)){
callASynMethod(method, arg);
}
else callSynMethod(method, arg);
}
}
View层通过MethodCenter实例,调用Presenter的方法
@Presenter(value = {"TestPresenter"})//通过注解动态plugin
public class ViewMethodCenter extends MethodCenter {
private static ViewMethodCenter instance ;
public ViewMethodCenter(){
super(SampleApplication.context());
}
public static ViewMethodCenter getInstance(){
if (instance == null) {
synchronized (ViewMethodCenter.class){
if (instance == null) {
instance = new ViewMethodCenter() ;
}
}
}
return instance ;
}
}
MethodCenter通过注解@Presenter 或者 @Instance将Presenter实例化,并保存在map中
public void register(BasePresenter basePresenter) {
if(this.mChannels == null) {
this.mChannels = new SparseArray();
}
if(this.mChannels.get(basePresenter.getId()) != null) {
BaseLog.e("This Controller has already registerd");
} else {
AsyncChannel channel = new AsyncChannel();
channel.connect(this.mContext, this.mHandler, basePresenter.getHandler());
basePresenter.setChannel(channel);
this.mChannels.put(basePresenter.getId(), channel);
}
}
MethodCenter与Presenter沟通的桥梁是ASynChannel,这个类也是Wifi系统的桥梁,通过将两个Handler connect,可以将消息发送到另一边,双向通信。Presenter通过register方法将自己注册到MethodCenter,并建立ASynChannel桥梁。
public abstract class BasePresenter<Model extends IContract.IModel>{
......
protected void initASynMethod(){
mASynMethodMap = MethodHelper.initASynMethod(this);
}
protected abstract Model createModel();
protected Handler createHandler(Looper looper){
return new ControllerHandler(looper){
@Override
public void handleMessage(Message msg) {
for(String key:mASynMethodMap.keySet()){
if (mASynMethodMap.get(key) == msg.what) {
ExecutorHelper.getInstance().execute(new ASynRunnable(msg, key));
}
}
}
};
}
protected abstract boolean onHandleResult(Object result);
protected void returnMethodResult(Message msg, Object result, boolean isHandled){
if (!isHandled) {
getChannel().replyToMessage(
msg,
BaseConstant.MESSAGE_WHAT_CALLBACK,
msg.what,
0,
result);
}
}
public Handler getHandler() {
return mHandler;
}
public class ControllerHandler extends Handler{
public ControllerHandler(Looper looper){
super(looper);
}
}
public int getId(){
return hashCode();
}
class ASynRunnable implements Runnable{
private Message srcMsg;
private String methodName;
public ASynRunnable(Message srcMsg, String methodName){
this.srcMsg = srcMsg;
this.methodName = methodName;
}
@Override
public void run() {
Object result = MethodHelper.callASynMethod(BasePresenter.this, methodName, (Object[]) srcMsg.obj);
if(result != null){// have return
returnMethodResult(srcMsg, result, onHandleResult(result));
}
}
}
BasePresenter 处理异步方法时,用线程池装载一个Runnable执行,结果returnMethodResult返回,BasePresenter可以利用onHandleResult方法确定要不要对返回值进行处理,return true,则结果不返回methodCenter,否则返回结果。
BasePresenter通过泛型绑定BaseModel的实现类,利用桥接模式,让BasePresenter和BaseModel的实现分别进化,再用Contract接口一对一绑定Presenter和Model
public interface TestContract1 {
interface ITestPresenter1 extends IContract.IPresenter{
List<String> aSynPresenterMethod();
boolean synPresenterMethod();
}
interface ITestModel1 extends IContract.IModel{
List<String> aSynModelMethod();
boolean synModelMethod();
}
}
public class TestPresenter extends BasePresenter<TestModel1> implements TestContract1.ITestPresenter1{
public TestPresenter(BaseMethodCenter methodCenter) {
super(methodCenter);
}
private static TestPresenter instance ;
public static TestPresenter getInstance(BaseMethodCenter methodCenter){
if (instance == null) {
synchronized (TestPresenter.class){
if (instance == null) {
instance = new TestPresenter(methodCenter) ;
}
}
}
return instance ;
}
@Override
protected TestModel1 createModel() {
return new TestModel1();
}
@Override
protected boolean onHandleResult(Object result) {
return false;
}
@MessageWhat(Constant.MessageWhat.MESSAGE_WHAT_PRESENTER_ASYN_METHOD)
@Override
public List<String> aSynPresenterMethod() {
BaseLog.i("aSynPresenterMethod");
return getModel().aSynModelMethod();
}
@Override
public boolean synPresenterMethod() {
BaseLog.i("synPresenterMethod");
return getModel().synModelMethod();
}
}
通过Contract协议接口,将Presenter和Model一一对应,Presenter通过泛型将Model引入
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
Button test1 = (Button) findViewById(R.id.test1);
test1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean result = viewMethodCenter.callSynMethodBoolean(Constant.Method.METHOD_TEST_PRESENTER_SYN_METHOD, null);
BaseLog.i("call synmethod result:"+result);
}
});
Button test2 = (Button) findViewById(R.id.test2);
test2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewMethodCenter.callASynMethod(Constant.Method.METHOD_TEST_PRESENTER_ASYN_METHOD, null);
}
});
}
private MethodCenter viewMethodCenter;
protected void init() {
ViewMethodCenter.setPresenterPath(Constant.PRESENTER_PATH);
viewMethodCenter = new ViewMethodCenter();
viewMethodCenter.setCallback(new BaseMethodCenter.Callback() {
@Override
public void onCallback(Message msg) {
BaseLog.i("onCallback arg1:"+msg.arg1+" obj:"+msg.obj);
if(msg.arg1 == Constant.MessageWhat.MESSAGE_WHAT_PRESENTER_ASYN_METHOD){
List<String> result = (List<String>) msg.obj;
BaseLog.i("result size:"+result);
for(String s:result){
BaseLog.i("result:"+s);
}
}
}
});
}
}
测试Activity,相当于View层,P层通过callback接口回调View层
04-07 14:28:03.901 17265-17265/com.pluginmvpm.sample I/MVPM: callSynMethodBoolean
04-07 14:28:03.904 17265-17265/com.pluginmvpm.sample I/MVPM: synPresenterMethod
04-07 14:28:03.904 17265-17265/com.pluginmvpm.sample I/MVPM: synModelMethod
04-07 14:28:03.904 17265-17265/com.pluginmvpm.sample I/MVPM: false
04-07 14:28:03.904 17265-17265/com.pluginmvpm.sample I/MVPM: call synmethod result:false
同步方法测试结果
04-07 14:28:05.809 17265-17265/com.pluginmvpm.sample I/MVPM: callASynMethod
04-07 14:28:05.810 17265-17702/com.pluginmvpm.sample I/MVPM: handleMessage
04-07 14:28:05.810 17265-17702/com.pluginmvpm.sample I/MVPM: aSynPresenterMethod
04-07 14:28:05.810 17265-17702/com.pluginmvpm.sample I/MVPM: aSynModelMethod
04-07 14:28:05.810 17265-17702/com.pluginmvpm.sample I/MVPM: onCallback arg1:1119 obj:[1, 2, 3, 4]
04-07 14:28:05.810 17265-17702/com.pluginmvpm.sample I/MVPM: result size:[1, 2, 3, 4]
异步方法测试结果
还有一点必须要注意的是,方法名必须和Message What一一对应,如果存在多工程,注意Message What不要相同