本文基于Android 优雅的封装MVP模式下的Retrofit+RxJava主要讲解封装完毕后,如何使用。
https://github.com/DeMonLiu623/DeMon_MVPRR
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.DeMonLiu623:DeMon_MVPRR:v2.0.0'
}
public class App extends BaseApp {
@Override
public void onCreate() {
super.onCreate();
//如果你Application已经继承,可以如下设置
//BaseApp.setContext(getApplicationContext());
}
}
测试api,淘宝商品搜索建议:https://suggest.taobao.com/
访问http://www.bejson.com/knownjson/webInterface/可见
Retrofit单例,设置base_url,自定义一些拦截器如Token等。
public class Api {
//测试api,淘宝商品搜索建议
//访问http://www.bejson.com/knownjson/webInterface/可见
private static String base_url = "https://suggest.taobao.com/";
private volatile static Retrofit retrofit;
public static Retrofit getRetrofit() {
if (retrofit == null) {
synchronized (Api.class) {
if (retrofit == null) {
new Api();
}
}
}
return retrofit;
}
private Api() {
BaseApi baseApi = new BaseApi();
retrofit = baseApi.getRetrofit(base_url, new TokenInterceptor());
}
}
public class TokenInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response originalResponse = chain.proceed(request);
return originalResponse.newBuilder().header("assess-token", "123456").build();
}
}
根据Api服务接口,添加Retrofit Service接口。
public interface ApiService {
@POST("sug?")
Observable<TaobaoBean> getTaobao(@Body Map<String, Object> map);
@FormUrlEncoded
@POST("sug?")
Observable<TaobaoBean> getTaobao(@Field("code") String code, @Field("q") String q);
}
public class IObserver<T> extends BaseObserver<T> {
private OnRequestListener<T> listener;
public IObserver(Context context, OnRequestListener<T> listener) {
super(context);
this.listener = listener;
}
public IObserver(Context context, OnRequestListener<T> listener, boolean isShow) {
super(context, isShow);
this.listener = listener;
}
@Override
protected void onNextResult(T t) {
listener.onSucceed(t);
}
@Override
protected void onErrorResult(Throwable e) {
listener.onError(e.getMessage());
}
//加载进度框,重写可自定义
@Override
public ProgressDialog initDialog(Context context) {
ProgressDialog dialog = new ProgressDialog(context);
dialog.setTitle("数据加载中");
return dialog;
}
}
public interface OnRequestListener<T> {
void onSucceed(T t);
void onError(String s);
}
/**
* 网络请求model
*/
public class Model extends BaseModel {
private static final String TAG = "Model";
private static Model instance = new Model();
private BaseService baseService = Api.getRetrofit().create(BaseService.class);
private ApiService apiService = Api.getRetrofit().create(ApiService.class);
public static Model getInstance() {
return instance;
}
public void get(String url, OnRequestListener<String> listener) {
Observer<String> observer = new IObserver<>(mContext, listener);
addSubcription(baseService.get(url), observer);
}
public void getTaobao(Map<String, Object> maps, OnRequestListener<TaobaoBean> listener) {
Observer<TaobaoBean> observer = new IObserver<>(mContext, listener);
addSubcription(apiService.getTaobao(maps), observer);
}
public void getTaobao(String q, OnRequestListener<TaobaoBean> listener) {
Observer<TaobaoBean> observer = new IObserver<>(mContext, listener);
addSubcription(apiService.getTaobao("utf-8", q), observer);
}
public void post(String url, Map<String, Object> maps, OnRequestListener<String> listener) {
Observer<String> observer = new IObserver<>(mContext, listener);
addSubcription(baseService.post(url, maps), observer);
}
/**
* 不显示dialog
*
* @param url
* @param maps
* @param listener
*/
public void postNoDialog(String url, Map<String, Object> maps, OnRequestListener<String> listener) {
Observer<String> observer = new IObserver<>(mContext, listener, false);
addSubcription(baseService.post(url, maps), observer);
}
/**
* 文件上传
*
* @param url
* @param file
* @param name
* @param listener
*/
public void uploadFile(String url, File file, String name, OnRequestListener<String> listener) {
Observer<String> observer = new IObserver<>(mContext, listener);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", name, requestFile);
addSubcription(baseService.uploadsFile(url, filePart), observer);
}
}
根据官方建议增加Contract管理View接口和Presenter。
public interface JavaJsonContract {
interface View extends BaseView {
void result(String s);
}
abstract class Presenter extends BasePresenter<View> {
public abstract void Taobao(String q);
}
}
public class JavaJsonPresenter extends JavaJsonContract.Presenter {
@Override
public void Taobao(String q) {
Map map = new HashMap<>();
map.put("code", "utf-8");
map.put("q", q);
Model.getInstance().post("sug?", map, new OnRequestListener() {
@Override
public void onSucceed(String s) {
getView().result(s);
}
@Override
public void onError(String s) {
Log.i(TAG, "onError: " + s);
}
});
}
}
public class JavaJsonActivity extends BaseMvpActivity<JavaJsonPresenter> implements JavaJsonContract.View {
private EditText et;
private TextView tv;
@Override
protected int bindLayout() {
return R.layout.activity_json;
}
@Override
protected void initCreate() {
et = findViewById(R.id.etContent);
tv = findViewById(R.id.text);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = et.getText().toString();
if (TextUtils.isEmpty(s)) {
Toast.makeText(mContext, "输入内容不能为空!", Toast.LENGTH_SHORT).show();
return;
}
mPresenter.Taobao(s);
}
});
}
@Override
public void result(String s) {
tv.setText(s);
}
}
class KotlinBeanContract {
interface View : BaseView {
fun result(bean: TaobaoBean)
}
abstract class Presenter : BasePresenter() {
abstract fun Taobao(s: String)
}
}
class KotlinBeanPresenter : KotlinBeanContract.Presenter() {
override fun Taobao(s: String) {
Model.getInstance().getTaobao(s,object :OnRequestListener{
override fun onSucceed(t: TaobaoBean) {
mView.result(t)
}
override fun onError(s: String?) {
}
})
}
}
class KotlinBeanActivity : BaseMvpActivity(), KotlinBeanContract.View {
override fun bindLayout(): Int {
return R.layout.activity_json
}
override fun initCreate() {
btn.setOnClickListener {
val s = etContent.text.toString()
if (s.isNullOrEmpty()) {
Toast.makeText(mContext, "搜索内容不能为空", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
mPresenter.Taobao(s)
}
}
override fun result(bean: TaobaoBean) {
text.text = ""
for (i in 0 until bean.result.size) {
val list = bean.result[i]
for (j in 0 until list.size) {
text.append(list[j] + "\n")
}
}
}
}
请见Demo使用代码,针对各种情景下都有详细使用代码。