前言:
MVP作为一种MVC的演化版本在Android开发中受到了越来越多的关注,但是MVP到现在为止并没有统一的标准或者框架。网络或github上也有很多相应的模板,但是并不是自己想要的,所以自己便简单地封装下。
先看下效果图:
1、项目结构:
所用到的依赖build.gradle中加入:
//网络请求
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
//数据解析
implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
//加载框
implementation 'com.wang.avi:library:2.1.3'
AndroidManifest.xml清单文件加入:
<uses-permission android:name="android.permission.INTERNET"/>
2、代码部分
①基类activity和fragment:
public abstract class BaseMvpActivity<V extends BaseView, P extends BasePresenter<V>>
extends FragmentActivity implements BaseDelegate<V, P> {
protected P mPresenter;
protected void onCreate(@Nullable Bundle savedInstanceState) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
super.onCreate(savedInstanceState);
setContentView(this.setLayoutId());
mPresenter = createPresenter();
initView();
}
/**
* 设置布局的ID
*/
protected abstract int setLayoutId();
/**
* 初始化操作
*/
protected abstract void initView();
@Override
public P getPresenter() {
return mPresenter;
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mPresenter != null) {
mPresenter.detachView();
}
}
/**
* 吐司
*/
public void showToast(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}
public abstract class BaseMvpFragment<V extends BaseView, P extends BasePresenter<V>>
extends Fragment implements BaseDelegate<V, P> {
protected P mPresenter;
private View mView;
protected BaseMvpActivity mActivity;
@Override
public void onAttach(Context context) {
super.onAttach(context);
//内存不足的情况会导致Fragment调用getActivity()的地方却返回null空指针异常
this.mActivity = (BaseMvpActivity) context;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mView != null) {
ViewGroup parent = (ViewGroup) mView.getParent();
if (parent != null) {
parent.removeView(mView);
}
} else {
mPresenter = createPresenter();
mView = inflater.inflate(setLayoutId(), container, false);
initView(mView, savedInstanceState);
}
return mView;
}
/**
* 设置布局的ID
*/
protected abstract int setLayoutId();
/**
* 初始化操作
*/
protected abstract void initView(View view, Bundle savedInstanceState);
@Override
public P getPresenter() {
return mPresenter;
}
@Override
public void onDestroy() {
mView = null;
super.onDestroy();
if (mPresenter != null) {
mPresenter.detachView();
}
}
}
②:处理基类:
/**
* 功能描述:委托类
*/
public interface BaseDelegate<V extends BaseView, P extends BasePresenter<V>> {
/**
* 初始化presenter
*/
P createPresenter();
/**
* 获取presenter
*/
P getPresenter();
}
public abstract class BaseModel<P> {
protected P mPresenter;
public BaseModel(P presenter) {
this.mPresenter = presenter;
}
}
/**
* 功能描述:主要负责View与Model的交互
*/
public interface BasePresenter<V extends BaseView> {
/**
* 绑定接口
*/
//void attachView(BaseMvpActivity context, V view);
void attachView(V view);
/**
* 释放接口
*/
void detachView();
}
public interface BaseView {
}
③个人信息实体类:
/**
* 个人信息实体类
*/
public class UserInfoBean {
/**
* createTime : 2019-08-17 08:18:20
* userName : HelloWord
* password : e10adc3949ba59abbe56e057f20f883e
* mobile : 16666666666
* birthday : 2001-05-17
* height : 150
* weight : 60
* sex : BOY
*/
private String createTime;
private String userName;
private String password;
private String mobile;
private String birthday;
private int height;
private int weight;
private String sex;
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "UserInfoBean{" +
"createTime='" + createTime + '\'' +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
", mobile='" + mobile + '\'' +
", birthday='" + birthday + '\'' +
", height=" + height +
", weight=" + weight +
", sex='" + sex + '\'' +
'}';
}
}
④:请求类(关键部分):
/**
* 添加请求头
*/
public class HeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder builder = request.newBuilder()
.addHeader("Content-Type", "text/plain;charset=UTF-8");
builder = builder.url(request.url().newBuilder()
//建议缓存到Appaction中再取值即可
.addQueryParameter("token", "传入自己的token")
.build());
return chain.proceed(builder.build());
// Request request = chain.request()
// .newBuilder()
// .addHeader("Content-Type", "application/text;charset=UTF-8")
// .addHeader("Accept-Encoding", "gzip, deflate")
// .addHeader("Connection", "keep-alive")
// .addHeader("Accept", "*/*")
// .addHeader("Cookie", "add cookies here")
// .addHeader("Content-Type", "text/plain;charset=UTF-8")
// .build();
// return chain.proceed(request);
}
}
/**
* 打印请求链接、请求时间
*/
public class LogingInterceptor implements Interceptor {
private static final String TAG = "LogingInterceptor";
@Override
public Response intercept(Chain chain) throws IOException {
//一秒的10亿分之一
//1纳秒=0.000001 毫秒
//1纳秒=0.00000 0001秒
long t1 = System.nanoTime();
Response response = chain.proceed(chain.request());
long t2 = System.nanoTime();
Log.e(TAG,String.format(Locale.getDefault(), "Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
MediaType mediaType = response.body().contentType();
String content = response.body().string();
Log.e(TAG,content);
return response.newBuilder()
.body(okhttp3.ResponseBody.create(mediaType, content))
.build();
}
}
/**
* 功能描述:回调接口
* 自行修改,根据对应code或状态设置是否请求成功
*/
public class HttpBaseCallBack<T> {
private static final String TAG = "HttpBaseCallBack";
protected Call<HttpBaseDto<T>> mCall;
private BaseMvpActivity mActivity;
//默认显示加载框
private boolean isLoading = true;
private LoadingDialog dialog;
public HttpBaseCallBack(BaseMvpActivity context, Call call) {
this.mCall = call;
this.mActivity = context;
}
public HttpBaseCallBack(BaseMvpActivity context, Call call, boolean isLoading) {
this.mCall = call;
this.mActivity = context;
this.isLoading = isLoading;
}
/**
* 处理返回数据
*/
public void getInstanceResponse(final ResponseListener listener) {
if (isLoading) {
showLoading();
}
mCall.enqueue(new Callback<HttpBaseDto<T>>() {
@Override
public void onResponse(Call<HttpBaseDto<T>> call, Response<HttpBaseDto<T>> response) {
//关闭弹窗
dismissLoading();
String errorMsg = response.body().getMsg();
//请求成功
if (response.isSuccessful() && null == response.errorBody()) {
//此处是Code码为0请求成功(根据后台返回自行修改)
if (response.body().code.equals("0")) {
listener.onSuccess(response.body().getData());
} else {
listener.onFailure(errorMsg);
mActivity.showToast(errorMsg);
}
} else {
//请求失败,回调错误信息
listener.onFailure(errorMsg);
mActivity.showToast(errorMsg);
}
}
@Override
public void onFailure(Call<HttpBaseDto<T>> call, Throwable t) {
dismissLoading();
listener.onFailure(t.getMessage());
mActivity.showToast("获取失败,请稍后再试~");
}
});
}
/**
* 接口回调
*/
public interface ResponseListener<T> {
//请求成功
void onSuccess(T t);
//请求失败
void onFailure(String msg);
}
/**
* 显示加载提示
*/
private void showLoading() {
if (dialog == null) {
dialog = new LoadingDialog(mActivity);
}
dialog.show();
}
/**
* 关闭加载提示
*/
private void dismissLoading() {
if (dialog != null) {
dialog.dismiss();
dialog.cancel();
dialog = null;
}
}
}
public class HttpBaseDto<T> implements Serializable {
//根据返回的不同自行修改、请求状态
public String code;
//请求成功或失败
public String msg;
//数据源
private T data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "HttpBaseDto{" +
"code='" + code + '\'' +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
注意code、msg、data根据后端返回自行修改
/**
* 功能描述:请求连接
*/
public interface RetrofitClient {
/**
* POST请求
*/
@FormUrlEncoded
@POST("app/login")
Call<HttpBaseDto<UserInfoBean>> postRequest(@Field("account") String account,
@Field("password") String password);
/**
* GET请求
*/
@GET("app/login")
Call<HttpBaseDto<UserInfoBean>> getRequest(@Query("account") String account,
@Query("password") String password);
/**
* 多个参数请求(GET方式同理)
*/
@FormUrlEncoded
@POST("app/login")
Call<HttpBaseDto<UserInfoBean>> mapRequest(@FieldMap HashMap<String, String> hashMap);
/**
* 上传图片
*/
@Multipart
@POST("app/file/uploadImg")
Call<ResponseBody> uploadImg(@Part("img") RequestBody file);
}
/**
* 功能描述:Retrofit基本配置
*/
public class RetrofitFactory {
private static RetrofitClient mRetrofitClient;
private static Retrofit.Builder mBuilder;
/**
* 双重单例
*/
public static RetrofitClient getInstance() {
if (null == mRetrofitClient) {
synchronized (RetrofitClient.class) {
if (null == mRetrofitClient) {
OkHttpClient client = new OkHttpClient.Builder()
//连接超时10 、单位秒
.connectTimeout(15, TimeUnit.SECONDS)
//读取时间
.readTimeout(10, TimeUnit.SECONDS)
//写入时间
.writeTimeout(10, TimeUnit.SECONDS)
//添加拦截器
.addInterceptor(new LogingInterceptor())
.addInterceptor(new HeaderInterceptor())
.build();
mBuilder = new Retrofit.Builder()
//请求链接
.baseUrl(AppConfig.BASE_URL)
//添加Gson解析器(若返回不是gson格式可自定义解析器 )
//继承Converter.Factory 实现其方法
.addConverterFactory(GsonConverterFactory.create())
.client(client);
mRetrofitClient = mBuilder.build().create(RetrofitClient.class);
}
}
}
return mRetrofitClient;
}
}
3、使用方法:
新建interfaceview、model、presenter3个包(名字自行修改)
/**
* 功能描述:成功失败回调
*/
public interface IRequestView extends BaseView {
void onRequestSuccess(UserInfoBean dto);
void onRequestFailed(String msg);
void onUploadImgSuccess(String url);
void onUploadImgFailed(String msg);
}
public class RequestModel extends BaseModel<RequestPresenter> {
private static final String TAG = "RequestModel";
private BaseMvpActivity mActivity;
public RequestModel(RequestPresenter presenter, BaseMvpActivity mActivity) {
super(presenter);
this.mActivity = mActivity;
}
/**
* POST和GET请求(注意密码MD5加密)
*/
public void getRequest(boolean type, String account, String password) {
RetrofitClient client = RetrofitFactory.getInstance();
Call<HttpBaseDto<UserInfoBean>> call;
if (type) {
call = client.postRequest(account, Md5Utils.encryption(password));
} else {
call = client.getRequest(account, Md5Utils.encryption(password));
}
new HttpBaseCallBack<>(mActivity, call).getInstanceResponse(
new HttpBaseCallBack.ResponseListener<UserInfoBean>() {
@Override
public void onSuccess(UserInfoBean dto) {
//请求成功
if (null != dto) {
mPresenter.OnRequestSuccess(dto);
}
}
@Override
public void onFailure(String msg) {
//请求失败
mPresenter.OnRequestFailed(msg);
}
});
}
/**
* 多个参数请求
*/
public void mapRequest(UserInfoBean bean) {
HashMap<String, String> hashMap = new HashMap<>();
if (!TextUtils.isEmpty(bean.getMobile())) {
hashMap.put("account", bean.getMobile());
}
if (!TextUtils.isEmpty(bean.getPassword())) {
hashMap.put("password", Md5Utils.encryption(bean.getPassword()));
}
if (!TextUtils.isEmpty(bean.getUserName())) {
hashMap.put("userName", bean.getUserName());
}
if (!TextUtils.isEmpty(bean.getBirthday())) {
hashMap.put("birthday", bean.getBirthday());
}
Call<HttpBaseDto<UserInfoBean>> call = RetrofitFactory.getInstance().mapRequest(hashMap);
new HttpBaseCallBack<>(mActivity, call).getInstanceResponse(
new HttpBaseCallBack.ResponseListener<UserInfoBean>() {
@Override
public void onSuccess(UserInfoBean dto) {
//请求成功
if (null != dto) {
mPresenter.OnRequestSuccess(dto);
}
}
@Override
public void onFailure(String msg) {
//请求失败
mPresenter.OnRequestFailed(msg);
}
});
}
/**
* 上传图片
*/
public void uploadImg(String path) {
File file = new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpg"), file);
Call<ResponseBody> call = RetrofitFactory.getInstance().uploadImg(requestFile);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.e(TAG, "onResponse: " + response.body().toString());
Log.e(TAG, "onResponse: " + call.toString());
Log.e(TAG, "onResponse: " + response.message());
Log.e(TAG, "onResponse: " + response.message());
if (null != response.body()) {
mPresenter.OnUploadImgSuccess(response.body().toString());
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.getMessage());
mPresenter.OnUploadImgFailed(t.getMessage());
}
});
}
}
public class RequestPresenter implements BasePresenter<IRequestView> {
private IRequestView mView;
private RequestModel mModel;
public RequestPresenter(IRequestView view, BaseMvpActivity mActivity) {
attachView(view);
mModel = new RequestModel(this, mActivity);
}
/**
* POST、GET请求
*/
public void getRequest(boolean type, String account, String password) {
mModel.getRequest(type, account, password);
}
/**
* 多参数请求
*/
public void mapRequest(UserInfoBean bean) {
mModel.mapRequest(bean);
}
/**
* 上传图片
*/
public void uploadImg(String path) {
mModel.uploadImg(path);
}
@Override
public void attachView(IRequestView view) {
this.mView = view;
}
@Override
public void detachView() {
this.mView = null;
}
public void OnRequestSuccess(UserInfoBean dto) {
if (null != mView) {
mView.onRequestSuccess(dto);
}
}
public void OnRequestFailed(String msg) {
if (null != mView) {
mView.onRequestFailed(msg);
}
}
public void OnUploadImgSuccess(String url) {
if (null != mView) {
mView.onUploadImgSuccess(url);
}
}
public void OnUploadImgFailed(String msg) {
if (null != mView) {
mView.onUploadImgFailed(msg);
}
}
}
Activity中的写法:
public class MainActivity extends BaseMvpActivity<IRequestView, RequestPresenter> implements View.OnClickListener, IRequestView {
private TextView contText1, contText2, contText3;
private static final String TAG = "MainActivity";
//判断请求方式
private int requestType;
@Override
protected int setLayoutId() {
return R.layout.activity_main;
}
@Override
protected void initView() {
findViewById(R.id.btn_post).setOnClickListener(this);
findViewById(R.id.btn_get).setOnClickListener(this);
findViewById(R.id.btn_map).setOnClickListener(this);
findViewById(R.id.btn_upload).setOnClickListener(this);
contText1 = findViewById(R.id.cont_text1);
contText2 = findViewById(R.id.cont_text2);
contText3 = findViewById(R.id.cont_text3);
}
@Override
public RequestPresenter createPresenter() {
return new RequestPresenter(this, this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_post:
requestType = 1;
//POST请求
mPresenter.getRequest(true, "16666666666", "123456");
break;
case R.id.btn_get:
requestType = 2;
//GET请求
mPresenter.getRequest(false, "16666666666", "123456");
break;
case R.id.btn_map:
requestType = 3;
//多个参数请求
UserInfoBean bean = new UserInfoBean();
bean.setMobile("16666666666");
bean.setPassword("123456");
mPresenter.mapRequest(bean);
break;
case R.id.btn_upload:
//上传图片(path:本地图片路径)
String path = "/storage/emulated/0/Android/data/com.helloword.demo/1567324566927.jpg";
mPresenter.uploadImg(path);
break;
}
}
@Override
public void onRequestSuccess(UserInfoBean bean) {
//请求成功
String str = bean.toString();
Log.e(TAG, "onRequestSuccess: " + str);
switch (requestType) {
case 1:
contText1.setText(str);
break;
case 2:
contText2.setText(str);
break;
case 3:
contText3.setText(str);
break;
}
}
@Override
public void onRequestFailed(String msg) {
//请求失败
}
@Override
public void onUploadImgSuccess(String url) {
//上传成功
Log.e(TAG, "onUploadImgSuccess: 图片地址" + url);
}
@Override
public void onUploadImgFailed(String msg) {
//上传失败
}
}
对应布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/cont_text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp" />
<Button
android:id="@+id/btn_post"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="POST请求" />
<TextView
android:id="@+id/cont_text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp" />
<Button
android:id="@+id/btn_get"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="GET请求" />
<TextView
android:id="@+id/cont_text3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp" />
<Button
android:id="@+id/btn_map"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="多参数为空请求" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="描述:有多个参数时,为空时不携带键值,不能传“null”或双引号" />
<Button
android:id="@+id/btn_upload"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="上传图片" />
</LinearLayout>
用到的工具类与加载框:
public class AppConfig {
/**
* 请求链接
*/
public static final String BASE_URL = "http://198.110.8080/helloword/";
}
/**
* 功能描述:MD5加密工具
*/
public class Md5Utils {
/**
* 32位小写加密
* @param plain
* @return
*/
public static String encryption(String plain) {
String re_md5 = new String();
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plain.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
re_md5 = buf.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return re_md5;
}
/***
* MD5加密 生成32位md5码
* @param inStr 待加密字符串
* @return 返回32位md5码
*/
public static String md5Encode(String inStr) throws Exception {
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
return "";
}
byte[] byteArray = inStr.getBytes("UTF-8");
byte[] md5Bytes = md5.digest(byteArray);
StringBuffer hexValue = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
int val = ((int) md5Bytes[i]) & 0xff;
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString().toLowerCase();
}
}
/**
* 功能描述:加载框(https://github.com/81813780/AVLoadingIndicatorView)
*/
public class LoadingDialog extends Dialog {
private AVLoadingIndicatorView view;
public LoadingDialog(@NonNull BaseMvpActivity context) {
super(context, R.style.MyAlertDialog);
setContentView(R.layout.dialog_loading);
view = findViewById(R.id.loading_view);
}
@Override
public void show() {
super.show();
view.show();
}
@Override
public void dismiss() {
super.dismiss();
view.hide();
}
}
style:
<style name="MyAlertDialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<!-- 边框 -->
<item name="android:windowIsFloating">true</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsTranslucent">false</item>
<!-- 半透明 -->
<item name="android:windowNoTitle">true</item>
<!-- 无标题 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 背景透明 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 模糊 -->
<item name="android:background">@android:color/transparent</item>
<!-- 背景色 -->
</style>
颜色值:
<color name="translucent_color">#99000000</color>
<color name="transparent">#00000000</color>
<color name="white_bg_color">#ffffff</color>
布局文件:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/loading_shape"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="30dp"
android:paddingTop="20dp"
android:paddingRight="30dp"
android:paddingBottom="20dp">
<!--LineScalePartyIndicator x -->
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/loading_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:indicatorColor="@color/white_bg_color"
app:indicatorName="PacmanIndicator" />
<TextView
android:id="@+id/dialog_msg"
android:textColor="@color/white_bg_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="加载中..."
android:textSize="12sp" />
</LinearLayout>
样式loading_shape:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="10dp" />
<solid android:color="@color/translucent_color" />
</shape>
后端返回样例:
{
"code": "0",
"msg": "成功",
"data": {
"createTime": "2019-08-17 08:18:20",
"userName": "HelloWorld",
"mobile": "16666666666",
"password": "e10adc3949ba59abbe56e057f20f883e",
"token": "e10adc3949ba59abbe56e057f20f883e",
"birthday": "2001-05-17",
"height": 0,
"weight": 0,
"sex": "BOY"
}
}
如果是数组的方式返回:
{
"code": "0",
"msg": "成功",
"data": [
"createTime": "2019-08-17 08:18:20",
"userName": "HelloWorld",
"mobile": "16666666666",
"password": "e10adc3949ba59abbe56e057f20f883e",
"token": "e10adc3949ba59abbe56e057f20f883e",
"birthday": "2001-05-17",
"height": 0,
"weight": 0,
"sex": "BOY"
]
}
代码处修改:
void onGetListSuccess(List<UserInfoBean> dto);
void onGetListFailed(String msg);
/**
* 数组形式
*/
@Multipart
@POST("app/getList")
Call<HttpBaseDto<List<UserInfoBean>>> getList(@Field("pageSize") int pageSize,
@Field("pageNo") int pageNo);
public void getList(int pageSize, int pageNo) {
Call<HttpBaseDto<List<UserInfoBean>>> call = RetrofitFactory.getInstance().getList(pageSize, pageNo);
new HttpBaseCallBack<>(mActivity, call).getInstanceResponse(
new HttpBaseCallBack.ResponseListener<List<UserInfoBean>>() {
@Override
public void onSuccess(List<UserInfoBean> dto) {
}
@Override
public void onFailure(String msg) {
}
});
}