经过了漫长时间,终于又开始更新了。今天给大家介绍下我用的MVP框架,这套框架与其他的大多MVP框架一样使用了Dagger+Retrofit+RxJava来写的。那么我的框架又做了哪些东西才对得起文章的标题呢?先给大家看看我这套框架的Presenter与View。
presenter
public class MainPresenter extends BaseAbstractPresenter implements MainContract.Presenter {
@Inject
protected MainPresenter(DataRepository dataRepository, MainContract.View view) {
super(dataRepository, view);
}
}
view
public class MainFragment extends BaseFragment implements MainContract.View {
@NonNull
public static MainFragment newInstance() {
return new MainFragment();
}
@Nullable
@Override
public View bindView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main_frag, container, false);
return view;
}
}
这套框架是Activity
作为Fragment
的容器,真正的View
是Fragment
。Activity
的代码是基本不变的,变的只是类名。
presenter
是不是除了一个加了@Inject
注解的构造方法什么都没有了,在fragment
中也没有看到与presenter的绑定。仔细看看presenter
是不是比其他的MVP架构多继承了一个BaseAbstractPresenter
,还是泛型类,再看fragment
也是继承了BaseFragment
,它也是一个泛型类。那么我们就看看BaseAbstractPresenter
与BaseFragment
到底做了什么事情。
BaseAbstractPresenter
public abstract class BaseAbstractPresenter, P extends BasePresenter> implements BasePresenter {
protected DataRepository mDataRepository;
protected T mView;
protected BaseAbstractPresenter(DataRepository dataRepository, T view) {
mDataRepository = dataRepository;
mView = view;
}
@Inject
@Override
public void setupPresenterToView() {
// noinspection unchecked
mView.setPresenter((P) this);
}
}
BaseFragment
public abstract class BaseFragment, P extends BasePresenter> extends Fragment implements BaseView {
protected BaseAbstractPresenter mBaseAbstractPresenter;
protected P mPresenter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
...
return bindView(inflater, container, savedInstanceState);
}
...
@Nullable
public View bindView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return null;
}
@SuppressWarnings("unchecked")
@Override
public void setPresenter(BasePresenter presenter) {
mBaseAbstractPresenter = (BaseAbstractPresenter) presenter;
mPresenter = (P) presenter;
}
}
可以看到BaseAbstractPresenter
与BaseFragment
做了绑定的工作,这样我们就不用每个Presenter
与View
中都去做绑定工作了。
既然对Presenter
与View
都做了优化,那么网络请求这块怎么可能不做优化呢。
public class MainDataSourceImpl extends BaseDataSourceImpl implements MainDataSource {
public MainDataSourceImpl(Context context) {
super(context);
}
@Override
public void request(Callback callback) {
Observable observable = RetrofitFactory.getInstance().request();
HttpUtil.callbackString(observable, callback);
}
@Override
public void request(String id, Callback callback) {
Observable> observable = RetrofitFactory.getInstance().request(id);
HttpUtil.callbackResult(observable, callback);
}
}
HttpUtil
做了observable
的后续处理。申明一点:返回的数据是resultful格式的,其他的数据格式没有做处理。虽然是大多数公司都是返回数据都是resultful格式的,但就我知道的有好几家公司的数据格式不是resultful格式的,因此说明一下。
好了,我们看看HttpUtil
做了什么事儿吧。
public class HttpUtil {
public static Disposable mDisposable;
public static CompositeDisposable mCompositeDisposable;
public static void callbackString(@NonNull Observable observable, @NonNull Callback callback) {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
mCompositeDisposable.add(d);
}
@Override
public void onNext(Data data) {
if (data.getCode() == 1000) {
callback.onSuccess(data.getMessage());
} else {
callback.onFailure(data.getMessage());
}
}
@Override
public void onError(Throwable e) {
if (e.getMessage().contains("UnknownHostException")
|| e.getMessage().contains("Unable to resolve host")
|| e.getMessage().contains("No address associated with hostname")
|| e.getMessage().contains("Failed to connect to")) {
callback.onFailure("网络连接已断开");
} else if (e.getMessage().contains("403")) {
callback.onFailure("登录超时,请重新登录");
} else if (e.getMessage().contains("timed out") || e.getMessage().contains("Timedout")
|| e.getMessage().contains("timedout") || e.getMessage().contains("Timed out")) {
callback.onFailure("网络连接超时");
} else {
callback.onFailure(e.getMessage());
}
}
@Override
public void onComplete() {
}
});
}
public static void callbackResult(@NonNull Observable> observable, @NonNull Callback callback) {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer>() {
@Override
public void onSubscribe(Disposable d) {
mCompositeDisposable.add(d);
}
@Override
public void onNext(Data data) {
if (data.getCode() == 1000) {
if (data.getResult() instanceof List) {
if (data.getResult() == null || ((List) data.getResult()).size() == 0) {
callback.onFailure("暂无数据");
} else {
callback.onSuccess(data.getResult());
}
} else {
callback.onSuccess(data.getResult());
}
} else {
callback.onFailure(data.getMessage());
}
}
@Override
public void onError(Throwable e) {
if (e.getMessage().contains("UnknownHostException")
|| e.getMessage().contains("Unable to resolve host")
|| e.getMessage().contains("No address associated with hostname")
|| e.getMessage().contains("Failed to connect to")) {
callback.onFailure("网络连接已断开");
} else if (e.getMessage().contains("403")) {
callback.onFailure("登录超时,请重新登录");
} else if (e.getMessage().contains("timed out")) {
callback.onFailure("网络连接超时");
} else if (e.getMessage().contains("empty String") || e.getMessage().contains("Invalid double:")) {
callback.onFailure("暂无数据");
} else {
callback.onFailure(e.getMessage());
}
}
@Override
public void onComplete() {
}
});
}
public static void clear() {
if (mDisposable != null) {
mDisposable.dispose();
}
if (mCompositeDisposable != null) {
mCompositeDisposable.dispose();
}
}
}
Callback
public interface Callback {
/**
* request success
*
* @param t response {@link T}
*/
void onSuccess(T t);
/**
* request failure
*
* @param message failure message
*/
void onFailure(String message);
}
Data
public class Data {
private int code = 0;
private String message;
private T result;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getResult() {
return result;
}
public void setResult(T result) {
this.result = result;
}
}
这就是全部内容了。框架完整代码上传到了github
,有需要的可以去看看。
框架github:DaggerMVPDemo
如果觉得这篇文章对你有帮助,希望各位能够点一个关注或者喜欢
关于我:
* github : chengHeaven
* : 月色丶 Heaven
* 邮箱: [email protected] / [email protected]