Don’t put view != null checks in your Presenters
passsy
23614

Actually, I solved this problem by dynamic proxy. This works well and elegant.

I can do that in my AbsPresenter like this:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;

/**
* Created by Jean on 17/3/10.
* abstract presenter, attach presenter and view
*/

public class AbsPresenter<View extends IView> implements IPresenter {

private View mView;
private Class<? extends IView> mViewClass;

public AbsPresenter(@NonNull View iView) {
this.mView = iView;
this.mViewClass = iView.getClass();
if (this.mViewClass.getInterfaces().length == 0) {
throw new IllegalArgumentException("iView must implement IView interface");
}
}

public void detach() {
this.mView = null;
}

public @NonNull View getView() {
if (mView == null) {
return ViewProxy.newInstance(mViewClass);
}
return mView;
}

private static final class ViewProxy implements InvocationHandler {

public static <View> View newInstance(Class<? extends IView> clazz) {
return (View) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new ViewProxy());
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Type type = method.getReturnType();
if (type == boolean.class) {
return false;
} else if (type == int.class) {
return 0;
} else if (type == short.class) {
return (short)0;
} else if(type == char.class) {
return (char)0;
} else if (type == byte.class) {
return (byte)0;
} else if(type == long.class) {
return 0L;
} else if (type == float.class) {
return 0f;
} else if (type == double.class) {
return 0D;
} else {
return null;
}
}
}
...
}